Loading src/check.sh 0 → 100644 +20 −0 Original line number Diff line number Diff line #!/usr/bin/env bash set -Eeuo pipefail : "${NETWORK:="Y"}" [ -f "/run/shm/qemu.end" ] && echo "QEMU is shutting down.." && exit 1 [ ! -s "/run/shm/qemu.pid" ] && echo "QEMU is not running yet.." && exit 0 [[ "$NETWORK" == [Nn]* ]] && echo "Networking is disabled.." && exit 0 file="/run/shm/qemu.url" [ ! -s "$file" ] && echo "The container has not enabled networking yet..." && exit 1 url=$(<"$file") if ! curl -m 20 -LfSs -o /dev/null "$url"; then echo "Failed to reach VM at $url" && exit 1 fi echo "Healthcheck OK" exit 0 src/entry.sh +1 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ cd /run . network.sh # Initialize network . boot.sh # Configure boot . proc.sh # Initialize processor . power.sh # Configure shutdown . memory.sh # Check available memory . balloon.sh # Initialize ballooning . config.sh # Configure arguments Loading src/network.sh +4 −1 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ set -Eeuo pipefail : "${NETWORK:="Y"}" : "${HOST_PORTS:=""}" : "${USER_PORTS:=""}" : "${CHECK_PORT:="80"}" : "${ADAPTER:="virtio-net-pci"}" : "${VM_NET_IP:=""}" Loading Loading @@ -944,7 +945,9 @@ fi NET_OPTS+=" -device $ADAPTER,id=net0,netdev=hostnet0,romfile=,mac=$VM_NET_MAC" [[ "$MTU" != "0" && "$MTU" != "1500" ]] && NET_OPTS+=",host_mtu=$MTU" echo "$VM_NET_IP" > /run/shm/qemu.ip echo "$VM_NET_IP" > "$QEMU_DIR"/qemu.ip echo "http://$VM_NET_IP:$CHECK_PORT" > "$QEMU_DIR"/qemu.url html "Initialized network successfully..." return 0 src/power.sh 0 → 100644 +180 −0 Original line number Diff line number Diff line #!/usr/bin/env bash set -Eeuo pipefail : "${SHUTDOWN:="N"}" # Graceful ACPI shutdown : "${QEMU_TIMEOUT:="110"}" # QEMU Termination timeout # Configure QEMU for graceful shutdown QEMU_TERM="" QEMU_PTY="$QEMU_DIR/qemu.pty" QEMU_LOG="$QEMU_DIR/qemu.log" QEMU_OUT="$QEMU_DIR/qemu.out" QEMU_END="$QEMU_DIR/qemu.end" _trap() { local func="$1"; shift local sig for sig; do trap "$func $sig" "$sig" done } finish() { local pid local cnt=0 local reason=$1 local pids=( "/var/run/tpm.pid" ) touch "$QEMU_END" if [ -s "$QEMU_PID" ]; then pid=$(<"$QEMU_PID") echo && error "Forcefully terminating QEMU, reason: $reason..." { kill -15 "$pid" || true; } 2>/dev/null while isAlive "$pid"; do sleep 1 (( cnt++ )) # Workaround for zombie pid [ ! -s "$QEMU_PID" ] && break if [ "$cnt" -eq 5 ]; then echo && error "QEMU did not terminate itself, forcefully killing process..." { kill -9 "$pid" || true; } 2>/dev/null fi done fi for pid in "${pids[@]}"; do if [[ -s "$pid" ]]; then pKill "$(<"$pid")" fi rm -f "$pid" done closeNetwork sleep 0.5 echo "❯ Shutdown completed!" exit "$reason" } terminal() { local dev="" if [ -s "$QEMU_OUT" ]; then local msg msg=$(<"$QEMU_OUT") if [ -n "$msg" ]; then if [[ "${msg,,}" != "char"* || "$msg" != *"serial0)" ]]; then echo "$msg" fi dev="${msg#*/dev/p}" dev="/dev/p${dev%% *}" fi fi if [ ! -c "$dev" ]; then dev=$(echo 'info chardev' | nc -q 1 -w 1 localhost "$MON_PORT" | tr -d '\000') dev="${dev#*serial0}" dev="${dev#*pty:}" dev="${dev%%$'\n'*}" dev="${dev%%$'\r'*}" fi if [ ! -c "$dev" ]; then error "Device '$dev' not found!" finish 34 && return 34 fi QEMU_TERM="$dev" return 0 } _graceful_shutdown() { local sig="$1" local code=0 case "$sig" in SIGTERM) code=143 ;; SIGINT) code=130 ;; SIGHUP) code=129 ;; SIGABRT) code=134 ;; SIGQUIT) code=131 ;; esac set +e if [ -f "$QEMU_END" ]; then info "Received $1 while already shutting down..." return fi touch "$QEMU_END" info "Received $1, sending ACPI shutdown signal..." if [ ! -s "$QEMU_PID" ]; then error "QEMU PID file does not exist?" finish "$code" && return "$code" fi local pid="" pid=$(<"$QEMU_PID") if ! isAlive "$pid"; then error "QEMU process does not exist?" finish "$code" && return "$code" fi # Send ACPI shutdown signal echo 'system_powerdown' | nc -q 1 -w 1 localhost "$MON_PORT" > /dev/null local cnt=0 while [ "$cnt" -lt "$QEMU_TIMEOUT" ]; do sleep 1 (( cnt++ )) ! isAlive "$pid" && break # Workaround for zombie pid [ ! -s "$QEMU_PID" ] && break info "Waiting for VM to shutdown... ($cnt/$QEMU_TIMEOUT)" # Send ACPI shutdown signal echo 'system_powerdown' | nc -q 1 -w 1 localhost "$MON_PORT" > /dev/null done if [ "$cnt" -ge "$QEMU_TIMEOUT" ]; then error "Shutdown timeout reached, aborting..." fi finish "$code" && return "$code" } [[ "$SHUTDOWN" != [Yy1]* ]] && return 0 touch "$QEMU_LOG" SERIAL="pty" MONITOR="telnet:localhost:$MON_PORT,server,nowait,nodelay -daemonize -D $QEMU_LOG" _trap _graceful_shutdown SIGTERM SIGHUP SIGINT SIGABRT SIGQUIT return 0 src/reset.sh +6 −1 Original line number Diff line number Diff line Loading @@ -103,7 +103,6 @@ else fi QEMU_PID="$QEMU_DIR/qemu.pid" rm -f "$QEMU_PID" # Check folder Loading Loading @@ -227,4 +226,10 @@ if [[ "$KVM" != [Nn]* ]]; then fi # Cleanup dirs rm -rf "$STORAGE/tmp" # Cleanup files rm -f "$QEMU_DIR"/qemu.* return 0 Loading
src/check.sh 0 → 100644 +20 −0 Original line number Diff line number Diff line #!/usr/bin/env bash set -Eeuo pipefail : "${NETWORK:="Y"}" [ -f "/run/shm/qemu.end" ] && echo "QEMU is shutting down.." && exit 1 [ ! -s "/run/shm/qemu.pid" ] && echo "QEMU is not running yet.." && exit 0 [[ "$NETWORK" == [Nn]* ]] && echo "Networking is disabled.." && exit 0 file="/run/shm/qemu.url" [ ! -s "$file" ] && echo "The container has not enabled networking yet..." && exit 1 url=$(<"$file") if ! curl -m 20 -LfSs -o /dev/null "$url"; then echo "Failed to reach VM at $url" && exit 1 fi echo "Healthcheck OK" exit 0
src/entry.sh +1 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ cd /run . network.sh # Initialize network . boot.sh # Configure boot . proc.sh # Initialize processor . power.sh # Configure shutdown . memory.sh # Check available memory . balloon.sh # Initialize ballooning . config.sh # Configure arguments Loading
src/network.sh +4 −1 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ set -Eeuo pipefail : "${NETWORK:="Y"}" : "${HOST_PORTS:=""}" : "${USER_PORTS:=""}" : "${CHECK_PORT:="80"}" : "${ADAPTER:="virtio-net-pci"}" : "${VM_NET_IP:=""}" Loading Loading @@ -944,7 +945,9 @@ fi NET_OPTS+=" -device $ADAPTER,id=net0,netdev=hostnet0,romfile=,mac=$VM_NET_MAC" [[ "$MTU" != "0" && "$MTU" != "1500" ]] && NET_OPTS+=",host_mtu=$MTU" echo "$VM_NET_IP" > /run/shm/qemu.ip echo "$VM_NET_IP" > "$QEMU_DIR"/qemu.ip echo "http://$VM_NET_IP:$CHECK_PORT" > "$QEMU_DIR"/qemu.url html "Initialized network successfully..." return 0
src/power.sh 0 → 100644 +180 −0 Original line number Diff line number Diff line #!/usr/bin/env bash set -Eeuo pipefail : "${SHUTDOWN:="N"}" # Graceful ACPI shutdown : "${QEMU_TIMEOUT:="110"}" # QEMU Termination timeout # Configure QEMU for graceful shutdown QEMU_TERM="" QEMU_PTY="$QEMU_DIR/qemu.pty" QEMU_LOG="$QEMU_DIR/qemu.log" QEMU_OUT="$QEMU_DIR/qemu.out" QEMU_END="$QEMU_DIR/qemu.end" _trap() { local func="$1"; shift local sig for sig; do trap "$func $sig" "$sig" done } finish() { local pid local cnt=0 local reason=$1 local pids=( "/var/run/tpm.pid" ) touch "$QEMU_END" if [ -s "$QEMU_PID" ]; then pid=$(<"$QEMU_PID") echo && error "Forcefully terminating QEMU, reason: $reason..." { kill -15 "$pid" || true; } 2>/dev/null while isAlive "$pid"; do sleep 1 (( cnt++ )) # Workaround for zombie pid [ ! -s "$QEMU_PID" ] && break if [ "$cnt" -eq 5 ]; then echo && error "QEMU did not terminate itself, forcefully killing process..." { kill -9 "$pid" || true; } 2>/dev/null fi done fi for pid in "${pids[@]}"; do if [[ -s "$pid" ]]; then pKill "$(<"$pid")" fi rm -f "$pid" done closeNetwork sleep 0.5 echo "❯ Shutdown completed!" exit "$reason" } terminal() { local dev="" if [ -s "$QEMU_OUT" ]; then local msg msg=$(<"$QEMU_OUT") if [ -n "$msg" ]; then if [[ "${msg,,}" != "char"* || "$msg" != *"serial0)" ]]; then echo "$msg" fi dev="${msg#*/dev/p}" dev="/dev/p${dev%% *}" fi fi if [ ! -c "$dev" ]; then dev=$(echo 'info chardev' | nc -q 1 -w 1 localhost "$MON_PORT" | tr -d '\000') dev="${dev#*serial0}" dev="${dev#*pty:}" dev="${dev%%$'\n'*}" dev="${dev%%$'\r'*}" fi if [ ! -c "$dev" ]; then error "Device '$dev' not found!" finish 34 && return 34 fi QEMU_TERM="$dev" return 0 } _graceful_shutdown() { local sig="$1" local code=0 case "$sig" in SIGTERM) code=143 ;; SIGINT) code=130 ;; SIGHUP) code=129 ;; SIGABRT) code=134 ;; SIGQUIT) code=131 ;; esac set +e if [ -f "$QEMU_END" ]; then info "Received $1 while already shutting down..." return fi touch "$QEMU_END" info "Received $1, sending ACPI shutdown signal..." if [ ! -s "$QEMU_PID" ]; then error "QEMU PID file does not exist?" finish "$code" && return "$code" fi local pid="" pid=$(<"$QEMU_PID") if ! isAlive "$pid"; then error "QEMU process does not exist?" finish "$code" && return "$code" fi # Send ACPI shutdown signal echo 'system_powerdown' | nc -q 1 -w 1 localhost "$MON_PORT" > /dev/null local cnt=0 while [ "$cnt" -lt "$QEMU_TIMEOUT" ]; do sleep 1 (( cnt++ )) ! isAlive "$pid" && break # Workaround for zombie pid [ ! -s "$QEMU_PID" ] && break info "Waiting for VM to shutdown... ($cnt/$QEMU_TIMEOUT)" # Send ACPI shutdown signal echo 'system_powerdown' | nc -q 1 -w 1 localhost "$MON_PORT" > /dev/null done if [ "$cnt" -ge "$QEMU_TIMEOUT" ]; then error "Shutdown timeout reached, aborting..." fi finish "$code" && return "$code" } [[ "$SHUTDOWN" != [Yy1]* ]] && return 0 touch "$QEMU_LOG" SERIAL="pty" MONITOR="telnet:localhost:$MON_PORT,server,nowait,nodelay -daemonize -D $QEMU_LOG" _trap _graceful_shutdown SIGTERM SIGHUP SIGINT SIGABRT SIGQUIT return 0
src/reset.sh +6 −1 Original line number Diff line number Diff line Loading @@ -103,7 +103,6 @@ else fi QEMU_PID="$QEMU_DIR/qemu.pid" rm -f "$QEMU_PID" # Check folder Loading Loading @@ -227,4 +226,10 @@ if [[ "$KVM" != [Nn]* ]]; then fi # Cleanup dirs rm -rf "$STORAGE/tmp" # Cleanup files rm -f "$QEMU_DIR"/qemu.* return 0