Compare commits

...

12 Commits

Author SHA1 Message Date
Kroese c768ba894d fix: Display signal names (#1760) 2026-06-05 03:14:50 +02:00
Kroese 0c9472b62c fix: Add fail_level to reviewdog actions (#1759) 2026-06-04 23:21:36 +02:00
Kroese 8d2f27bd67 feat: Improved start and stop logic (#1758) 2026-06-04 22:37:18 +02:00
Kroese bcae867d68 build: Update QEMU base image to v7.32 (#1755) 2026-06-04 12:49:26 +02:00
Kroese 77c164a3fa fix: Provide exitcode on shutdown (#1752) 2026-05-31 00:30:39 +02:00
Kroese f088a60e2c build: Update QEMU base image to v7.31 (#1751) 2026-05-30 15:53:42 +02:00
Kroese 6dc5ce7919 build: Add timeout to wsddn download (#1750) 2026-05-29 18:18:33 +02:00
Kroese ba478700de feat: Update version file path (#1749) 2026-05-29 16:31:47 +02:00
Kroese 6e45deea2f feat: Simplify increment syntax (#1747) 2026-05-29 15:50:53 +02:00
Kroese 0bc2380452 fix: Add CharDevice type to KVM hostPath (#1746) 2026-05-29 15:32:40 +02:00
Kroese e1732e66ec fix: High resolutions produce wrong hex value (#1745) 2026-05-29 14:48:30 +02:00
Kroese 8f70ffa902 build: Disable Shellformat action (#1744) 2026-05-29 13:17:18 +02:00
9 changed files with 169 additions and 221 deletions
+6
View File
@@ -22,6 +22,7 @@ jobs:
with: with:
locale: "US" locale: "US"
level: warning level: warning
fail_level: error
pattern: | pattern: |
*.md *.md
*.sh *.sh
@@ -32,6 +33,7 @@ jobs:
uses: reviewdog/action-hadolint@v1 uses: reviewdog/action-hadolint@v1
with: with:
level: warning level: warning
fail_level: error
reporter: github-pr-review reporter: github-pr-review
hadolint_ignore: DL3006 DL3008 hadolint_ignore: DL3006 DL3008
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -40,6 +42,7 @@ jobs:
uses: reviewdog/action-yamllint@v1 uses: reviewdog/action-yamllint@v1
with: with:
level: warning level: warning
fail_level: error
reporter: github-pr-review reporter: github-pr-review
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
- -
@@ -52,8 +55,10 @@ jobs:
- -
name: Shellformat name: Shellformat
uses: reviewdog/action-shfmt@v1 uses: reviewdog/action-shfmt@v1
if: false
with: with:
level: warning level: warning
fail_on_error: "true"
shfmt_flags: "-i 2 -ci -bn" shfmt_flags: "-i 2 -ci -bn"
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
- -
@@ -61,6 +66,7 @@ jobs:
uses: reviewdog/action-shellcheck@v1 uses: reviewdog/action-shellcheck@v1
with: with:
level: warning level: warning
fail_level: error
reporter: github-pr-review reporter: github-pr-review
shellcheck_flags: -x -e SC1091 -e SC2001 -e SC2002 -e SC2034 -e SC2064 -e SC2153 -e SC2317 -e SC2028 shellcheck_flags: -x -e SC1091 -e SC2001 -e SC2002 -e SC2034 -e SC2064 -e SC2153 -e SC2317 -e SC2028
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
+3 -3
View File
@@ -3,7 +3,7 @@
ARG VERSION_ARG="latest" ARG VERSION_ARG="latest"
FROM scratch AS build-amd64 FROM scratch AS build-amd64
COPY --from=qemux/qemu:7.30 / / COPY --from=qemux/qemu:7.32 / /
ARG TARGETARCH ARG TARGETARCH
ARG VERSION_WSDD="1.24" ARG VERSION_WSDD="1.24"
@@ -22,7 +22,7 @@ RUN set -eu && \
cabextract \ cabextract \
libxml2-utils \ libxml2-utils \
libarchive-tools && \ 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 && \ dpkg -i /tmp/wsddn.deb && \
apt-get clean && \ apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 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} FROM build-${TARGETARCH}
ARG VERSION_ARG="0.00" ARG VERSION_ARG="0.00"
RUN echo "$VERSION_ARG" > /run/version RUN echo "$VERSION_ARG" > /etc/version
VOLUME /storage VOLUME /storage
EXPOSE 3389 8006 EXPOSE 3389 8006
+1
View File
@@ -66,6 +66,7 @@ spec:
claimName: windows-pvc claimName: windows-pvc
- hostPath: - hostPath:
path: /dev/kvm path: /dev/kvm
type: CharDevice
name: dev-kvm name: dev-kvm
- hostPath: - hostPath:
path: /dev/net/tun path: /dev/net/tun
+8 -37
View File
@@ -171,32 +171,26 @@ getLanguage() {
"ar" | "ar-"* ) "ar" | "ar-"* )
short="ar" short="ar"
lang="Arabic" lang="Arabic"
desc="$lang"
culture="ar-SA" ;; culture="ar-SA" ;;
"bg" | "bg-"* ) "bg" | "bg-"* )
short="bg" short="bg"
lang="Bulgarian" lang="Bulgarian"
desc="$lang"
culture="bg-BG" ;; culture="bg-BG" ;;
"cs" | "cs-"* | "cz" | "cz-"* ) "cs" | "cs-"* | "cz" | "cz-"* )
short="cs" short="cs"
lang="Czech" lang="Czech"
desc="$lang"
culture="cs-CZ" ;; culture="cs-CZ" ;;
"da" | "da-"* | "dk" | "dk-"* ) "da" | "da-"* | "dk" | "dk-"* )
short="da" short="da"
lang="Danish" lang="Danish"
desc="$lang"
culture="da-DK" ;; culture="da-DK" ;;
"de" | "de-"* ) "de" | "de-"* )
short="de" short="de"
lang="German" lang="German"
desc="$lang"
culture="de-DE" ;; culture="de-DE" ;;
"el" | "el-"* | "gr" | "gr-"* ) "el" | "el-"* | "gr" | "gr-"* )
short="el" short="el"
lang="Greek" lang="Greek"
desc="$lang"
culture="el-GR" ;; culture="el-GR" ;;
"gb" | "en-gb" ) "gb" | "en-gb" )
short="en-gb" short="en-gb"
@@ -206,7 +200,6 @@ getLanguage() {
"en" | "en-"* ) "en" | "en-"* )
short="en" short="en"
lang="English" lang="English"
desc="English"
culture="en-US" ;; culture="en-US" ;;
"mx" | "es-mx" ) "mx" | "es-mx" )
short="mx" short="mx"
@@ -216,17 +209,14 @@ getLanguage() {
"es" | "es-"* ) "es" | "es-"* )
short="es" short="es"
lang="Spanish" lang="Spanish"
desc="$lang"
culture="es-ES" ;; culture="es-ES" ;;
"et" | "et-"* ) "et" | "et-"* )
short="et" short="et"
lang="Estonian" lang="Estonian"
desc="$lang"
culture="et-EE" ;; culture="et-EE" ;;
"fi" | "fi-"* ) "fi" | "fi-"* )
short="fi" short="fi"
lang="Finnish" lang="Finnish"
desc="$lang"
culture="fi-FI" ;; culture="fi-FI" ;;
"ca" | "fr-ca" ) "ca" | "fr-ca" )
short="ca" short="ca"
@@ -236,62 +226,50 @@ getLanguage() {
"fr" | "fr-"* ) "fr" | "fr-"* )
short="fr" short="fr"
lang="French" lang="French"
desc="$lang"
culture="fr-FR" ;; culture="fr-FR" ;;
"he" | "he-"* | "il" | "il-"* ) "he" | "he-"* | "il" | "il-"* )
short="he" short="he"
lang="Hebrew" lang="Hebrew"
desc="$lang"
culture="he-IL" ;; culture="he-IL" ;;
"hr" | "hr-"* | "cr" | "cr-"* ) "hr" | "hr-"* | "cr" | "cr-"* )
short="hr" short="hr"
lang="Croatian" lang="Croatian"
desc="$lang"
culture="hr-HR" ;; culture="hr-HR" ;;
"hu" | "hu-"* ) "hu" | "hu-"* )
short="hu" short="hu"
lang="Hungarian" lang="Hungarian"
desc="$lang"
culture="hu-HU" ;; culture="hu-HU" ;;
"it" | "it-"* ) "it" | "it-"* )
short="it" short="it"
lang="Italian" lang="Italian"
desc="$lang"
culture="it-IT" ;; culture="it-IT" ;;
"ja" | "ja-"* | "jp" | "jp-"* ) "ja" | "ja-"* | "jp" | "jp-"* )
short="ja" short="ja"
lang="Japanese" lang="Japanese"
desc="$lang"
culture="ja-JP" ;; culture="ja-JP" ;;
"ko" | "ko-"* | "kr" | "kr-"* ) "ko" | "ko-"* | "kr" | "kr-"* )
short="ko" short="ko"
lang="Korean" lang="Korean"
desc="$lang"
culture="ko-KR" ;; culture="ko-KR" ;;
"lt" | "lt-"* ) "lt" | "lt-"* )
short="lt" short="lt"
lang="Lithuanian" lang="Lithuanian"
desc="$lang"
culture="lt-LT" ;; culture="lt-LT" ;;
"lv" | "lv-"* ) "lv" | "lv-"* )
short="lv" short="lv"
lang="Latvian" lang="Latvian"
desc="$lang"
culture="lv-LV" ;; culture="lv-LV" ;;
"nb" | "nb-"* | "nn" | "nn-"* | "no" | "no-"* ) "nb" | "nb-"* | "nn" | "nn-"* | "no" | "no-"* )
short="no" short="no"
lang="Norwegian" lang="Norwegian"
desc="$lang"
culture="nb-NO" ;; culture="nb-NO" ;;
"nl" | "nl-"* ) "nl" | "nl-"* )
short="nl" short="nl"
lang="Dutch" lang="Dutch"
desc="$lang"
culture="nl-NL" ;; culture="nl-NL" ;;
"pl" | "pl-"* ) "pl" | "pl-"* )
short="pl" short="pl"
lang="Polish" lang="Polish"
desc="$lang"
culture="pl-PL" ;; culture="pl-PL" ;;
"br" | "pt-br" ) "br" | "pt-br" )
short="pt" short="pt"
@@ -301,27 +279,22 @@ getLanguage() {
"pt" | "pt-"* ) "pt" | "pt-"* )
short="pp" short="pp"
lang="Portuguese" lang="Portuguese"
desc="$lang"
culture="pt-BR" ;; culture="pt-BR" ;;
"ro" | "ro-"* ) "ro" | "ro-"* )
short="ro" short="ro"
lang="Romanian" lang="Romanian"
desc="$lang"
culture="ro-RO" ;; culture="ro-RO" ;;
"ru" | "ru-"* ) "ru" | "ru-"* )
short="ru" short="ru"
lang="Russian" lang="Russian"
desc="$lang"
culture="ru-RU" ;; culture="ru-RU" ;;
"sk" | "sk-"* ) "sk" | "sk-"* )
short="sk" short="sk"
lang="Slovak" lang="Slovak"
desc="$lang"
culture="sk-SK" ;; culture="sk-SK" ;;
"sl" | "sl-"* | "si" | "si-"* ) "sl" | "sl-"* | "si" | "si-"* )
short="sl" short="sl"
lang="Slovenian" lang="Slovenian"
desc="$lang"
culture="sl-SI" ;; culture="sl-SI" ;;
"sr" | "sr-"* ) "sr" | "sr-"* )
short="sr" short="sr"
@@ -331,22 +304,18 @@ getLanguage() {
"sv" | "sv-"* | "se" | "se-"* ) "sv" | "sv-"* | "se" | "se-"* )
short="sv" short="sv"
lang="Swedish" lang="Swedish"
desc="$lang"
culture="sv-SE" ;; culture="sv-SE" ;;
"th" | "th-"* ) "th" | "th-"* )
short="th" short="th"
lang="Thai" lang="Thai"
desc="$lang"
culture="th-TH" ;; culture="th-TH" ;;
"tr" | "tr-"* ) "tr" | "tr-"* )
short="tr" short="tr"
lang="Turkish" lang="Turkish"
desc="$lang"
culture="tr-TR" ;; culture="tr-TR" ;;
"ua" | "ua-"* | "uk" | "uk-"* ) "ua" | "ua-"* | "uk" | "uk-"* )
short="uk" short="uk"
lang="Ukrainian" lang="Ukrainian"
desc="$lang"
culture="uk-UA" ;; culture="uk-UA" ;;
"hk" | "zh-hk" | "cn-hk" ) "hk" | "zh-hk" | "cn-hk" )
short="hk" short="hk"
@@ -365,6 +334,8 @@ getLanguage() {
culture="zh-CN" ;; culture="zh-CN" ;;
esac esac
[ -z "$desc" ] && desc="$lang"
case "${ret,,}" in case "${ret,,}" in
"desc" ) echo "$desc" ;; "desc" ) echo "$desc" ;;
"name" ) echo "$lang" ;; "name" ) echo "$lang" ;;
@@ -1577,8 +1548,8 @@ prepareInstall() {
[ -z "$WIDTH" ] && WIDTH="1280" [ -z "$WIDTH" ] && WIDTH="1280"
[ -z "$HEIGHT" ] && HEIGHT="720" [ -z "$HEIGHT" ] && HEIGHT="720"
XHEX=$(printf '%x\n' "$WIDTH") XHEX=$(printf '%08x\n' "$WIDTH")
YHEX=$(printf '%x\n' "$HEIGHT") YHEX=$(printf '%08x\n' "$HEIGHT")
local username="" local username=""
local password="" local password=""
@@ -1697,13 +1668,13 @@ prepareInstall() {
echo "" echo ""
echo "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Video\{23A77BF7-ED96-40EC-AF06-9B1F4867732A}\0000]" echo "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Video\{23A77BF7-ED96-40EC-AF06-9B1F4867732A}\0000]"
echo "\"DefaultSettings.BitsPerPel\"=dword:00000020" echo "\"DefaultSettings.BitsPerPel\"=dword:00000020"
echo "\"DefaultSettings.XResolution\"=dword:00000$XHEX" echo "\"DefaultSettings.XResolution\"=dword:$XHEX"
echo "\"DefaultSettings.YResolution\"=dword:00000$YHEX" echo "\"DefaultSettings.YResolution\"=dword:$YHEX"
echo "" echo ""
echo "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Control\VIDEO\{23A77BF7-ED96-40EC-AF06-9B1F4867732A}\0000]" 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.BitsPerPel\"=dword:00000020"
echo "\"DefaultSettings.XResolution\"=dword:00000$XHEX" echo "\"DefaultSettings.XResolution\"=dword:$XHEX"
echo "\"DefaultSettings.YResolution\"=dword:00000$YHEX" echo "\"DefaultSettings.YResolution\"=dword:$YHEX"
echo "" echo ""
echo "[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce]" 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\\\"\"" echo "\"ScreenSaver\"=\"reg add \\\"HKCU\\\\Control Panel\\\\Desktop\\\" /f /v \\\"SCRNSAVE.EXE\\\" /t REG_SZ /d \\\"off\\\"\""
+26 -12
View File
@@ -29,21 +29,35 @@ cd /run
trap - ERR 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..." info "Booting ${APP}${BOOT_DESC} using QEMU v$version..."
{ qemu-system-x86_64 ${ARGS:+ $ARGS} >"$QEMU_OUT" 2>"$QEMU_LOG"; rc=$?; } || : pipe="$QEMU_DIR/qemu.pipe"
(( rc != 0 )) && error "$(<"$QEMU_LOG")" && exit 15 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 ) & ( sleep 30; boot ) &
tail -fn +0 "$QEMU_LOG" --pid=$$ 2>/dev/null &
cat "$QEMU_TERM" 2> /dev/null | tee "$QEMU_PTY" | \ rc=0
sed -u -e 's/\x1B\[[=0-9;]*[a-z]//gi' \ wait "$pid" || rc=$?
-e 's/\x1B\x63//g' -e 's/\x1B\[[=?]7l//g' \ [ -f "$QEMU_END" ] && exit "$rc"
-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 $! || :
sleep 1 & wait $! sleep 1 & wait $!
[ ! -f "$QEMU_END" ] && finish 0 finish "$rc"
+5 -7
View File
@@ -32,13 +32,11 @@ backup () {
while [ -d "$dir" ] while [ -d "$dir" ]
do do
count=$((count+1)) (( count++ ))
folder="${name}.${count}" folder="${name}.${count}"
dir="$root/$folder" dir="$root/$folder"
done done
rm -rf "$dir"
if ! makeDir "$dir"; then if ! makeDir "$dir"; then
error "Failed to create directory \"$dir\" !" error "Failed to create directory \"$dir\" !"
return 1 return 1
@@ -110,7 +108,7 @@ skipInstall() {
[ ! -s "$iso" ] && return 1 [ ! -s "$iso" ] && return 1
# Check if the ISO was already processed by our script # 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')" magic="$(printf '%s' "$magic" | od -A n -t x1 -v | tr -d ' \n')"
byte="16" && [[ "$MANUAL" == [Yy1]* ]] && byte="17" byte="16" && [[ "$MANUAL" == [Yy1]* ]] && byte="17"
@@ -164,7 +162,7 @@ startInstall() {
fi fi
if ! makeDir "$TMP"; then if ! makeDir "$TMP"; then
error "Failed to create directory \"$TMP\" !" error "Failed to create directory \"$TMP\" !" && exit 50
fi fi
if [ -z "$CUSTOM" ]; then if [ -z "$CUSTOM" ]; then
@@ -224,7 +222,7 @@ finishInstall() {
fi fi
local file="$STORAGE/windows.ver" 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\" !" ! setOwner "$file" && error "Failed to set the owner for \"$file\" !"
if [[ "$iso" == "$STORAGE/"* ]]; then if [[ "$iso" == "$STORAGE/"* ]]; then
@@ -1180,7 +1178,7 @@ buildImage() {
error "Failed to locate file \"$ETFS\" in ISO image!" && return 1 error "Failed to locate file \"$ETFS\" in ISO image!" && return 1
fi fi
size=$(du -h -b --max-depth=0 "$dir" | cut -f1) size=$(du -b --max-depth=0 "$dir" | cut -f1)
size_gb=$(formatBytes "$size") size_gb=$(formatBytes "$size")
space=$(df --output=avail -B 1 "$TMP" | tail -n 1) space=$(df --output=avail -B 1 "$TMP" | tail -n 1)
space_gb=$(formatBytes "$space") space_gb=$(formatBytes "$space")
+15 -27
View File
@@ -63,18 +63,12 @@ download_windows() {
local id="$1" local id="$1"
local lang="$2" local lang="$2"
local desc="$3" local desc="$3"
local sku_id="" local ovw="" rtick="" mdt="" sku_id="" sku_url=""
local sku_url="" local iso_url="" iso_json="" language="" org_id=""
local iso_url="" local instance_id="" vls_url="" ov_url="" ov_data=""
local iso_json="" local session_id="" user_agent="" download_type=""
local language="" local windows_version="" iso_download_link=""
local session_id="" local download_page_html="" product_edition_id=""
local user_agent=""
local download_type=""
local windows_version=""
local iso_download_link=""
local download_page_html=""
local product_edition_id=""
local language_skuid_json="" local language_skuid_json=""
local profile="606624d44113" local profile="606624d44113"
@@ -88,7 +82,6 @@ download_windows() {
esac esac
local url="https://www.microsoft.com/en-us/software-download/windows$windows_version" 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 # 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) 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) # 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_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 if ! [ "$iso_json" ]; then
# This should only happen if there's been some change to how this API works # 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 id="$1"
local lang="$2" local lang="$2"
local desc="$3" local desc="$3"
local filter="" local filter="" culture="" compare="" language=""
local culture="" local user_agent="" enterprise_type="" windows_version=""
local compare=""
local language=""
local user_agent=""
local enterprise_type=""
local windows_version=""
case "${id,,}" in case "${id,,}" in
"win11${PLATFORM,,}-enterprise-eval" ) "win11${PLATFORM,,}-enterprise-eval" )
@@ -273,6 +264,7 @@ download_windows_eval() {
culture=$(getLanguage "$lang" "culture") culture=$(getLanguage "$lang" "culture")
local country="${culture#*-}" local country="${culture#*-}"
local iso_download_link=""
local iso_download_links="" local iso_download_links=""
local iso_download_page_html="" local iso_download_page_html=""
local url="https://www.microsoft.com/en-us/evalcenter/download-$windows_version" local url="https://www.microsoft.com/en-us/evalcenter/download-$windows_version"
@@ -512,12 +504,8 @@ getESD() {
local version="$2" local version="$2"
local lang="$3" local lang="$3"
local desc="$4" local desc="$4"
local file local file result culture
local result local language edition catalog
local culture
local language
local edition
local catalog
file=$(getCatalog "$version" "file") file=$(getCatalog "$version" "file")
catalog=$(getCatalog "$version" "url") catalog=$(getCatalog "$version" "url")
+94 -120
View File
@@ -1,26 +1,28 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -Eeuo pipefail set -Eeuo pipefail
: "${QEMU_TIMEOUT:="110"}" # QEMU Termination timeout : "${SHUTDOWN:="Y"}" # Graceful ACPI shutdown
: "${TIMEOUT:="115"}" # QEMU termination timeout
# Configure QEMU for graceful shutdown # Configure QEMU for graceful shutdown
QEMU_TERM=""
QEMU_PTY="$QEMU_DIR/qemu.pty" QEMU_PTY="$QEMU_DIR/qemu.pty"
QEMU_LOG="$QEMU_DIR/qemu.log"
QEMU_OUT="$QEMU_DIR/qemu.out"
QEMU_END="$QEMU_DIR/qemu.end" QEMU_END="$QEMU_DIR/qemu.end"
rm -f "$QEMU_DIR/qemu.*"
touch "$QEMU_LOG"
_trap() { _trap() {
func="$1" ; shift local func="$1"; shift
for sig ; do local sig
TRAP_PID=$BASHPID
for sig; do
trap "$func $sig" "$sig" trap "$func $sig" "$sig"
done done
} }
app() {
echo "$APP" && return 0
}
boot() { boot() {
[ -f "$QEMU_END" ] && return 0 [ -f "$QEMU_END" ] && return 0
@@ -33,17 +35,14 @@ boot() {
grep -Fq "BOOTMGR is missing" "$QEMU_PTY" && fail="y" grep -Fq "BOOTMGR is missing" "$QEMU_PTY" && fail="y"
fi fi
if [ -z "$fail" ]; then 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 return 0
fi fi
fi fi
fi fi
error "Timeout while waiting for QEMU to boot the machine!" error "Timeout while waiting for QEMU to boot the machine, aborting..."
sKill "$QEMU_PID"
local pid
pid=$(<"$QEMU_PID")
{ kill -15 "$pid" || true; } 2>/dev/null
return 0 return 0
} }
@@ -71,39 +70,29 @@ ready() {
finish() { finish() {
local pid local i=0
local cnt=0 local pid=""
local reason=$1 local reason=$1
local pids=( local pids=( "${SMB_PID:-}" "${NMB_PID:-}" "${DDN_PID:-}" "${TPM_PID:-}" "${WSD_PID:-}" \
"/var/run/tpm.pid" "${WEB_PID:-}" "${PASST_PID:-}" "${DNSMASQ_PID:-}" "${BALLOONING_PID:-}" )
"/var/run/wsdd.pid"
"/var/run/samba/nmbd.pid"
"/var/run/samba/smbd.pid"
)
touch "$QEMU_END" touch "$QEMU_END"
if [ -s "$QEMU_PID" ]; then if [ -s "$QEMU_PID" ]; then
if read -r pid <"$QEMU_PID"; then
pid=$(<"$QEMU_PID") if [ -n "$pid" ] && isAlive "$pid"; then
echo && error "Forcefully terminating Windows, reason: $reason..." local display="$reason"
{ kill -15 "$pid" || true; } 2>/dev/null case "$reason" in
129 ) display="SIGHUP" ;;
while isAlive "$pid"; do 130 ) display="SIGINT" ;;
131 ) display="SIGQUIT" ;;
sleep 1 134 ) display="SIGABRT" ;;
cnt=$((cnt+1)) 143 ) display="SIGTERM" ;;
esac
# Workaround for zombie pid error "Forcefully terminating $(app), reason: $display..."
[ ! -s "$QEMU_PID" ] && break { disown "$pid" || :; kill -9 -- "$pid" || :; } 2>/dev/null
if [ "$cnt" -eq 5 ]; then
echo && error "QEMU did not terminate itself, forcefully killing process..."
{ kill -9 "$pid" || true; } 2>/dev/null
fi fi
fi
done
fi fi
if [ ! -f "$STORAGE/windows.boot" ] && [ -f "$BOOT" ]; then if [ ! -f "$STORAGE/windows.boot" ] && [ -f "$BOOT" ]; then
@@ -118,121 +107,106 @@ finish() {
fi fi
fi fi
for pid in "${pids[@]}"; do mKill "${pids[@]}"
if [[ -s "$pid" ]]; then
pKill "$(cat "$pid")"
fi
rm -f "$pid"
done
closeNetwork closeNetwork
sleep 0.5 if ! waitPidFile "$QEMU_PID" 10; then
echo " Shutdown completed!" warn "Timed out while waiting for $(app) to exit!"
fi
(( reason != 1 )) && echo && echo " Shutdown completed!"
exit "$reason" 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 case "$sig" in
msg=$(<"$QEMU_OUT") SIGHUP) code=129 ;;
SIGINT) code=130 ;;
if [ -n "$msg" ]; then SIGQUIT) code=131 ;;
SIGABRT) code=134 ;;
if [[ "${msg,,}" != "char"* || "$msg" != *"serial0)" ]]; then SIGTERM) code=143 ;;
echo "$msg" esac
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
if [ -f "$QEMU_END" ]; then if [ -f "$QEMU_END" ]; then
info "Received $1 while already shutting down..." echo && info "Received $1 signal while already shutting down..."
return return
fi fi
set +e
touch "$QEMU_END" touch "$QEMU_END"
info "Received $1, sending ACPI shutdown signal..." echo && info "Received $1 signal, sending ACPI shutdown signal..."
if [ ! -s "$QEMU_PID" ]; then if [ ! -s "$QEMU_PID" ] || ! read -r pid <"$QEMU_PID"; then
error "QEMU PID file does not exist?" warn "QEMU PID file ($QEMU_PID) does not exist?"
finish "$code" && return "$code" finish "$code"
fi fi
local pid="" if [ -z "$pid" ] || ! isAlive "$pid"; then
pid=$(<"$QEMU_PID") warn "QEMU process with PID $pid does not exist?"
finish "$code"
if ! isAlive "$pid"; then
error "QEMU process does not exist?"
finish "$code" && return "$code"
fi fi
if ! ready; then if ! ready; then
info "Cannot send ACPI signal during Windows setup, aborting..." info "Cannot send ACPI signal during $(app) setup, aborting..."
finish "$code" && return "$code" sKill "$QEMU_PID"
if ! waitPidFile "$QEMU_PID" 5; then
warn "Timed out while waiting for $(app) to exit!"
fi
finish "$code"
fi fi
# Send ACPI shutdown signal local cnt=0 abort=0 factor=3 offset=3 min max name
echo 'system_powerdown' | nc -q 1 -w 1 localhost "$MON_PORT" > /dev/null
local cnt=0 [[ "$TIMEOUT" =~ ^[0-9]+$ ]] || TIMEOUT=115
while [ "$cnt" -lt "$QEMU_TIMEOUT" ]; do [ "$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 while [ "$cnt" -le "$max" ]; do
cnt=$((cnt+1))
sleep 1 &
local slp=$!
! isAlive "$pid" && break ! isAlive "$pid" && break
# Workaround for zombie pid # Workaround for zombie pid
[ ! -s "$QEMU_PID" ] && break [ ! -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 # 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 done
if [ "$cnt" -ge "$QEMU_TIMEOUT" ]; then finish "$code"
error "Shutdown timeout reached, aborting..."
fi
finish "$code" && return "$code"
} }
SERIAL="pty" [[ "$SHUTDOWN" != [Yy1]* ]] && return 0
MONITOR="telnet:localhost:$MON_PORT,server,nowait,nodelay -daemonize -D $QEMU_LOG" [ -n "${QEMU_TIMEOUT:-}" ] && TIMEOUT="$QEMU_TIMEOUT"
_trap _graceful_shutdown SIGTERM SIGHUP SIGINT SIGABRT SIGQUIT _trap graceful_shutdown SIGTERM SIGHUP SIGABRT SIGQUIT
return 0 return 0
+11 -15
View File
@@ -2,15 +2,16 @@
set -Eeuo pipefail set -Eeuo pipefail
: "${SAMBA:="Y"}" # Enable Samba : "${SAMBA:="Y"}" # Enable Samba
: "${SAMBA_LEVEL:="1"}" # Logging level
: "${SAMBA_DEBUG:="N"}" # Disable debug : "${SAMBA_DEBUG:="N"}" # Disable debug
tmp="/tmp/smb" tmp="/tmp/smb"
rm -rf "$tmp" rm -rf "$tmp"
rm -f /var/run/wsdd.pid DDN_PID="/var/run/wsdd.pid"
rm -f /var/run/samba/nmbd.pid NMB_PID="/var/run/samba/nmbd.pid"
rm -f /var/run/samba/smbd.pid SMB_PID="/var/run/samba/smbd.pid"
rm -f "$SMB_PID" "$NMB_PID" "$DDN_PID"
[[ "$SAMBA" == [Nn]* ]] && return 0 [[ "$SAMBA" == [Nn]* ]] && return 0
[[ "$NETWORK" == [Nn]* ]] && return 0 [[ "$NETWORK" == [Nn]* ]] && return 0
@@ -78,7 +79,7 @@ addShare() {
if [[ "$dir" == "$tmp" ]]; then if [[ "$dir" == "$tmp" ]]; then
{ echo "--------------------------------------------------------" { echo "--------------------------------------------------------"
echo " $APP for $ENGINE v$(</run/version)..." echo " $APP for $ENGINE v$(</etc/version)..."
echo " For support visit $SUPPORT" echo " For support visit $SUPPORT"
echo "--------------------------------------------------------" echo "--------------------------------------------------------"
echo "" echo ""
@@ -151,18 +152,14 @@ share="/shared"
if [ -d "/shared2" ]; then if [ -d "/shared2" ]; then
addShare "/shared2" "/shared2" "Data2" "Shared" "$SAMBA_CONFIG" || : addShare "/shared2" "/shared2" "Data2" "Shared" "$SAMBA_CONFIG" || :
else elif [ -d "/data2" ]; then
if [ -d "/data2" ]; then addShare "/data2" "/shared2" "Data2" "Shared" "$SAMBA_CONFIG" || :
addShare "/data2" "/shared2" "Data2" "Shared" "$SAMBA_CONFIG" || :
fi
fi fi
if [ -d "/shared3" ]; then if [ -d "/shared3" ]; then
addShare "/shared3" "/shared3" "Data3" "Shared" "$SAMBA_CONFIG" || : addShare "/shared3" "/shared3" "Data3" "Shared" "$SAMBA_CONFIG" || :
else elif [ -d "/data3" ]; then
if [ -d "/data3" ]; then addShare "/data3" "/shared3" "Data3" "Shared" "$SAMBA_CONFIG" || :
addShare "/data3" "/shared3" "Data3" "Shared" "$SAMBA_CONFIG" || :
fi
fi fi
# Create directories if missing # Create directories if missing
@@ -211,10 +208,9 @@ else
# Enable Web Service Discovery on Vista and up # Enable Web Service Discovery on Vista and up
[[ "$DEBUG" == [Yy1]* ]] && echo "Starting wsddn daemon..." [[ "$DEBUG" == [Yy1]* ]] && echo "Starting wsddn daemon..."
rm -f /var/log/wsddn.log 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" SAMBA_DEBUG="Y"
error "Failed to start wsddn daemon!" error "Failed to start wsddn daemon!"
fi fi