Detect VM address

Detect VM address
This commit is contained in:
Kroese 2023-05-08 23:18:24 +02:00 committed by GitHub
commit 1c68f9e26c
7 changed files with 99 additions and 50 deletions

View File

@ -11,4 +11,4 @@ jobs:
- name: Run ShellCheck - name: Run ShellCheck
uses: ludeeus/action-shellcheck@master uses: ludeeus/action-shellcheck@master
env: env:
SHELLCHECK_OPTS: -x -e SC2001 -e SC2002 -e SC2223 -e SC2034 -e SC2064 -e SC2317 SHELLCHECK_OPTS: -x -e SC2001 -e SC2002 -e SC2223 -e SC2034 -e SC2064 -e SC2317 -e SC2028

View File

@ -27,8 +27,8 @@ RUN apt-get update && apt-get -y upgrade && \
net-tools \ net-tools \
btrfs-progs \ btrfs-progs \
ca-certificates \ ca-certificates \
netcat-openbsd \
qemu-system-x86 \ qemu-system-x86 \
netcat-traditional \
&& apt-get clean && apt-get clean
COPY run/*.sh /run/ COPY run/*.sh /run/
@ -65,6 +65,6 @@ LABEL org.opencontainers.image.version=${VERSION_ARG}
LABEL org.opencontainers.image.source=https://github.com/kroese/virtual-dsm/ LABEL org.opencontainers.image.source=https://github.com/kroese/virtual-dsm/
LABEL org.opencontainers.image.url=https://hub.docker.com/r/kroese/virtual-dsm/ LABEL org.opencontainers.image.url=https://hub.docker.com/r/kroese/virtual-dsm/
HEALTHCHECK --interval=30s --retries=3 CMD /run/check.sh HEALTHCHECK --interval=30s --retries=2 CMD /run/check.sh
ENTRYPOINT ["/run/run.sh"] ENTRYPOINT ["/run/run.sh"]

View File

@ -1,16 +1,47 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -u set -u
# Docker Healthcheck # Retrieve guest info for Docker healthcheck
RESPONSE=$(curl -s -m 6 -S http://127.0.0.1:2210/read?command=10 2>&1)
: ${DHCP:='N'} if [[ ! "${RESPONSE}" =~ "\"success\"" ]] ; then
echo "Failed to connect to guest: $RESPONSE"
exit 1
fi
if [[ "${DHCP}" == [Yy1]* ]]; then # Retrieve the HTTP port number
PORT=5555
IP="127.0.0.1" if [[ ! "${RESPONSE}" =~ "\"http_port\"" ]] ; then
else echo "Failed to parse response from guest: $RESPONSE"
PORT=5000 exit 1
IP="20.20.20.21" fi
rest=${RESPONSE#*http_port}
rest=${rest#*:}
rest=${rest%%,*}
PORT=${rest%%\"*}
if [ -z "${PORT}" ]; then
echo "Guest has not set a portnumber yet.."
exit 1
fi
# Retrieve the IP address
if [[ ! "${RESPONSE}" =~ "eth0" ]] ; then
echo "Failed to parse response from guest: $RESPONSE"
exit 1
fi
rest=${RESPONSE#*eth0}
rest=${rest#*ip}
rest=${rest#*:}
rest=${rest#*\"}
IP=${rest%%\"*}
if [ -z "${IP}" ]; then
echo "Guest has not received an IP yet.."
exit 1
fi fi
if ! curl -m 3 -ILfSs "http://${IP}:${PORT}/" > /dev/null; then if ! curl -m 3 -ILfSs "http://${IP}:${PORT}/" > /dev/null; then

View File

@ -5,9 +5,10 @@ set -Eeuo pipefail
HTML="Please wait while Virtual DSM is installing...<script>\ HTML="Please wait while Virtual DSM is installing...<script>\
setTimeout(() => { document.location.reload(); }, 9999);</script>" setTimeout(() => { document.location.reload(); }, 9999);</script>"
pkill -f server.sh || true { pkill -f server.sh || true; } 2>/dev/null
/run/server.sh 80 "${HTML}" > /dev/null &
/run/server.sh 5000 "${HTML}" > /dev/null & /run/server.sh 80 "${HTML}" &
/run/server.sh 5000 "${HTML}" &
# Download the required files from the Synology website # Download the required files from the Synology website
DL="https://global.synologydownload.com/download/DSM" DL="https://global.synologydownload.com/download/DSM"

View File

@ -31,8 +31,8 @@ configureDHCP() {
{ ip link add link "${VM_NET_DEV}" "${VM_NET_VLAN}" type macvlan mode bridge ; rc=$?; } || : { ip link add link "${VM_NET_DEV}" "${VM_NET_VLAN}" type macvlan mode bridge ; rc=$?; } || :
if (( rc != 0 )); then if (( rc != 0 )); then
echo -n "ERROR: Cannot create macvlan interface. Please make sure the network type is 'macvlan' and not 'ipvlan'." echo "ERROR: Cannot create macvlan interface. Please make sure the network type is 'macvlan' and not 'ipvlan',"
echo " And that the NET_ADMIN capability has been added to the container config: --cap-add NET_ADMIN" && exit 15 echo "ERROR: and that the NET_ADMIN capability has been added to the container config: --cap-add NET_ADMIN" && exit 15
fi fi
ip address add "${IP}" dev "${VM_NET_VLAN}" ip address add "${IP}" dev "${VM_NET_VLAN}"
@ -226,14 +226,26 @@ if [[ "${DHCP}" == [Yy1]* ]]; then
# Configuration for DHCP IP # Configuration for DHCP IP
configureDHCP configureDHCP
# Display the received IP on port 5000 { pkill -f server.sh || true; } 2>/dev/null
HTML="DSM is using another IP address.<br><br>Check the Docker logfile to see which one was<br> assigned, or download the\
<a href='https://global.synologydownload.com/download/Utility/Assistant/7.0.4-50051/Windows/synology-assistant-7.0.4-50051.exe'>\
Synology Assistant</a> utility."
pkill -f server.sh || true SH_SCRIPT="/run/ipinfo.sh"
/run/server.sh 80 "${HTML}" > /dev/null &
/run/server.sh 5000 "${HTML}" > /dev/null & { echo "#!/bin/bash"
echo "INFO=\$(curl -s -m 5 -S http://127.0.0.1:2210/read?command=10 2>/dev/null)"
echo "rest=\${INFO#*http_port}; rest=\${rest#*:}; rest=\${rest%%,*}; PORT=\${rest%%\\\"*}"
echo "rest=\${INFO#*eth0}; rest=\${rest#*ip}; rest=\${rest#*:}; rest=\${rest#*\\\"}; IP=\${rest%%\\\"*}"
echo "BODY=\"The location of DSM is <a href=\"http://\${IP}:\${PORT}\">http://\${IP}:\${PORT}</a><script>\\"
echo "setTimeout(function(){ window.location.assign('http://\${IP}:\${PORT}'); }, 3000);</script>\""
echo "HTML=\"<!DOCTYPE html><HTML><HEAD><TITLE>VirtualDSM</TITLE><STYLE>body { color: white; background-color: #125bdb; font-family: Verdana,\\"
echo "Arial,sans-serif; } a, a:hover, a:active, a:visited { color: white; }</STYLE></HEAD><BODY><BR><BR><H1><CENTER>\$BODY</CENTER></H1></BODY></HTML>\""
echo "LENGTH=\"\${#HTML}\"; RESPONSE=\"HTTP/1.1 200 OK\\nContent-Length: \${LENGTH}\\nConnection: close\\n\\n\$HTML\\n\\n\""
echo "echo -e \"\$RESPONSE\""
} > "$SH_SCRIPT"
chmod +x "$SH_SCRIPT"
/run/server.sh 80 "$SH_SCRIPT" &
/run/server.sh 5000 "$SH_SCRIPT" &
else else
@ -244,17 +256,6 @@ fi
NET_OPTS="${NET_OPTS} -device virtio-net-pci,romfile=,netdev=hostnet0,mac=${VM_NET_MAC},id=net0" NET_OPTS="${NET_OPTS} -device virtio-net-pci,romfile=,netdev=hostnet0,mac=${VM_NET_MAC},id=net0"
if [[ "${DHCP}" == [Yy1]* ]]; then
# Add extra LAN interface for Docker Healthcheck script
: ${MAC2:='02:11:32:CC:BB:AA'}
NET_OPTS="${NET_OPTS} -netdev user,id=hostnet1,restrict=y,hostfwd=tcp::5555-:5000"
NET_OPTS="${NET_OPTS} -device virtio-net-pci,romfile=,netdev=hostnet1,mac=${MAC2},id=net1"
fi
[[ "${DEBUG}" == [Yy1]* ]] && echo && echo "Finished network setup.." && echo [[ "${DEBUG}" == [Yy1]* ]] && echo && echo "Finished network setup.." && echo
return 0 return 0

View File

@ -33,7 +33,7 @@ _graceful_shutdown() {
# echo 'system_powerdown' | nc -q 1 -w 1 localhost "${QEMU_MONPORT}" > /dev/null # echo 'system_powerdown' | nc -q 1 -w 1 localhost "${QEMU_MONPORT}" > /dev/null
# Send shutdown command to guest agent via serial port # Send shutdown command to guest agent via serial port
RESPONSE=$(curl -s -m 2 -S http://127.0.0.1:2210/write?command=6 2>&1) RESPONSE=$(curl -s -m 5 -S http://127.0.0.1:2210/read?command=6 2>&1)
if [[ ! "${RESPONSE}" =~ "\"success\"" ]] ; then if [[ ! "${RESPONSE}" =~ "\"success\"" ]] ; then
@ -47,9 +47,13 @@ _graceful_shutdown() {
if ((AGENT_VERSION > 1)); then if ((AGENT_VERSION > 1)); then
# Send a NMI interrupt which will be detected by the kernel # Send a NMI interrupt which will be detected by the kernel
echo 'nmi' | nc -q 1 -w 1 localhost "${QEMU_MONPORT}" > /dev/null if ! echo 'nmi' | nc -q 1 -w 1 localhost "${QEMU_MONPORT}" > /dev/null ; then
AGENT_VERSION=0
else fi
fi
if ((AGENT_VERSION < 2)); then
echo && echo "Please update the VirtualDSM Agent to allow for gracefull shutdowns..." echo && echo "Please update the VirtualDSM Agent to allow for gracefull shutdowns..."
@ -65,7 +69,7 @@ _graceful_shutdown() {
echo $(($(cat ${_QEMU_SHUTDOWN_COUNTER})+1)) > ${_QEMU_SHUTDOWN_COUNTER} echo $(($(cat ${_QEMU_SHUTDOWN_COUNTER})+1)) > ${_QEMU_SHUTDOWN_COUNTER}
# Try to connect to qemu # Try to connect to qemu
if echo 'info version'| nc -q 1 -w 1 localhost "${QEMU_MONPORT}" > /dev/null; then if echo 'info version'| nc -q 1 -w 1 localhost "${QEMU_MONPORT}" >/dev/null 2>&1 ; then
sleep 1 sleep 1
#echo "Shutting down, waiting... ($(cat ${_QEMU_SHUTDOWN_COUNTER})/${QEMU_POWERDOWN_TIMEOUT})" #echo "Shutting down, waiting... ($(cat ${_QEMU_SHUTDOWN_COUNTER})/${QEMU_POWERDOWN_TIMEOUT})"
@ -75,7 +79,7 @@ _graceful_shutdown() {
done done
echo && echo "Quitting..." echo && echo "Quitting..."
echo 'quit' | nc -q 1 -w 1 localhost "${QEMU_MONPORT}" > /dev/null || true echo 'quit' | nc -q 1 -w 1 localhost "${QEMU_MONPORT}" >/dev/null 2>&1 || true
return return
} }

View File

@ -1,17 +1,29 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eu set -eu
trap 'kill 0' EXIT stop() {
trap exit SIGINT SIGTERM trap - SIGINT EXIT
{ pkill -f nc || true; } 2>/dev/null
}
# Serve the page trap 'stop' EXIT SIGINT SIGTERM SIGHUP
HTML="<!DOCTYPE html><HTML><HEAD><TITLE>VirtualDSM</TITLE><STYLE>body { color: white; background-color: #125bdb; font-family: Verdana,\
Arial,sans-serif; } a, a:hover, a:active, a:visited { color: white; }</STYLE></HEAD><BODY><BR><BR><H1><CENTER>$2</CENTER></H1></BODY></HTML>"
LENGTH="${#HTML}" if [[ "$2" == "/"* ]]; then
RESPONSE="HTTP/1.1 200 OK\nContent-Length: ${LENGTH}\nConnection: close\n\n$HTML\n\n" while true ; do
nc -lp "${1:-5000}" -e "$2" & wait $!
done
while true; do else
echo -en "$RESPONSE" | nc -lp "${1:-5000}" & wait $!
done HTML="<!DOCTYPE html><HTML><HEAD><TITLE>VirtualDSM</TITLE><STYLE>body { color: white; background-color: #125bdb; font-family: Verdana,\
Arial,sans-serif; } a, a:hover, a:active, a:visited { color: white; }</STYLE></HEAD><BODY><BR><BR><H1><CENTER>$2</CENTER></H1></BODY></HTML>"
LENGTH="${#HTML}"
RESPONSE="HTTP/1.1 200 OK\nContent-Length: ${LENGTH}\nConnection: close\n\n$HTML\n\n"
while true; do
echo -en "$RESPONSE" | nc -lp "${1:-5000}" & wait $!
done
fi