Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore functionality #24

Merged
merged 23 commits into from
Aug 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
## 20240813
- [x] style for the dashboard (unikernel info)
- TODO unikernel detailed information (/unikernel/info/<name>) - displayed
- TODO shutdown and restart of a unikernel
- TODO deploy/create a new unikernel

- [x] unikernel detailed information (/unikernel/info/<name>) - displayed
- [x] destroy of a unikernel
- [x] deploy/create a new unikernels
- [x] store configuration data on block device (PR pending)
- [x] have an HTTP endpoint for editing / uploading the configuration
- TODO Shutdown and restart a unikernel

- TODO we should remove all unauthenticated endpoints (comment out)

Expand All @@ -26,4 +26,4 @@
- TODO email verification (sending emails)

- TODO deploy unikernels via GitHub action (Bearer token etc.)
- TODO REST API - rely on bearer tokens
- TODO REST API - rely on bearer tokenss
12 changes: 6 additions & 6 deletions albatross_json.ml
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@ let console_data_to_json (ts, data) =
[ ("timestamp", `String (Ptime.to_rfc3339 ts)); ("line", `String data) ]

let res = function
| `Command _ -> `String "command not supported"
| `Success s -> success s
| `Failure f -> `String ("failure: " ^ f)
| `Data (`Console_data (ts, data)) -> console_data_to_json (ts, data)
| `Data (`Utc_console_data (ts, data)) -> console_data_to_json (ts, data)
| `Data (`Stats_data _) -> `String "stats not supported"
| `Command _ -> Error (`String "command not supported")
| `Success s -> Ok (success s)
| `Failure f -> Error (`String ("failure: " ^ f))
| `Data (`Console_data (ts, data)) -> Ok (console_data_to_json (ts, data))
| `Data (`Utc_console_data (ts, data)) -> Ok (console_data_to_json (ts, data))
| `Data (`Stats_data _) -> Error (`String "stats not supported")

let fail_behaviour_of_json js =
let ( let* ) = Result.bind in
Expand Down
69 changes: 0 additions & 69 deletions assets/create_unikernel.html

This file was deleted.

143 changes: 141 additions & 2 deletions assets/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
document.addEventListener('DOMContentLoaded', function () {
AOS.init();
AOS.init();
if (window.location.pathname.startsWith("/unikernel/info")) {
setInterval(getConsoleOutput, 300);
}
});

function filterData() {
Expand Down Expand Up @@ -74,7 +77,8 @@ async function saveConfig() {
formAlert.classList.remove("hidden", "text-secondary-500");
formAlert.classList.add("text-primary-500");
formAlert.textContent = "Succesfully updated";
setTimeout(function() {
postAlert("bg-primary-300", data.data);
setTimeout(function () {
window.location.reload();
}, 2000);
} else {
Expand All @@ -95,3 +99,138 @@ function closeBanner() {
var banner = document.getElementById("banner-message");
banner.style.display = "none";
}

function postAlert(bg_color, content) {
const alertContainer = document.getElementById("alert-container");
alertContainer.classList.remove("hidden")
alertContainer.classList.add("block", `${bg_color}`, "text-white", "transition", "ease-in-out", "delay-150", "duration-300")
const alert = document.createElement("div");
alert.className = `text-white transition ease-in-out delay-150 duration-300 ${bg_color}`;
alert.textContent = content;
alertContainer.appendChild(alert);
setTimeout(() => {
alertContainer.classList.remove("block", `${bg_color}`)
alertContainer.classList.add("hidden")
alertContainer.removeChild(alert);
}, 1600);
}

async function deployUnikernel() {
const deployButton = document.getElementById("deploy-button");
const name = document.getElementById("unikernel-name").value.trim();
const arguments = document.getElementById("unikernel-arguments").value.trim();
const binary = document.getElementById("unikernel-binary").files[0];
const formAlert = document.getElementById("form-alert");
if (!name || !binary) {
formAlert.classList.remove("hidden", "text-primary-500");
formAlert.classList.add("text-secondary-500");
formAlert.textContent = "Please fill in the required data"
buttonLoading(deployButton, false, "Deploy")
} else {
buttonLoading(deployButton, true, "Deploying...")
let formData = new FormData();
formData.append("name", name);
formData.append("binary", binary)
formData.append("arguments", arguments)
try {
const response = await fetch("/unikernel/create", {
method: 'POST',
headers: {
"Content-Type": "application/json",
},
body: formData
})
const data = await response.json();
if (data.status === 200 && data.success) {
formAlert.classList.remove("hidden", "text-secondary-500");
formAlert.classList.add("text-primary-500");
formAlert.textContent = "Succesfully updated";
postAlert("bg-primary-300", data.data);
setTimeout(function () {
window.location.href = "/dashboard";
}, 2000);
} else {
postAlert("bg-secondary-300", data.data);
formAlert.classList.remove("hidden", "text-primary-500");
formAlert.classList.add("text-secondary-500");
formAlert.textContent = data.data
buttonLoading(deployButton, false, "Deploy")
}
} catch (error) {
postAlert("bg-secondary-300", error);
formAlert.classList.remove("hidden");
formAlert.classList.add("text-secondary-500");
formAlert.textContent = error
buttonLoading(deployButton, false, "Deploy")
}
}
}

async function destroyUnikernel(name) {
try {
const response = await fetch(`/unikernel/destroy/${name}`, {
method: 'GET',
mode: "no-cors"
})
const data = await response.json();
if (data.status === 200) {
postAlert("bg-primary-300", `Successful: ${data.data}`);
setTimeout(function () {
window.location.href = "/dashboard";
}, 2000);
} else {
postAlert("bg-secondary-300", data.data);
}
} catch (error) {
postAlert("bg-secondary-300", error);
}
}

function getUnikernelName(url) {
const urlObj = new URL(url);
const pathParts = urlObj.pathname.split('/');
return pathParts[pathParts.length - 1];
}

var consoleArea = document.createElement("textarea");
async function getConsoleOutput() {
let unikernel_name = getUnikernelName(window.location.href);
if (unikernel_name) {
const consoleDiv = document.getElementById("console-container");
fetch("/unikernel/console/" + unikernel_name, {
method: "get",
})
.then((response) => response.json())
.then((responseText) => {
let data = ""
responseText.forEach(item => {
data += `${item.timestamp} - ${item.line} \n`
})
consoleArea.textContent = ""
consoleArea.textContent = data
})
.catch((error) => {
postAlert("bg-secondary-300", `${unikernel_name} ${error}`)
})
.finally(() => {

});
consoleDiv.appendChild(consoleArea)
}
}

function buttonLoading(btn, load, text) {
if (load) {
btn.disabled = true;
btn.classList.remove("bg-primary-500", "text-gray-50");
btn.classList.add("bg-primary-50", "text-primary-950");
btn.innerHTML = `<i class="fa-solid fa-spinner animate-spin mr-2"></i> ${text}`;
} else {
btn.disabled = false;
btn.classList.remove("bg-primary-50", "text-primary-950");
btn.classList.add("bg-primary-500", "text-gray-50");
btn.innerHTML = text;
}
}


2 changes: 1 addition & 1 deletion assets/style.css

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions dashboard.ml
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,24 @@ let dashboard_layout ~icon ?(page_title = "Dashboard | Mollymawk")
section
~a:[ a_class [ "col-span-2 px-4 py-6 w-full mx-auto" ] ]
[
div
~a:
[
a_id "alert-container";
a_class
[
"absolute top-1/4 rounded-md right-4 z-50 w-fit \
space-y-2 p-4 shadow border text-wrap hidden";
];
]
[];
div
~a:[ a_class [ "w-full my-2" ] ]
[
a
~a:
[
a_href "/unikernel/deploy";
a_class
[
"cursor-pointer bg-primary-500 \
Expand Down
Loading
Loading