mirror of https://github.com/lukechilds/umbrel.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
2.7 KiB
117 lines
2.7 KiB
const isIframe = (window.self !== window.top);
|
|
|
|
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
|
|
const on = (selector, eventName, callback) => {
|
|
for (element of document.querySelectorAll(selector)) {
|
|
element.addEventListener(eventName, event => {
|
|
event.preventDefault();
|
|
callback();
|
|
});
|
|
}
|
|
};
|
|
|
|
const setState = (key, value) => document.body.dataset[key] = value;
|
|
const getState = key => document.body.dataset[key];
|
|
|
|
const isUmbrelUp = async () => {
|
|
const response = await fetch('/manager-api/ping');
|
|
return response.status === 200 && response.redirected === false;
|
|
};
|
|
|
|
const checkForError = async () => {
|
|
const response = await fetch('/status');
|
|
const status = await response.json();
|
|
const errorCode = (status.find(service => service.status === 'errored') || {}).error;
|
|
return errorCode;
|
|
};
|
|
|
|
const isStatusServerUp = async () => {
|
|
try {
|
|
await checkForError();
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
const power = async action => {
|
|
try {
|
|
const token = await (await fetch('/token')).json();
|
|
const response = await fetch(`/${action}`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({token}),
|
|
});
|
|
if (!response.ok) {
|
|
return false;
|
|
}
|
|
} catch (e) {} finally {
|
|
return true;
|
|
}
|
|
};
|
|
|
|
on('.shutdown', 'click', async () => {
|
|
if (! await power('shutdown')) {
|
|
alert('Failed to shutdown Umbrel');
|
|
return;
|
|
}
|
|
|
|
setState('status', 'shutting-down');
|
|
await delay(30000);
|
|
setState('status', 'shutdown-complete');
|
|
});
|
|
|
|
on('.restart', 'click', async () => {
|
|
if (! await power('restart')) {
|
|
alert('Failed to restart Umbrel');
|
|
return;
|
|
}
|
|
|
|
setState('status', 'restarting');
|
|
await delay(10000);
|
|
// Wait for Umbrel to come back up then reload the page.
|
|
while (true) {
|
|
try {
|
|
if (await isStatusServerUp() || await isUmbrelUp()) {
|
|
window.location.reload();
|
|
}
|
|
} catch (e) {}
|
|
await delay(1000);
|
|
}
|
|
});
|
|
|
|
const main = async () => {
|
|
// Protect against clickjacking
|
|
if (isIframe) {
|
|
document.body.innerText = 'For security reasons Umbrel doesn\'t work in an iframe.';
|
|
return;
|
|
}
|
|
|
|
// Set initial loading state
|
|
setState('status', 'starting');
|
|
|
|
// Start loop
|
|
while (getState('status') === 'starting') {
|
|
try {
|
|
// If Umbrel is ready, reload
|
|
if (await isUmbrelUp()) {
|
|
window.location.reload();
|
|
}
|
|
|
|
// If there are errors, set error state
|
|
const error = await checkForError();
|
|
if (error) {
|
|
setState('status', 'error');
|
|
setState('error', error);
|
|
}
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
await delay(1000);
|
|
}
|
|
};
|
|
|
|
main();
|
|
|