diff --git a/Dockerfile b/Dockerfile index 6352e5f..59a7820 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,11 +12,14 @@ RUN apk add --no-cache \ qemu-hw-usb-host \ qemu-hw-usb-redirect \ nginx \ + netcat-openbsd \ && mkdir -p /usr/share/novnc \ && wget https://github.com/novnc/noVNC/archive/refs/tags/v${NOVNC_VERSION}.tar.gz -O /tmp/novnc.tar.gz -q \ && tar -xf /tmp/novnc.tar.gz -C /tmp/ \ && cd /tmp/noVNC-${NOVNC_VERSION}\ && mv app core vendor package.json *.html /usr/share/novnc \ + && wget https://github.com/OliveTin/OliveTin/releases/latest/download/OliveTin_linux_arm64.apk \ + && apk add --allow-untrusted OliveTin_linux_arm64.apk \ && sed -i 's/^worker_processes.*/worker_processes 1;/' /etc/nginx/nginx.conf # export OPENWRT_VERSION=`date '+%Y%M%W'`_$OPENWRT_VERSION \ diff --git a/src/entry.sh b/src/entry.sh index 8edae70..72b1549 100755 --- a/src/entry.sh +++ b/src/entry.sh @@ -139,7 +139,7 @@ if [ -f /storage/old_version ]; then chmod +x /mnt/etc/rc.local umount /mnt - info "Boot previos $OLD_VERSION_ROOTFS to get config" + info "Boot previous $OLD_VERSION_ROOTFS to get config" qemu-system-aarch64 -M virt \ -m 128 \ -nodefaults \ @@ -220,7 +220,8 @@ exec qemu-system-aarch64 -M virt \ -device qemu-xhci -device usb-kbd \ $LAN_ARGS \ $WAN_ARGS \ - $USB_ARGS + $USB_ARGS \ + -qmp unix:/run/qmp-sock,server=on,wait=off # -device virtio-net,netdev=qlan1 -netdev user,id=qlan1,net=192.168.1.0/24,hostfwd=tcp::8000-192.168.1.1:80 \ # -blockdev driver=raw,node-name=hd0,cache.direct=on,file.driver=file,file.filename=/var/vm/openwrt-armsr-armv8-generic-ext4-combined.img \ diff --git a/src/qemu_qmp.sh b/src/qemu_qmp.sh new file mode 100644 index 0000000..95c5e87 --- /dev/null +++ b/src/qemu_qmp.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# Source: https://www.redhat.com/sysadmin/arguments-options-bash-scripts + +VERSION=0.1 + +############################################################ +# Help # +############################################################ +Help() +{ + # Display Help + echo "Small helper to interact with qemu QMP" + echo + echo "Syntax: qemu_qmp [-r|h|v]" + echo "options:" + echo "r Reset VM." + echo "h Print this Help." + echo "v Print software version and exit." + echo +} + +############################################################ +############################################################ +# Main program # +############################################################ +############################################################ +############################################################ +# Process the input options. Add options as needed. # +############################################################ +# Get the options +while getopts ":hvrqf" option; do + case $option in + h) # display Help + Help + exit;; + v) # Show version + echo $VERSION + exit;; + r) # Reset VM + echo -ne '{ "execute": "qmp_capabilities" } { "execute": "system_reset" }' | nc -w 1 -U /run/qmp-sock + exit;; + q) # Quit Qemu + echo -ne '{ "execute": "qmp_capabilities" } { "execute": "quit" }' | nc -w 1 -U /run/qmp-sock + exit;; + f) # Apply factory reset + rm /storage/current_version + rm /storage/rootfs-${OPENWRT_VERSION}.img + echo -ne '{ "execute": "qmp_capabilities" } { "execute": "quit" }' | nc -w 1 -U /run/qmp-sock + exit;; + \?) # Invalid option + echo "Error: Invalid option" + Help + exit;; + esac +done + diff --git a/src/reset.sh b/src/reset.sh index 488088e..6fcd273 100644 --- a/src/reset.sh +++ b/src/reset.sh @@ -168,4 +168,8 @@ cp -r /var/www/* /run/shm html "Starting $APP for Docker..." nginx -e stderr +# Start OliveTin +cp -f /var/www/olivetin_config.yaml /etc/OliveTin/config.yaml +OliveTin 2> /var/log/olivetin.log & + return 0 diff --git a/web/css/style.css b/web/css/style.css index d17bfa2..b8b4735 100644 --- a/web/css/style.css +++ b/web/css/style.css @@ -1,154 +1,12 @@ -body { - color: white; - background-color: #125bdb; - font-family: Verdana, Arial, sans-serif; -} +div { + text-align:center; + } + + html, body, div, iframe { height: 100%; } -#content { - text-align: center; - padding: 20px; - margin-top: 50px; -} + iframe { + display:inline-block; + margin: 5px auto; + border: solid; + } -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 - } -} diff --git a/web/index.html b/web/index.html index 0f10e13..237c476 100644 --- a/web/index.html +++ b/web/index.html @@ -2,33 +2,17 @@
- [1] - [2] -" + msg + "
"; - } - - 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(); diff --git a/web/nginx.conf.generic b/web/nginx.conf.generic index 7ea33dc..6cc4f42 100644 --- a/web/nginx.conf.generic +++ b/web/nginx.conf.generic @@ -26,25 +26,17 @@ server { add_header Cache-Control "no-cache"; location / { - - root /run/shm; - - if ( -f /run/shm/index.html) { - break; - } - - try_files /index.html @vnc; + root /var/www; } - location @vnc { - - root /usr/share/novnc; + location /novnc { index vnc.html; + alias /usr/share/novnc; + try_files $uri $uri/ /vnc.html; - if ($request_uri = "/") { - return 301 /?resize=scale&autoconnect=true; + if ($request_uri = "/novnc/") { + return 301 ?resize=scale&autoconnect=true&reconnect_delay=2000&reconnect=true; } - } location /websockify { @@ -61,4 +53,14 @@ server { proxy_pass http://127.0.0.1:5700/; } + location /olivetin/ { + proxy_pass http://localhost:1337/; + proxy_redirect http://localhost:1337/ http://localhost/OliveTin/; + } + + location /websocket { + proxy_set_header Upgrade "websocket"; + proxy_set_header Connection "upgrade"; + proxy_pass http://localhost:1337/websocket; + } } diff --git a/web/olivetin_config.yaml b/web/olivetin_config.yaml new file mode 100644 index 0000000..b7dd02e --- /dev/null +++ b/web/olivetin_config.yaml @@ -0,0 +1,19 @@ +# There is a built-in micro proxy that will host the webui and REST API all on +# one port (this is called the "Single HTTP Frontend") and means you just need +# one open port in the container/firewalls/etc. +# +# Listen on all addresses available, port 1337 +listenAddressSingleHTTPFrontend: 0.0.0.0:1337 + +# Choose from INFO (default), WARN and DEBUG +logLevel: "INFO" + +# Actions (buttons) to show up on the WebUI: +actions: + - title: Restart Openwrt + shell: /run/qemu_qmp.sh -r + icon: restart + + - title: Factory reset + shell: /run/qemu_qmp.sh -f + icon: "⚙"