mirror of
https://github.com/dockur/windows.git
synced 2026-06-09 22:17:22 +01:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c768ba894d | |||
| 0c9472b62c | |||
| 8d2f27bd67 | |||
| bcae867d68 | |||
| 77c164a3fa | |||
| f088a60e2c | |||
| 6dc5ce7919 | |||
| ba478700de | |||
| 6e45deea2f | |||
| 0bc2380452 | |||
| e1732e66ec | |||
| 8f70ffa902 |
@@ -22,6 +22,7 @@ jobs:
|
||||
with:
|
||||
locale: "US"
|
||||
level: warning
|
||||
fail_level: error
|
||||
pattern: |
|
||||
*.md
|
||||
*.sh
|
||||
@@ -32,6 +33,7 @@ jobs:
|
||||
uses: reviewdog/action-hadolint@v1
|
||||
with:
|
||||
level: warning
|
||||
fail_level: error
|
||||
reporter: github-pr-review
|
||||
hadolint_ignore: DL3006 DL3008
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -40,6 +42,7 @@ jobs:
|
||||
uses: reviewdog/action-yamllint@v1
|
||||
with:
|
||||
level: warning
|
||||
fail_level: error
|
||||
reporter: github-pr-review
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
@@ -52,8 +55,10 @@ jobs:
|
||||
-
|
||||
name: Shellformat
|
||||
uses: reviewdog/action-shfmt@v1
|
||||
if: false
|
||||
with:
|
||||
level: warning
|
||||
fail_on_error: "true"
|
||||
shfmt_flags: "-i 2 -ci -bn"
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
@@ -61,6 +66,7 @@ jobs:
|
||||
uses: reviewdog/action-shellcheck@v1
|
||||
with:
|
||||
level: warning
|
||||
fail_level: error
|
||||
reporter: github-pr-review
|
||||
shellcheck_flags: -x -e SC1091 -e SC2001 -e SC2002 -e SC2034 -e SC2064 -e SC2153 -e SC2317 -e SC2028
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
ARG VERSION_ARG="latest"
|
||||
FROM scratch AS build-amd64
|
||||
|
||||
COPY --from=qemux/qemu:7.30 / /
|
||||
COPY --from=qemux/qemu:7.32 / /
|
||||
|
||||
ARG TARGETARCH
|
||||
ARG VERSION_WSDD="1.24"
|
||||
@@ -22,7 +22,7 @@ RUN set -eu && \
|
||||
cabextract \
|
||||
libxml2-utils \
|
||||
libarchive-tools && \
|
||||
wget "https://github.com/gershnik/wsdd-native/releases/download/v${VERSION_WSDD}/wsddn_${VERSION_WSDD}_${TARGETARCH}.deb" -O /tmp/wsddn.deb -q && \
|
||||
wget "https://github.com/gershnik/wsdd-native/releases/download/v${VERSION_WSDD}/wsddn_${VERSION_WSDD}_${TARGETARCH}.deb" -O /tmp/wsddn.deb -q --timeout=10 && \
|
||||
dpkg -i /tmp/wsddn.deb && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
@@ -36,7 +36,7 @@ FROM dockurr/windows-arm:${VERSION_ARG} AS build-arm64
|
||||
FROM build-${TARGETARCH}
|
||||
|
||||
ARG VERSION_ARG="0.00"
|
||||
RUN echo "$VERSION_ARG" > /run/version
|
||||
RUN echo "$VERSION_ARG" > /etc/version
|
||||
|
||||
VOLUME /storage
|
||||
EXPOSE 3389 8006
|
||||
|
||||
@@ -66,6 +66,7 @@ spec:
|
||||
claimName: windows-pvc
|
||||
- hostPath:
|
||||
path: /dev/kvm
|
||||
type: CharDevice
|
||||
name: dev-kvm
|
||||
- hostPath:
|
||||
path: /dev/net/tun
|
||||
|
||||
+8
-37
@@ -171,32 +171,26 @@ getLanguage() {
|
||||
"ar" | "ar-"* )
|
||||
short="ar"
|
||||
lang="Arabic"
|
||||
desc="$lang"
|
||||
culture="ar-SA" ;;
|
||||
"bg" | "bg-"* )
|
||||
short="bg"
|
||||
lang="Bulgarian"
|
||||
desc="$lang"
|
||||
culture="bg-BG" ;;
|
||||
"cs" | "cs-"* | "cz" | "cz-"* )
|
||||
short="cs"
|
||||
lang="Czech"
|
||||
desc="$lang"
|
||||
culture="cs-CZ" ;;
|
||||
"da" | "da-"* | "dk" | "dk-"* )
|
||||
short="da"
|
||||
lang="Danish"
|
||||
desc="$lang"
|
||||
culture="da-DK" ;;
|
||||
"de" | "de-"* )
|
||||
short="de"
|
||||
lang="German"
|
||||
desc="$lang"
|
||||
culture="de-DE" ;;
|
||||
"el" | "el-"* | "gr" | "gr-"* )
|
||||
short="el"
|
||||
lang="Greek"
|
||||
desc="$lang"
|
||||
culture="el-GR" ;;
|
||||
"gb" | "en-gb" )
|
||||
short="en-gb"
|
||||
@@ -206,7 +200,6 @@ getLanguage() {
|
||||
"en" | "en-"* )
|
||||
short="en"
|
||||
lang="English"
|
||||
desc="English"
|
||||
culture="en-US" ;;
|
||||
"mx" | "es-mx" )
|
||||
short="mx"
|
||||
@@ -216,17 +209,14 @@ getLanguage() {
|
||||
"es" | "es-"* )
|
||||
short="es"
|
||||
lang="Spanish"
|
||||
desc="$lang"
|
||||
culture="es-ES" ;;
|
||||
"et" | "et-"* )
|
||||
short="et"
|
||||
lang="Estonian"
|
||||
desc="$lang"
|
||||
culture="et-EE" ;;
|
||||
"fi" | "fi-"* )
|
||||
short="fi"
|
||||
lang="Finnish"
|
||||
desc="$lang"
|
||||
culture="fi-FI" ;;
|
||||
"ca" | "fr-ca" )
|
||||
short="ca"
|
||||
@@ -236,62 +226,50 @@ getLanguage() {
|
||||
"fr" | "fr-"* )
|
||||
short="fr"
|
||||
lang="French"
|
||||
desc="$lang"
|
||||
culture="fr-FR" ;;
|
||||
"he" | "he-"* | "il" | "il-"* )
|
||||
short="he"
|
||||
lang="Hebrew"
|
||||
desc="$lang"
|
||||
culture="he-IL" ;;
|
||||
"hr" | "hr-"* | "cr" | "cr-"* )
|
||||
short="hr"
|
||||
lang="Croatian"
|
||||
desc="$lang"
|
||||
culture="hr-HR" ;;
|
||||
"hu" | "hu-"* )
|
||||
short="hu"
|
||||
lang="Hungarian"
|
||||
desc="$lang"
|
||||
culture="hu-HU" ;;
|
||||
"it" | "it-"* )
|
||||
short="it"
|
||||
lang="Italian"
|
||||
desc="$lang"
|
||||
culture="it-IT" ;;
|
||||
"ja" | "ja-"* | "jp" | "jp-"* )
|
||||
short="ja"
|
||||
lang="Japanese"
|
||||
desc="$lang"
|
||||
culture="ja-JP" ;;
|
||||
"ko" | "ko-"* | "kr" | "kr-"* )
|
||||
short="ko"
|
||||
lang="Korean"
|
||||
desc="$lang"
|
||||
culture="ko-KR" ;;
|
||||
"lt" | "lt-"* )
|
||||
short="lt"
|
||||
lang="Lithuanian"
|
||||
desc="$lang"
|
||||
culture="lt-LT" ;;
|
||||
"lv" | "lv-"* )
|
||||
short="lv"
|
||||
lang="Latvian"
|
||||
desc="$lang"
|
||||
culture="lv-LV" ;;
|
||||
"nb" | "nb-"* | "nn" | "nn-"* | "no" | "no-"* )
|
||||
short="no"
|
||||
lang="Norwegian"
|
||||
desc="$lang"
|
||||
culture="nb-NO" ;;
|
||||
"nl" | "nl-"* )
|
||||
short="nl"
|
||||
lang="Dutch"
|
||||
desc="$lang"
|
||||
culture="nl-NL" ;;
|
||||
"pl" | "pl-"* )
|
||||
short="pl"
|
||||
lang="Polish"
|
||||
desc="$lang"
|
||||
culture="pl-PL" ;;
|
||||
"br" | "pt-br" )
|
||||
short="pt"
|
||||
@@ -301,27 +279,22 @@ getLanguage() {
|
||||
"pt" | "pt-"* )
|
||||
short="pp"
|
||||
lang="Portuguese"
|
||||
desc="$lang"
|
||||
culture="pt-BR" ;;
|
||||
"ro" | "ro-"* )
|
||||
short="ro"
|
||||
lang="Romanian"
|
||||
desc="$lang"
|
||||
culture="ro-RO" ;;
|
||||
"ru" | "ru-"* )
|
||||
short="ru"
|
||||
lang="Russian"
|
||||
desc="$lang"
|
||||
culture="ru-RU" ;;
|
||||
"sk" | "sk-"* )
|
||||
short="sk"
|
||||
lang="Slovak"
|
||||
desc="$lang"
|
||||
culture="sk-SK" ;;
|
||||
"sl" | "sl-"* | "si" | "si-"* )
|
||||
short="sl"
|
||||
lang="Slovenian"
|
||||
desc="$lang"
|
||||
culture="sl-SI" ;;
|
||||
"sr" | "sr-"* )
|
||||
short="sr"
|
||||
@@ -331,22 +304,18 @@ getLanguage() {
|
||||
"sv" | "sv-"* | "se" | "se-"* )
|
||||
short="sv"
|
||||
lang="Swedish"
|
||||
desc="$lang"
|
||||
culture="sv-SE" ;;
|
||||
"th" | "th-"* )
|
||||
short="th"
|
||||
lang="Thai"
|
||||
desc="$lang"
|
||||
culture="th-TH" ;;
|
||||
"tr" | "tr-"* )
|
||||
short="tr"
|
||||
lang="Turkish"
|
||||
desc="$lang"
|
||||
culture="tr-TR" ;;
|
||||
"ua" | "ua-"* | "uk" | "uk-"* )
|
||||
short="uk"
|
||||
lang="Ukrainian"
|
||||
desc="$lang"
|
||||
culture="uk-UA" ;;
|
||||
"hk" | "zh-hk" | "cn-hk" )
|
||||
short="hk"
|
||||
@@ -365,6 +334,8 @@ getLanguage() {
|
||||
culture="zh-CN" ;;
|
||||
esac
|
||||
|
||||
[ -z "$desc" ] && desc="$lang"
|
||||
|
||||
case "${ret,,}" in
|
||||
"desc" ) echo "$desc" ;;
|
||||
"name" ) echo "$lang" ;;
|
||||
@@ -1577,8 +1548,8 @@ prepareInstall() {
|
||||
[ -z "$WIDTH" ] && WIDTH="1280"
|
||||
[ -z "$HEIGHT" ] && HEIGHT="720"
|
||||
|
||||
XHEX=$(printf '%x\n' "$WIDTH")
|
||||
YHEX=$(printf '%x\n' "$HEIGHT")
|
||||
XHEX=$(printf '%08x\n' "$WIDTH")
|
||||
YHEX=$(printf '%08x\n' "$HEIGHT")
|
||||
|
||||
local username=""
|
||||
local password=""
|
||||
@@ -1697,13 +1668,13 @@ prepareInstall() {
|
||||
echo ""
|
||||
echo "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Video\{23A77BF7-ED96-40EC-AF06-9B1F4867732A}\0000]"
|
||||
echo "\"DefaultSettings.BitsPerPel\"=dword:00000020"
|
||||
echo "\"DefaultSettings.XResolution\"=dword:00000$XHEX"
|
||||
echo "\"DefaultSettings.YResolution\"=dword:00000$YHEX"
|
||||
echo "\"DefaultSettings.XResolution\"=dword:$XHEX"
|
||||
echo "\"DefaultSettings.YResolution\"=dword:$YHEX"
|
||||
echo ""
|
||||
echo "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Control\VIDEO\{23A77BF7-ED96-40EC-AF06-9B1F4867732A}\0000]"
|
||||
echo "\"DefaultSettings.BitsPerPel\"=dword:00000020"
|
||||
echo "\"DefaultSettings.XResolution\"=dword:00000$XHEX"
|
||||
echo "\"DefaultSettings.YResolution\"=dword:00000$YHEX"
|
||||
echo "\"DefaultSettings.XResolution\"=dword:$XHEX"
|
||||
echo "\"DefaultSettings.YResolution\"=dword:$YHEX"
|
||||
echo ""
|
||||
echo "[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce]"
|
||||
echo "\"ScreenSaver\"=\"reg add \\\"HKCU\\\\Control Panel\\\\Desktop\\\" /f /v \\\"SCRNSAVE.EXE\\\" /t REG_SZ /d \\\"off\\\"\""
|
||||
|
||||
+26
-12
@@ -29,21 +29,35 @@ cd /run
|
||||
|
||||
trap - ERR
|
||||
|
||||
version=$(qemu-system-x86_64 --version | head -n 1 | cut -d '(' -f 1 | awk '{ print $NF }')
|
||||
cmd=(qemu-system-x86_64)
|
||||
version=$("${cmd[@]}" --version | awk 'NR==1 { print $4 }')
|
||||
info "Booting ${APP}${BOOT_DESC} using QEMU v$version..."
|
||||
|
||||
{ qemu-system-x86_64 ${ARGS:+ $ARGS} >"$QEMU_OUT" 2>"$QEMU_LOG"; rc=$?; } || :
|
||||
(( rc != 0 )) && error "$(<"$QEMU_LOG")" && exit 15
|
||||
pipe="$QEMU_DIR/qemu.pipe"
|
||||
rm -f "$pipe" && mkfifo "$pipe"
|
||||
|
||||
terminal
|
||||
tee "$QEMU_PTY" <"$pipe" |
|
||||
sed -u \
|
||||
-e 's/\x1B\[[=0-9;]*[a-z]//gi' \
|
||||
-e 's/\x1B\x63//g' \
|
||||
-e 's/\x1B\[[=?]7l//g' \
|
||||
-e '/^$/d' \
|
||||
-e 's/\x44\x53\x73//g' \
|
||||
-e 's/failed to load Boot/skipped Boot/g' \
|
||||
-e 's/0): Not Found/0)/g' &
|
||||
|
||||
if [[ "$SHUTDOWN" != [Yy1]* ]]; then
|
||||
exec "${cmd[@]}" ${ARGS:+ $ARGS} >"$pipe"
|
||||
fi
|
||||
|
||||
"${cmd[@]}" ${ARGS:+ $ARGS} >"$pipe" &
|
||||
|
||||
pid=$!
|
||||
( sleep 30; boot ) &
|
||||
tail -fn +0 "$QEMU_LOG" --pid=$$ 2>/dev/null &
|
||||
cat "$QEMU_TERM" 2> /dev/null | tee "$QEMU_PTY" | \
|
||||
sed -u -e 's/\x1B\[[=0-9;]*[a-z]//gi' \
|
||||
-e 's/\x1B\x63//g' -e 's/\x1B\[[=?]7l//g' \
|
||||
-e '/^$/d' -e 's/\x44\x53\x73//g' \
|
||||
-e 's/failed to load Boot/skipped Boot/g' \
|
||||
-e 's/0): Not Found/0)/g' & wait $! || :
|
||||
|
||||
rc=0
|
||||
wait "$pid" || rc=$?
|
||||
[ -f "$QEMU_END" ] && exit "$rc"
|
||||
|
||||
sleep 1 & wait $!
|
||||
[ ! -f "$QEMU_END" ] && finish 0
|
||||
finish "$rc"
|
||||
|
||||
+5
-7
@@ -32,13 +32,11 @@ backup () {
|
||||
|
||||
while [ -d "$dir" ]
|
||||
do
|
||||
count=$((count+1))
|
||||
(( count++ ))
|
||||
folder="${name}.${count}"
|
||||
dir="$root/$folder"
|
||||
done
|
||||
|
||||
rm -rf "$dir"
|
||||
|
||||
if ! makeDir "$dir"; then
|
||||
error "Failed to create directory \"$dir\" !"
|
||||
return 1
|
||||
@@ -110,7 +108,7 @@ skipInstall() {
|
||||
[ ! -s "$iso" ] && return 1
|
||||
|
||||
# Check if the ISO was already processed by our script
|
||||
magic=$(dd if="$iso" seek=0 bs=1 count=1 status=none | tr -d '\000')
|
||||
magic=$(dd if="$iso" bs=1 count=1 status=none | tr -d '\000')
|
||||
magic="$(printf '%s' "$magic" | od -A n -t x1 -v | tr -d ' \n')"
|
||||
byte="16" && [[ "$MANUAL" == [Yy1]* ]] && byte="17"
|
||||
|
||||
@@ -164,7 +162,7 @@ startInstall() {
|
||||
fi
|
||||
|
||||
if ! makeDir "$TMP"; then
|
||||
error "Failed to create directory \"$TMP\" !"
|
||||
error "Failed to create directory \"$TMP\" !" && exit 50
|
||||
fi
|
||||
|
||||
if [ -z "$CUSTOM" ]; then
|
||||
@@ -224,7 +222,7 @@ finishInstall() {
|
||||
fi
|
||||
|
||||
local file="$STORAGE/windows.ver"
|
||||
cp -f /run/version "$file"
|
||||
cp -f /etc/version "$file"
|
||||
! setOwner "$file" && error "Failed to set the owner for \"$file\" !"
|
||||
|
||||
if [[ "$iso" == "$STORAGE/"* ]]; then
|
||||
@@ -1180,7 +1178,7 @@ buildImage() {
|
||||
error "Failed to locate file \"$ETFS\" in ISO image!" && return 1
|
||||
fi
|
||||
|
||||
size=$(du -h -b --max-depth=0 "$dir" | cut -f1)
|
||||
size=$(du -b --max-depth=0 "$dir" | cut -f1)
|
||||
size_gb=$(formatBytes "$size")
|
||||
space=$(df --output=avail -B 1 "$TMP" | tail -n 1)
|
||||
space_gb=$(formatBytes "$space")
|
||||
|
||||
+15
-27
@@ -63,18 +63,12 @@ download_windows() {
|
||||
local id="$1"
|
||||
local lang="$2"
|
||||
local desc="$3"
|
||||
local sku_id=""
|
||||
local sku_url=""
|
||||
local iso_url=""
|
||||
local iso_json=""
|
||||
local language=""
|
||||
local session_id=""
|
||||
local user_agent=""
|
||||
local download_type=""
|
||||
local windows_version=""
|
||||
local iso_download_link=""
|
||||
local download_page_html=""
|
||||
local product_edition_id=""
|
||||
local ovw="" rtick="" mdt="" sku_id="" sku_url=""
|
||||
local iso_url="" iso_json="" language="" org_id=""
|
||||
local instance_id="" vls_url="" ov_url="" ov_data=""
|
||||
local session_id="" user_agent="" download_type=""
|
||||
local windows_version="" iso_download_link=""
|
||||
local download_page_html="" product_edition_id=""
|
||||
local language_skuid_json=""
|
||||
local profile="606624d44113"
|
||||
|
||||
@@ -88,7 +82,6 @@ download_windows() {
|
||||
esac
|
||||
|
||||
local url="https://www.microsoft.com/en-us/software-download/windows$windows_version"
|
||||
[[ "${id,,}" == "win10"* ]] && url+="ISO"
|
||||
|
||||
# uuidgen: For MacOS (installed by default) and other systems (e.g. with no /proc) that don't have a kernel interface for generating random UUIDs
|
||||
session_id=$(cat /proc/sys/kernel/random/uuid 2> /dev/null || uuidgen --random)
|
||||
@@ -194,7 +187,10 @@ download_windows() {
|
||||
# If any request is going to be blocked by Microsoft it's always this last one (the previous requests always seem to succeed)
|
||||
|
||||
iso_url="https://www.microsoft.com/software-download-connector/api/GetProductDownloadLinksBySku?profile=$profile&ProductEditionId=undefined&SKU=$sku_id&friendlyFileName=undefined&Locale=en-US&sessionID=$session_id"
|
||||
iso_json=$(curl --silent --max-time 30 --request GET --user-agent "$user_agent" --referer "$url" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "$iso_url")
|
||||
iso_json=$(curl --silent --max-time 30 --request GET --user-agent "$user_agent" --referer "$url" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "$iso_url") || {
|
||||
handle_curl_error "$?" "Microsoft"
|
||||
return $?
|
||||
}
|
||||
|
||||
if ! [ "$iso_json" ]; then
|
||||
# This should only happen if there's been some change to how this API works
|
||||
@@ -229,13 +225,8 @@ download_windows_eval() {
|
||||
local id="$1"
|
||||
local lang="$2"
|
||||
local desc="$3"
|
||||
local filter=""
|
||||
local culture=""
|
||||
local compare=""
|
||||
local language=""
|
||||
local user_agent=""
|
||||
local enterprise_type=""
|
||||
local windows_version=""
|
||||
local filter="" culture="" compare="" language=""
|
||||
local user_agent="" enterprise_type="" windows_version=""
|
||||
|
||||
case "${id,,}" in
|
||||
"win11${PLATFORM,,}-enterprise-eval" )
|
||||
@@ -273,6 +264,7 @@ download_windows_eval() {
|
||||
culture=$(getLanguage "$lang" "culture")
|
||||
|
||||
local country="${culture#*-}"
|
||||
local iso_download_link=""
|
||||
local iso_download_links=""
|
||||
local iso_download_page_html=""
|
||||
local url="https://www.microsoft.com/en-us/evalcenter/download-$windows_version"
|
||||
@@ -512,12 +504,8 @@ getESD() {
|
||||
local version="$2"
|
||||
local lang="$3"
|
||||
local desc="$4"
|
||||
local file
|
||||
local result
|
||||
local culture
|
||||
local language
|
||||
local edition
|
||||
local catalog
|
||||
local file result culture
|
||||
local language edition catalog
|
||||
|
||||
file=$(getCatalog "$version" "file")
|
||||
catalog=$(getCatalog "$version" "url")
|
||||
|
||||
+94
-120
@@ -1,26 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
: "${QEMU_TIMEOUT:="110"}" # QEMU Termination timeout
|
||||
: "${SHUTDOWN:="Y"}" # Graceful ACPI shutdown
|
||||
: "${TIMEOUT:="115"}" # 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"
|
||||
|
||||
rm -f "$QEMU_DIR/qemu.*"
|
||||
touch "$QEMU_LOG"
|
||||
|
||||
_trap() {
|
||||
func="$1" ; shift
|
||||
for sig ; do
|
||||
local func="$1"; shift
|
||||
local sig
|
||||
TRAP_PID=$BASHPID
|
||||
|
||||
for sig; do
|
||||
trap "$func $sig" "$sig"
|
||||
done
|
||||
}
|
||||
|
||||
app() {
|
||||
echo "$APP" && return 0
|
||||
}
|
||||
|
||||
boot() {
|
||||
|
||||
[ -f "$QEMU_END" ] && return 0
|
||||
@@ -33,17 +35,14 @@ boot() {
|
||||
grep -Fq "BOOTMGR is missing" "$QEMU_PTY" && fail="y"
|
||||
fi
|
||||
if [ -z "$fail" ]; then
|
||||
info "Windows started successfully, visit http://127.0.0.1:8006/ to view the screen..."
|
||||
info "$(app) started successfully, visit http://127.0.0.1:8006/ to view the screen..."
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
error "Timeout while waiting for QEMU to boot the machine!"
|
||||
|
||||
local pid
|
||||
pid=$(<"$QEMU_PID")
|
||||
{ kill -15 "$pid" || true; } 2>/dev/null
|
||||
error "Timeout while waiting for QEMU to boot the machine, aborting..."
|
||||
sKill "$QEMU_PID"
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -71,39 +70,29 @@ ready() {
|
||||
|
||||
finish() {
|
||||
|
||||
local pid
|
||||
local cnt=0
|
||||
local i=0
|
||||
local pid=""
|
||||
local reason=$1
|
||||
local pids=(
|
||||
"/var/run/tpm.pid"
|
||||
"/var/run/wsdd.pid"
|
||||
"/var/run/samba/nmbd.pid"
|
||||
"/var/run/samba/smbd.pid"
|
||||
)
|
||||
local pids=( "${SMB_PID:-}" "${NMB_PID:-}" "${DDN_PID:-}" "${TPM_PID:-}" "${WSD_PID:-}" \
|
||||
"${WEB_PID:-}" "${PASST_PID:-}" "${DNSMASQ_PID:-}" "${BALLOONING_PID:-}" )
|
||||
|
||||
touch "$QEMU_END"
|
||||
|
||||
if [ -s "$QEMU_PID" ]; then
|
||||
|
||||
pid=$(<"$QEMU_PID")
|
||||
echo && error "Forcefully terminating Windows, reason: $reason..."
|
||||
{ kill -15 "$pid" || true; } 2>/dev/null
|
||||
|
||||
while isAlive "$pid"; do
|
||||
|
||||
sleep 1
|
||||
cnt=$((cnt+1))
|
||||
|
||||
# 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
|
||||
if read -r pid <"$QEMU_PID"; then
|
||||
if [ -n "$pid" ] && isAlive "$pid"; then
|
||||
local display="$reason"
|
||||
case "$reason" in
|
||||
129 ) display="SIGHUP" ;;
|
||||
130 ) display="SIGINT" ;;
|
||||
131 ) display="SIGQUIT" ;;
|
||||
134 ) display="SIGABRT" ;;
|
||||
143 ) display="SIGTERM" ;;
|
||||
esac
|
||||
error "Forcefully terminating $(app), reason: $display..."
|
||||
{ disown "$pid" || :; kill -9 -- "$pid" || :; } 2>/dev/null
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f "$STORAGE/windows.boot" ] && [ -f "$BOOT" ]; then
|
||||
@@ -118,121 +107,106 @@ finish() {
|
||||
fi
|
||||
fi
|
||||
|
||||
for pid in "${pids[@]}"; do
|
||||
if [[ -s "$pid" ]]; then
|
||||
pKill "$(cat "$pid")"
|
||||
fi
|
||||
rm -f "$pid"
|
||||
done
|
||||
|
||||
mKill "${pids[@]}"
|
||||
closeNetwork
|
||||
|
||||
sleep 0.5
|
||||
echo "❯ Shutdown completed!"
|
||||
if ! waitPidFile "$QEMU_PID" 10; then
|
||||
warn "Timed out while waiting for $(app) to exit!"
|
||||
fi
|
||||
|
||||
(( reason != 1 )) && echo && echo "❯ Shutdown completed!"
|
||||
exit "$reason"
|
||||
}
|
||||
|
||||
terminal() {
|
||||
graceful_shutdown() {
|
||||
|
||||
local dev=""
|
||||
local sig="$1"
|
||||
local pid=""
|
||||
local code=0
|
||||
|
||||
if [ -s "$QEMU_OUT" ]; then
|
||||
[[ $BASHPID != "$TRAP_PID" ]] && return
|
||||
|
||||
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 code=$?
|
||||
|
||||
set +e
|
||||
case "$sig" in
|
||||
SIGHUP) code=129 ;;
|
||||
SIGINT) code=130 ;;
|
||||
SIGQUIT) code=131 ;;
|
||||
SIGABRT) code=134 ;;
|
||||
SIGTERM) code=143 ;;
|
||||
esac
|
||||
|
||||
if [ -f "$QEMU_END" ]; then
|
||||
info "Received $1 while already shutting down..."
|
||||
echo && info "Received $1 signal while already shutting down..."
|
||||
return
|
||||
fi
|
||||
|
||||
set +e
|
||||
touch "$QEMU_END"
|
||||
info "Received $1, sending ACPI shutdown signal..."
|
||||
echo && info "Received $1 signal, sending ACPI shutdown signal..."
|
||||
|
||||
if [ ! -s "$QEMU_PID" ]; then
|
||||
error "QEMU PID file does not exist?"
|
||||
finish "$code" && return "$code"
|
||||
if [ ! -s "$QEMU_PID" ] || ! read -r pid <"$QEMU_PID"; then
|
||||
warn "QEMU PID file ($QEMU_PID) does not exist?"
|
||||
finish "$code"
|
||||
fi
|
||||
|
||||
local pid=""
|
||||
pid=$(<"$QEMU_PID")
|
||||
|
||||
if ! isAlive "$pid"; then
|
||||
error "QEMU process does not exist?"
|
||||
finish "$code" && return "$code"
|
||||
if [ -z "$pid" ] || ! isAlive "$pid"; then
|
||||
warn "QEMU process with PID $pid does not exist?"
|
||||
finish "$code"
|
||||
fi
|
||||
|
||||
if ! ready; then
|
||||
info "Cannot send ACPI signal during Windows setup, aborting..."
|
||||
finish "$code" && return "$code"
|
||||
info "Cannot send ACPI signal during $(app) setup, aborting..."
|
||||
sKill "$QEMU_PID"
|
||||
if ! waitPidFile "$QEMU_PID" 5; then
|
||||
warn "Timed out while waiting for $(app) to exit!"
|
||||
fi
|
||||
finish "$code"
|
||||
fi
|
||||
|
||||
# Send ACPI shutdown signal
|
||||
echo 'system_powerdown' | nc -q 1 -w 1 localhost "$MON_PORT" > /dev/null
|
||||
local cnt=0 abort=0 factor=3 offset=3 min max name
|
||||
|
||||
local cnt=0
|
||||
while [ "$cnt" -lt "$QEMU_TIMEOUT" ]; do
|
||||
[[ "$TIMEOUT" =~ ^[0-9]+$ ]] || TIMEOUT=115
|
||||
[ "$TIMEOUT" -ge 15 ] && factor=4 && offset=4
|
||||
[ "$TIMEOUT" -ge 30 ] && factor=5 && offset=5
|
||||
min=$((factor + offset + 1))
|
||||
[ "$TIMEOUT" -lt "$min" ] && TIMEOUT="$min"
|
||||
max=$(( TIMEOUT - offset ))
|
||||
abort=$(( max - factor ))
|
||||
name="$(app)"
|
||||
|
||||
sleep 1
|
||||
cnt=$((cnt+1))
|
||||
while [ "$cnt" -le "$max" ]; do
|
||||
|
||||
sleep 1 &
|
||||
local slp=$!
|
||||
|
||||
! isAlive "$pid" && break
|
||||
# Workaround for zombie pid
|
||||
[ ! -s "$QEMU_PID" ] && break
|
||||
|
||||
info "Waiting for Windows to shutdown... ($cnt/$QEMU_TIMEOUT)"
|
||||
if [ "$cnt" -ne "$abort" ]; then
|
||||
if [ "$cnt" -gt 0 ]; then
|
||||
info "Waiting for $name to shut down... ($cnt/$max)"
|
||||
fi
|
||||
else
|
||||
info "${name^} is still running, sending SIGTERM... ($cnt/$max)"
|
||||
{ kill -15 -- "$pid" || :; } 2>/dev/null
|
||||
fi
|
||||
|
||||
# Send ACPI shutdown signal
|
||||
echo 'system_powerdown' | nc -q 1 -w 1 localhost "$MON_PORT" > /dev/null
|
||||
if [ -S "$QEMU_DIR/monitor.sock" ]; then
|
||||
nc -q 1 -w 1 -U "$QEMU_DIR/monitor.sock" &> /dev/null <<<'system_powerdown' || :
|
||||
fi
|
||||
|
||||
wait $slp
|
||||
(( cnt++ ))
|
||||
|
||||
done
|
||||
|
||||
if [ "$cnt" -ge "$QEMU_TIMEOUT" ]; then
|
||||
error "Shutdown timeout reached, aborting..."
|
||||
fi
|
||||
|
||||
finish "$code" && return "$code"
|
||||
finish "$code"
|
||||
}
|
||||
|
||||
SERIAL="pty"
|
||||
MONITOR="telnet:localhost:$MON_PORT,server,nowait,nodelay -daemonize -D $QEMU_LOG"
|
||||
[[ "$SHUTDOWN" != [Yy1]* ]] && return 0
|
||||
[ -n "${QEMU_TIMEOUT:-}" ] && TIMEOUT="$QEMU_TIMEOUT"
|
||||
|
||||
_trap _graceful_shutdown SIGTERM SIGHUP SIGINT SIGABRT SIGQUIT
|
||||
_trap graceful_shutdown SIGTERM SIGHUP SIGABRT SIGQUIT
|
||||
|
||||
return 0
|
||||
|
||||
+11
-15
@@ -2,15 +2,16 @@
|
||||
set -Eeuo pipefail
|
||||
|
||||
: "${SAMBA:="Y"}" # Enable Samba
|
||||
: "${SAMBA_LEVEL:="1"}" # Logging level
|
||||
: "${SAMBA_DEBUG:="N"}" # Disable debug
|
||||
|
||||
tmp="/tmp/smb"
|
||||
rm -rf "$tmp"
|
||||
|
||||
rm -f /var/run/wsdd.pid
|
||||
rm -f /var/run/samba/nmbd.pid
|
||||
rm -f /var/run/samba/smbd.pid
|
||||
DDN_PID="/var/run/wsdd.pid"
|
||||
NMB_PID="/var/run/samba/nmbd.pid"
|
||||
SMB_PID="/var/run/samba/smbd.pid"
|
||||
|
||||
rm -f "$SMB_PID" "$NMB_PID" "$DDN_PID"
|
||||
|
||||
[[ "$SAMBA" == [Nn]* ]] && return 0
|
||||
[[ "$NETWORK" == [Nn]* ]] && return 0
|
||||
@@ -78,7 +79,7 @@ addShare() {
|
||||
if [[ "$dir" == "$tmp" ]]; then
|
||||
|
||||
{ echo "--------------------------------------------------------"
|
||||
echo " $APP for $ENGINE v$(</run/version)..."
|
||||
echo " $APP for $ENGINE v$(</etc/version)..."
|
||||
echo " For support visit $SUPPORT"
|
||||
echo "--------------------------------------------------------"
|
||||
echo ""
|
||||
@@ -151,18 +152,14 @@ share="/shared"
|
||||
|
||||
if [ -d "/shared2" ]; then
|
||||
addShare "/shared2" "/shared2" "Data2" "Shared" "$SAMBA_CONFIG" || :
|
||||
else
|
||||
if [ -d "/data2" ]; then
|
||||
addShare "/data2" "/shared2" "Data2" "Shared" "$SAMBA_CONFIG" || :
|
||||
fi
|
||||
elif [ -d "/data2" ]; then
|
||||
addShare "/data2" "/shared2" "Data2" "Shared" "$SAMBA_CONFIG" || :
|
||||
fi
|
||||
|
||||
if [ -d "/shared3" ]; then
|
||||
addShare "/shared3" "/shared3" "Data3" "Shared" "$SAMBA_CONFIG" || :
|
||||
else
|
||||
if [ -d "/data3" ]; then
|
||||
addShare "/data3" "/shared3" "Data3" "Shared" "$SAMBA_CONFIG" || :
|
||||
fi
|
||||
elif [ -d "/data3" ]; then
|
||||
addShare "/data3" "/shared3" "Data3" "Shared" "$SAMBA_CONFIG" || :
|
||||
fi
|
||||
|
||||
# Create directories if missing
|
||||
@@ -211,10 +208,9 @@ else
|
||||
|
||||
# Enable Web Service Discovery on Vista and up
|
||||
[[ "$DEBUG" == [Yy1]* ]] && echo "Starting wsddn daemon..."
|
||||
|
||||
rm -f /var/log/wsddn.log
|
||||
|
||||
if ! wsddn -i "${interfaces%%,*}" -H "$hostname" --unixd --log-file=/var/log/wsddn.log --pid-file=/var/run/wsdd.pid; then
|
||||
if ! wsddn -i "${interfaces%%,*}" -H "$hostname" --unixd --log-file=/var/log/wsddn.log --pid-file="$DDN_PID"; then
|
||||
SAMBA_DEBUG="Y"
|
||||
error "Failed to start wsddn daemon!"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user