mirror of
https://github.com/vdsm/virtual-dsm.git
synced 2025-11-07 02:23:42 +08:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
675aa5e122 | ||
|
|
2a62d4e938 | ||
|
|
9cbb51cc86 | ||
|
|
7790f81d15 | ||
|
|
fdbff4879b | ||
|
|
739e679a66 | ||
|
|
0dea507d85 | ||
|
|
4f524c47d8 | ||
|
|
0c74201eb4 | ||
|
|
1e13258bc9 |
@@ -47,7 +47,7 @@ services:
|
||||
Via `docker run`
|
||||
|
||||
```bash
|
||||
docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-timeout 60 vdsm/virtual-dsm
|
||||
docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-timeout 120 vdsm/virtual-dsm
|
||||
```
|
||||
|
||||
## FAQ
|
||||
@@ -58,7 +58,7 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
||||
|
||||
- Start the container and get some coffee.
|
||||
|
||||
- Connect to port 5000 of the container in your web browser.
|
||||
- Connect to [port 5000](http://localhost:5000) of the container in your web browser.
|
||||
|
||||
- Wait until DSM is ready, choose an username and password, and you will be taken to the desktop.
|
||||
|
||||
@@ -99,7 +99,7 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
||||
|
||||
Please note that this may reduce the write performance of the disk.
|
||||
|
||||
* ### How do I add multiple disks?
|
||||
* ### How do I add multiple disks?
|
||||
|
||||
To create additional disks, modify your compose file like this:
|
||||
|
||||
@@ -114,7 +114,7 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
||||
|
||||
* ### How do I pass-through a disk?
|
||||
|
||||
It is possible to pass-through disk devices directly by adding them to your compose file in this way:
|
||||
It is possible to pass-through disk devices directly by adding them to your compose file in this way:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
|
||||
@@ -3,8 +3,8 @@ set -Eeuo pipefail
|
||||
|
||||
DEF_OPTS="-nodefaults -boot strict=on"
|
||||
RAM_OPTS=$(echo "-m $RAM_SIZE" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g')
|
||||
CPU_OPTS="-cpu $CPU_MODEL -smp $CPU_CORES,sockets=1,dies=1,cores=$CPU_CORES,threads=1"
|
||||
MAC_OPTS="-machine type=q35,usb=off,dump-guest-core=off,hpet=off${KVM_OPTS}"
|
||||
CPU_OPTS="-cpu $CPU_FLAGS -smp $CPU_CORES,sockets=1,dies=1,cores=$CPU_CORES,threads=1"
|
||||
MAC_OPTS="-machine type=q35,usb=off,vmport=off,dump-guest-core=off,hpet=off${KVM_OPTS}"
|
||||
DEV_OPTS="-device virtio-balloon-pci,id=balloon0,bus=pcie.0,addr=0x4"
|
||||
DEV_OPTS="$DEV_OPTS -object rng-random,id=objrng0,filename=/dev/urandom"
|
||||
DEV_OPTS="$DEV_OPTS -device virtio-rng-pci,rng=objrng0,id=rng0,bus=pcie.0,addr=0x1c"
|
||||
|
||||
12
src/disk.sh
12
src/disk.sh
@@ -112,8 +112,8 @@ createDisk() {
|
||||
fi
|
||||
fi
|
||||
|
||||
MSG="Creating a $DISK_TYPE $DISK_DESC image in $DISK_FMT format with a size of $DISK_SPACE..."
|
||||
info "$MSG" && html "$MSG"
|
||||
html "Creating a $DISK_DESC image..."
|
||||
info "Creating a $DISK_TYPE $DISK_DESC image in $DISK_FMT format with a size of $DISK_SPACE..."
|
||||
|
||||
local FAIL="Could not create a $DISK_TYPE $DISK_FMT $DISK_DESC image of $DISK_SPACE ($DISK_FILE)"
|
||||
|
||||
@@ -266,8 +266,8 @@ convertDisk() {
|
||||
fi
|
||||
fi
|
||||
|
||||
MSG="Converting $DISK_DESC to $DST_FMT, please wait until completed..."
|
||||
info "$MSG" && html "$MSG"
|
||||
html "Converting $DISK_DESC to $DST_FMT..."
|
||||
info "Converting $DISK_DESC to $DST_FMT, please wait until completed..."
|
||||
|
||||
local CONV_FLAGS="-p"
|
||||
local DISK_PARAM="$DISK_ALLOC"
|
||||
@@ -306,8 +306,8 @@ convertDisk() {
|
||||
fi
|
||||
fi
|
||||
|
||||
MSG="Conversion of $DISK_DESC to $DST_FMT completed succesfully!"
|
||||
info "$MSG" && html "$MSG"
|
||||
html "Conversion of $DISK_DESC completed..."
|
||||
info "Conversion of $DISK_DESC to $DST_FMT completed succesfully!"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -18,11 +18,13 @@ cd /run
|
||||
|
||||
trap - ERR
|
||||
|
||||
info "Booting $APP using $VERS..."
|
||||
[[ "$DEBUG" == [Yy1]* ]] && echo "Arguments: $ARGS" && echo
|
||||
|
||||
if [[ "$CONSOLE" == [Yy]* ]]; then
|
||||
exec qemu-system-x86_64 ${ARGS:+ $ARGS}
|
||||
fi
|
||||
|
||||
[[ "$DEBUG" == [Yy1]* ]] && info "$VERS" && echo "Arguments: $ARGS" && echo
|
||||
{ qemu-system-x86_64 ${ARGS:+ $ARGS} >"$QEMU_OUT" 2>"$QEMU_LOG"; rc=$?; } || :
|
||||
(( rc != 0 )) && error "$(<"$QEMU_LOG")" && exit 15
|
||||
|
||||
|
||||
@@ -174,8 +174,8 @@ fi
|
||||
|
||||
rm -rf "$TMP" && mkdir -p "$TMP"
|
||||
|
||||
MSG="Downloading $BASE.pat..."
|
||||
info "Install: $MSG" && html "$MSG"
|
||||
info "Install: Downloading $BASE.pat..."
|
||||
html "Install: Downloading DSM from Synology..."
|
||||
|
||||
PAT="/$BASE.pat"
|
||||
rm -f "$PAT"
|
||||
|
||||
@@ -254,8 +254,8 @@ if [[ "$DHCP" == [Yy1]* ]]; then
|
||||
# Configuration for DHCP IP
|
||||
configureDHCP
|
||||
|
||||
MSG="Please wait while discovering IP..."
|
||||
html "$MSG" "2000"
|
||||
MSG="Booting DSM instance..."
|
||||
html "$MSG"
|
||||
|
||||
else
|
||||
|
||||
|
||||
@@ -98,7 +98,6 @@ terminal() {
|
||||
|
||||
_graceful_shutdown() {
|
||||
|
||||
local cnt=0
|
||||
local code=$?
|
||||
local pid url response
|
||||
|
||||
@@ -144,6 +143,8 @@ _graceful_shutdown() {
|
||||
|
||||
fi
|
||||
|
||||
local cnt=0
|
||||
|
||||
while [ "$cnt" -lt "$QEMU_TIMEOUT" ]; do
|
||||
|
||||
! isAlive "$pid" && break
|
||||
|
||||
@@ -7,6 +7,7 @@ info () { printf "%b%s%b" "\E[1;34m❯ \E[1;36m" "$1" "\E[0m\n" >&2; }
|
||||
error () { printf "%b%s%b" "\E[1;31m❯ " "ERROR: $1" "\E[0m\n" >&2; }
|
||||
|
||||
file="/run/shm/dsm.url"
|
||||
info="/run/shm/msg.html"
|
||||
page="/run/shm/index.html"
|
||||
address="/run/shm/qemu.ip"
|
||||
shutdown="/run/shm/qemu.end"
|
||||
@@ -80,6 +81,7 @@ if [[ "$location" != "20.20"* ]]; then
|
||||
HTML="${HTML/\[5\]/}"
|
||||
|
||||
echo "$HTML" > "$page"
|
||||
echo "$body" > "$info"
|
||||
|
||||
else
|
||||
|
||||
|
||||
19
src/proc.sh
19
src/proc.sh
@@ -5,8 +5,8 @@ set -Eeuo pipefail
|
||||
|
||||
: "${KVM:="Y"}"
|
||||
: "${HOST_CPU:=""}"
|
||||
: "${CPU_FLAGS:=""}"
|
||||
: "${CPU_MODEL:="host"}"
|
||||
: "${CPU_FEATURES:="+ssse3,+sse4.1,+sse4.2"}"
|
||||
|
||||
[ "$ARCH" != "amd64" ] && KVM="N"
|
||||
|
||||
@@ -37,6 +37,7 @@ fi
|
||||
|
||||
if [[ "$KVM" != [Nn]* ]]; then
|
||||
|
||||
CPU_FEATURES="kvm=on"
|
||||
KVM_OPTS=",accel=kvm -enable-kvm"
|
||||
|
||||
if ! grep -qE '^flags.* (sse4_2)' /proc/cpuinfo; then
|
||||
@@ -48,15 +49,23 @@ if [[ "$KVM" != [Nn]* ]]; then
|
||||
else
|
||||
|
||||
KVM_OPTS=""
|
||||
CPU_FEATURES="+ssse3,+sse4.1,+sse4.2"
|
||||
|
||||
if [[ "${CPU_MODEL,,}" == "host"* ]]; then
|
||||
|
||||
if [[ "$CPU_MODEL" == "host"* ]]; then
|
||||
if [[ "$ARCH" == "amd64" ]]; then
|
||||
CPU_MODEL="max,$CPU_FEATURES"
|
||||
CPU_MODEL="max"
|
||||
else
|
||||
CPU_MODEL="qemu64,$CPU_FEATURES"
|
||||
CPU_MODEL="qemu64"
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$CPU_FLAGS" ]; then
|
||||
CPU_FLAGS="$CPU_MODEL,$CPU_FEATURES"
|
||||
else
|
||||
CPU_FLAGS="$CPU_MODEL,$CPU_FEATURES,$CPU_FLAGS"
|
||||
fi
|
||||
|
||||
if [ -z "$HOST_CPU" ]; then
|
||||
|
||||
24
src/reset.sh
24
src/reset.sh
@@ -29,6 +29,7 @@ echo
|
||||
# Helper variables
|
||||
|
||||
STORAGE="/storage"
|
||||
INFO="/run/shm/msg.html"
|
||||
PAGE="/run/shm/index.html"
|
||||
TEMPLATE="/var/www/index.html"
|
||||
FOOTER1="$APP for Docker v$(</run/version)"
|
||||
@@ -39,20 +40,20 @@ MINOR=$(uname -r | cut -d '.' -f2)
|
||||
ARCH=$(dpkg --print-architecture)
|
||||
VERS=$(qemu-system-x86_64 --version | head -n 1 | cut -d '(' -f 1)
|
||||
|
||||
# Check system
|
||||
|
||||
if [ ! -d "/dev/shm" ]; then
|
||||
error "Directory /dev/shm not found!" && exit 14
|
||||
else
|
||||
[ ! -d "/run/shm" ] && ln -s /dev/shm /run/shm
|
||||
fi
|
||||
|
||||
# Check folder
|
||||
|
||||
if [ ! -d "$STORAGE" ]; then
|
||||
error "Storage folder ($STORAGE) not found!" && exit 13
|
||||
fi
|
||||
|
||||
if [ ! -d "/run/shm" ]; then
|
||||
if [ -d "/dev/shm" ]; then
|
||||
ln -s /dev/shm /run/shm
|
||||
else
|
||||
error "Folder /dev/shm not found!" && exit 14
|
||||
fi
|
||||
fi
|
||||
|
||||
# Cleanup files
|
||||
rm -f /run/shm/qemu.*
|
||||
rm -f /run/shm/dsm.url
|
||||
@@ -118,6 +119,7 @@ html()
|
||||
{
|
||||
local title
|
||||
local body
|
||||
local script
|
||||
local footer
|
||||
|
||||
title=$(escape "$APP")
|
||||
@@ -129,10 +131,7 @@ html()
|
||||
body="<p class=\"loading\">${body/.../}</p>"
|
||||
fi
|
||||
|
||||
local timeout="4999"
|
||||
[ -n "${2:-}" ] && timeout="$2"
|
||||
local script="<script>setTimeout(() => { document.location.reload(); }, $timeout);</script>"
|
||||
[[ "$timeout" == "0" ]] && script=""
|
||||
[ -n "${2:-}" ] && script="$2" || script=""
|
||||
|
||||
local HTML
|
||||
HTML=$(<"$TEMPLATE")
|
||||
@@ -143,6 +142,7 @@ html()
|
||||
HTML="${HTML/\[5\]/$FOOTER2}"
|
||||
|
||||
echo "$HTML" > "$PAGE"
|
||||
echo "$body" > "$INFO"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
154
web/css/style.css
Normal file
154
web/css/style.css
Normal file
@@ -0,0 +1,154 @@
|
||||
body {
|
||||
color: white;
|
||||
background-color: #125bdb;
|
||||
font-family: Verdana, Arial, sans-serif;
|
||||
}
|
||||
|
||||
#content {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
footer {
|
||||
width: 98%;
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
height: 40px;
|
||||
text-align: center;
|
||||
color: #0c8aeb;
|
||||
}
|
||||
|
||||
#empty {
|
||||
height: 40px;
|
||||
/* Same height as footer */
|
||||
}
|
||||
|
||||
a,
|
||||
a:hover,
|
||||
a:active,
|
||||
a:visited {
|
||||
color: white;
|
||||
}
|
||||
|
||||
footer a:link,
|
||||
footer a:visited,
|
||||
footer a:active { color: #0c8aeb; }
|
||||
footer a:hover { color: #73e6ff; }
|
||||
|
||||
.loading:after {
|
||||
content: " .";
|
||||
animation: dots 1s steps(5, end) infinite;
|
||||
}
|
||||
|
||||
@keyframes dots {
|
||||
|
||||
0%,
|
||||
20% {
|
||||
color: rgba(0, 0, 0, 0);
|
||||
text-shadow: 0.25em 0 0 rgba(0, 0, 0, 0), 0.5em 0 0 rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
40% {
|
||||
color: white;
|
||||
text-shadow: 0.25em 0 0 rgba(0, 0, 0, 0), 0.5em 0 0 rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
60% {
|
||||
text-shadow: 0.25em 0 0 white, 0.5em 0 0 rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
80%,
|
||||
100% {
|
||||
text-shadow: 0.25em 0 0 white, 0.5em 0 0 white;
|
||||
}
|
||||
}
|
||||
|
||||
.spinner_LWk7 {
|
||||
animation: spinner_GWy6 1.2s linear infinite, spinner_BNNO 1.2s linear infinite
|
||||
}
|
||||
|
||||
.spinner_yOMU {
|
||||
animation: spinner_GWy6 1.2s linear infinite, spinner_pVqn 1.2s linear infinite;
|
||||
animation-delay: .15s
|
||||
}
|
||||
|
||||
.spinner_KS4S {
|
||||
animation: spinner_GWy6 1.2s linear infinite, spinner_6uKB 1.2s linear infinite;
|
||||
animation-delay: .3s
|
||||
}
|
||||
|
||||
.spinner_zVee {
|
||||
animation: spinner_GWy6 1.2s linear infinite, spinner_Qw4x 1.2s linear infinite;
|
||||
animation-delay: .45s
|
||||
}
|
||||
|
||||
@keyframes spinner_GWy6 {
|
||||
|
||||
0%,
|
||||
50% {
|
||||
width: 9px;
|
||||
height: 9px
|
||||
}
|
||||
|
||||
10% {
|
||||
width: 11px;
|
||||
height: 11px
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spinner_BNNO {
|
||||
|
||||
0%,
|
||||
50% {
|
||||
x: 1.5px;
|
||||
y: 1.5px
|
||||
}
|
||||
|
||||
10% {
|
||||
x: .5px;
|
||||
y: .5px
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spinner_pVqn {
|
||||
|
||||
0%,
|
||||
50% {
|
||||
x: 13.5px;
|
||||
y: 1.5px
|
||||
}
|
||||
|
||||
10% {
|
||||
x: 12.5px;
|
||||
y: .5px
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spinner_6uKB {
|
||||
|
||||
0%,
|
||||
50% {
|
||||
x: 13.5px;
|
||||
y: 13.5px
|
||||
}
|
||||
|
||||
10% {
|
||||
x: 12.5px;
|
||||
y: 12.5px
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spinner_Qw4x {
|
||||
|
||||
0%,
|
||||
50% {
|
||||
x: 1.5px;
|
||||
y: 13.5px
|
||||
}
|
||||
|
||||
10% {
|
||||
x: .5px;
|
||||
y: 12.5px
|
||||
}
|
||||
}
|
||||
1
web/img/favicon.svg
Normal file
1
web/img/favicon.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg id="Capa_1" enable-background="new 0 0 511.962 511.962" height="512" viewBox="0 0 511.962 511.962" width="512" xmlns="http://www.w3.org/2000/svg"><g><path d="m489.965 120.063c0-5.77-3.31-11.028-8.512-13.524l-218.984-105.063c-4.102-1.967-8.875-1.967-12.977 0l-218.985 105.063c-5.202 2.496-8.511 7.755-8.511 13.524l-.003 271.834c0 5.77 3.31 11.028 8.512 13.524l218.989 105.064c2.051.983 4.27 1.476 6.488 1.476 2.219 0 4.438-.492 6.488-1.476l218.989-105.064c5.202-2.496 8.512-7.755 8.512-13.524z" fill="#4e6ba6"/><path d="m489.965 120.063c0-5.77-3.31-11.028-8.512-13.524l-218.984-105.063c-2.051-.984-4.269-1.476-6.488-1.476v511.962c2.219 0 4.438-.492 6.488-1.476l218.989-105.064c5.202-2.496 8.512-7.755 8.512-13.524z" fill="#28487a"/><path d="m425.812 160.441c0-2.27-.519-4.457-1.457-6.432l-336.701-.095c-.967 1.999-1.504 4.22-1.504 6.526l-.002 191.081c0 5.769 3.31 11.028 8.512 13.524l154.833 74.285c2.051.983 4.27 1.476 6.488 1.476 2.219 0 4.438-.492 6.488-1.476l154.834-74.285c5.202-2.496 8.512-7.755 8.512-13.524z" fill="#8dc2eb"/><path d="m424.354 154.009h-168.373v286.798c2.219 0 4.438-.492 6.488-1.476l154.834-74.285c5.202-2.496 8.512-7.755 8.512-13.524l-.003-191.081c0-2.27-.52-4.458-1.458-6.432z" fill="#5e9ff6"/><path d="m417.3 146.916-154.831-74.284c-4.102-1.967-8.875-1.967-12.977 0l-154.831 74.284c-3.122 1.498-5.555 3.996-7.007 6.998l168.328 80.812 168.374-80.717c-1.448-3.044-3.9-5.579-7.056-7.093z" fill="#ecf9fd"/><path d="m417.3 146.916-154.831-74.284c-2.051-.983-4.27-1.476-6.488-1.476v163.569l168.374-80.717c-1.447-3.043-3.899-5.578-7.055-7.092z" fill="#d9f3fc"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -5,22 +5,30 @@
|
||||
[1]
|
||||
<meta http-equiv="Cache-Control" content="no-cache" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/style.css" />
|
||||
<link rel="icon" href="/img/favicon.svg" type="image/x-icon">
|
||||
[2]
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<h1>[3]</h1>
|
||||
<div id="page">
|
||||
<div id="content">
|
||||
<svg id="spinner" width="64" height="64" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect class="spinner_LWk7" fill="#0c8aeb" x="1.5" y="1.5" rx="1" width="9" height="9"/>
|
||||
<rect class="spinner_yOMU" fill="#0c8aeb" x="13.5" y="1.5" rx="1" width="9" height="9"/>
|
||||
<rect class="spinner_KS4S" fill="#0c8aeb" x="13.5" y="13.5" rx="1" width="9" height="9"/>
|
||||
<rect class="spinner_zVee" fill="#0c8aeb" x="1.5" y="13.5" rx="1" width="9" height="9"/>
|
||||
</svg>
|
||||
<h1 id="info">[3]</h1>
|
||||
</div>
|
||||
<div id="empty-space">
|
||||
<div id="empty">
|
||||
</div>
|
||||
<div id="footer">
|
||||
<footer id="footer">
|
||||
[4]<br />
|
||||
[5]
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<script type="text/javascript" src="/js/script.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
130
web/js/script.js
Normal file
130
web/js/script.js
Normal file
@@ -0,0 +1,130 @@
|
||||
var request;
|
||||
var interval = 1000;
|
||||
|
||||
function getInfo() {
|
||||
|
||||
var url = "/msg.html";
|
||||
|
||||
try {
|
||||
|
||||
if (window.XMLHttpRequest) {
|
||||
request = new XMLHttpRequest();
|
||||
} else {
|
||||
throw "XMLHttpRequest not available!";
|
||||
}
|
||||
|
||||
request.onreadystatechange = processInfo;
|
||||
request.open("GET", url, true);
|
||||
request.send();
|
||||
|
||||
} catch (e) {
|
||||
var err = "Error: " + e.message;
|
||||
console.log(err);
|
||||
setError(err);
|
||||
}
|
||||
}
|
||||
|
||||
function processInfo() {
|
||||
try {
|
||||
if (request.readyState != 4) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var msg = request.responseText;
|
||||
if (msg == null || msg.length == 0) {
|
||||
setInfo("Booting DSM instance", true);
|
||||
schedule();
|
||||
return false;
|
||||
}
|
||||
|
||||
var notFound = (request.status == 404);
|
||||
|
||||
if (request.status == 200) {
|
||||
if (msg.toLowerCase().indexOf("<html>") !== -1) {
|
||||
notFound = true;
|
||||
} else {
|
||||
if (msg.toLowerCase().indexOf("href=") !== -1) {
|
||||
var div = document.createElement("div");
|
||||
div.innerHTML = msg;
|
||||
var url = div.querySelector("a").href;
|
||||
setTimeout(() => {
|
||||
window.location.assign(url);
|
||||
}, 3000);
|
||||
setInfo(msg);
|
||||
return true;
|
||||
} else {
|
||||
setInfo(msg);
|
||||
schedule();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (notFound) {
|
||||
setInfo("Connecting to web portal", true);
|
||||
reload();
|
||||
return true;
|
||||
}
|
||||
|
||||
setError("Error: Received statuscode " + request.status);
|
||||
schedule();
|
||||
return false;
|
||||
|
||||
} catch (e) {
|
||||
var err = "Error: " + e.message;
|
||||
console.log(err);
|
||||
setError(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function setInfo(msg, loading, error) {
|
||||
|
||||
try {
|
||||
if (msg == null || msg.length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var el = document.getElementById("spinner");
|
||||
|
||||
error = !!error;
|
||||
if (!error) {
|
||||
el.style.visibility = 'visible';
|
||||
} else {
|
||||
el.style.visibility = 'hidden';
|
||||
}
|
||||
|
||||
loading = !!loading;
|
||||
if (loading) {
|
||||
msg = "<p class=\"loading\">" + msg + "</p>";
|
||||
}
|
||||
|
||||
el = document.getElementById("info");
|
||||
|
||||
if (el.innerHTML != msg) {
|
||||
el.innerHTML = msg;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} catch (e) {
|
||||
console.log("Error: " + e.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function setError(text) {
|
||||
return setInfo(text, false, true);
|
||||
}
|
||||
|
||||
function schedule() {
|
||||
setTimeout(getInfo, interval);
|
||||
}
|
||||
|
||||
function reload() {
|
||||
setTimeout(() => {
|
||||
document.location.reload();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
schedule();
|
||||
@@ -1,59 +0,0 @@
|
||||
body {
|
||||
color: white;
|
||||
background-color: #125bdb;
|
||||
font-family: Verdana, Arial, sans-serif;
|
||||
}
|
||||
|
||||
#content-wrap {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
margin-top: 100px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
width: 98%;
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
height: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#empty-space {
|
||||
height: 40px;
|
||||
/* Same height as footer */
|
||||
}
|
||||
|
||||
a,
|
||||
a:hover,
|
||||
a:active,
|
||||
a:visited {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.loading:after {
|
||||
content: " .";
|
||||
animation: dots 1s steps(5, end) infinite;
|
||||
}
|
||||
|
||||
@keyframes dots {
|
||||
|
||||
0%,
|
||||
20% {
|
||||
color: rgba(0, 0, 0, 0);
|
||||
text-shadow: 0.25em 0 0 rgba(0, 0, 0, 0), 0.5em 0 0 rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
40% {
|
||||
color: white;
|
||||
text-shadow: 0.25em 0 0 rgba(0, 0, 0, 0), 0.5em 0 0 rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
60% {
|
||||
text-shadow: 0.25em 0 0 white, 0.5em 0 0 rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
80%,
|
||||
100% {
|
||||
text-shadow: 0.25em 0 0 white, 0.5em 0 0 white;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user