From 5137d513fc9fe26bf8a6ab4ee08c89754f292646 Mon Sep 17 00:00:00 2001 From: Kroese Date: Fri, 19 Jan 2024 01:25:39 +0100 Subject: [PATCH] feat: Support more image layouts (#54) --- readme.md | 20 +++--- src/entry.sh | 3 +- src/install.sh | 174 +++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 166 insertions(+), 31 deletions(-) diff --git a/readme.md b/readme.md index 96c6d7a..da456c8 100644 --- a/readme.md +++ b/readme.md @@ -73,13 +73,15 @@ docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN dockurr/w Select from the values below: - - ```win11``` (Windows 11) - - ```win10``` (Windows 10) - - ```win81``` (Windows 8.1) - - ```win22``` (Windows Server 2022) - - ```win19``` (Windows Server 2019) - - ```win16``` (Windows Server 2016) - + - ```win11``` = Windows 11 + - ```win10``` = Windows 10 + - ```win81``` = Windows 8.1 + - ```win22``` = Windows Server 2022 + - ```win19``` = Windows Server 2019 + - ```win16``` = Windows Server 2016 + - ```tiny11``` = Tiny11 (Slow download) + - ```tiny10``` = Tiny10 (Slow download) + * ### How do I increase the amount of CPU or RAM? By default, 2 CPU cores and 4 GB of RAM are allocated to the container, as those are the minimum requirements of Windows 11. @@ -143,14 +145,14 @@ docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN dockurr/w * ### How do I install an unsupported version? - You can specify an URL in the `VERSION` environment variable, in order to download a custom ISO file: + You can specify an URL in the `VERSION` environment variable, in order to download a custom ISO image: ```yaml environment: VERSION: "https://example.com/win.iso" ``` - During the installation you will need to add some drivers as described in [manual installation](https://github.com/dockur/windows/tree/master?tab=readme-ov-file#how-do-i-perform-a-manual-installation) above. + During the installation you may need to add some drivers as described in [manual installation](https://github.com/dockur/windows/tree/master?tab=readme-ov-file#how-do-i-perform-a-manual-installation) above. * ### How do I pass-through a disk? diff --git a/src/entry.sh b/src/entry.sh index 9cf43cf..aa6f1ec 100644 --- a/src/entry.sh +++ b/src/entry.sh @@ -3,6 +3,7 @@ set -Eeuo pipefail echo "❯ Starting Windows for Docker v$( /dev/null +echo + +XML="" +FB="falling back to manual installation!" + +if [ -z "$MANUAL" ]; then + + MANUAL="N" + + if [[ "$EXTERNAL" == [Yy1]* ]]; then + [[ "${BASE,,}" == "tiny10"* ]] && MANUAL="Y" + fi + +fi if [[ "$MANUAL" != [Yy1]* ]]; then if [[ "$EXTERNAL" != [Yy1]* ]]; then - if [ -f "/run/assets/$VERSION.xml" ]; then - wimlib-imagex update "$DIR/sources/boot.wim" 2 \ - --command "add /run/assets/$VERSION.xml /autounattend.xml" + XML="$VERSION.xml" + else + + info "Detecting Windows version from ISO image..." + + LOC="$DIR/sources/install.wim" + [ ! -f "$LOC" ] && LOC="$DIR/sources/install.esd" + + if [ -f "$LOC" ]; then + + DETECTED="" + TAG="DISPLAYNAME" + RESULT=$(wimlib-imagex info -xml "$LOC" | tr -d '\000') + NAME=$(sed -n "/$TAG/{s/.*<$TAG>\(.*\)<\/$TAG>.*/\1/;p}" <<< "$RESULT") + + if [ -z "$NAME" ]; then + TAG="PRODUCTNAME" + NAME=$(sed -n "/$TAG/{s/.*<$TAG>\(.*\)<\/$TAG>.*/\1/;p}" <<< "$RESULT") + fi + + [[ "${NAME,,}" == "windows 11"* ]] && DETECTED="win11x64" + [[ "${NAME,,}" == "windows 10"* ]] && DETECTED="win10x64" + [[ "${NAME,,}" == "windows 8"* ]] && DETECTED="win81x64" + [[ "${NAME,,}" == *"server 2022"* ]] && DETECTED="win2022-eval" + [[ "${NAME,,}" == *"server 2019"* ]] && DETECTED="win2019-eval" + [[ "${NAME,,}" == *"server 2016"* ]] && DETECTED="win2016-eval" + + if [ -n "$DETECTED" ]; then + + XML="$DETECTED.xml" + echo "Detected image of type '$DETECTED', will apply autounattend.xml file." + + else + if [ -z "$NAME" ]; then + error "Warning: failed to detect Windows version from image, $FB" + else + if [[ "${NAME,,}" == "windows 7" ]]; then + error "Warning: detected Windows 7 image, $FB" + else + error "Warning: failed to detect Windows version from string '$NAME', $FB" + fi + fi + fi + else + error "Warning: failed to locate 'install.wim' or 'install.esd' in ISO image, $FB" fi + echo fi fi -LABEL="${BASE%.*}" -LABEL="${LABEL::32}" +ASSET="/run/assets/$XML" -ISO="$TMP/$LABEL.tmp" -rm -f "$ISO" +if [ -f "$ASSET" ]; then -genisoimage -b boot/etfsboot.com -no-emul-boot -c BOOT.CAT -iso-level 4 -J -l -D -N -joliet-long -relaxed-filenames \ - -v -V "$LABEL" -udf -boot-info-table -eltorito-alt-boot -eltorito-boot efi/microsoft/boot/efisys_noprompt.bin \ - -no-emul-boot -o "$ISO" -allow-limited-size "$DIR" + LOC="$DIR/sources/boot.wim" + [ ! -f "$LOC" ] && LOC="$DIR/sources/boot.esd" + + if [ -f "$LOC" ]; then + + info "Adding XML file for automatic installation..." + + RESULT=$(wimlib-imagex info -xml "$LOC" | tr -d '\000') + + if [[ "${RESULT^^}" == *""* ]]; then + INDEX="2" + else + INDEX="1" + fi + + wimlib-imagex update "$LOC" "$INDEX" --command "add $ASSET /autounattend.xml" > /dev/null + + else + error "Warning: failed to locate 'boot.wim' or 'boot.esd' in ISO image, $FB" + fi + + LOC="$DIR/autounattend.xml" + [ -f "$LOC" ] && mv -f "$ASSET" "$LOC" + LOC="$DIR/Autounattend.xml" + [ -f "$LOC" ] && mv -f "$ASSET" "$LOC" + LOC="$DIR/AutoUnattend.xml" + [ -f "$LOC" ] && mv -f "$ASSET" "$LOC" + LOC="$DIR/autounattend.XML" + [ -f "$LOC" ] && mv -f "$ASSET" "$LOC" + LOC="$DIR/Autounattend.XML" + [ -f "$LOC" ] && mv -f "$ASSET" "$LOC" + LOC="$DIR/AutoUnattend.XML" + [ -f "$LOC" ] && mv -f "$ASSET" "$LOC" + LOC="$DIR/AUTOUNATTEND.xml" + [ -f "$LOC" ] && mv -f "$ASSET" "$LOC" + LOC="$DIR/AUTOUNATTEND.XML" + [ -f "$LOC" ] && mv -f "$ASSET" "$LOC" + + echo + +else + [ -n "$XML" ] && error "Warning: XML file '$XML' does not exist, $FB" && echo +fi + +info "Generating new ISO image for installation..." + +ETFS="boot/etfsboot.com" +EFISYS="efi/microsoft/boot/efisys_noprompt.bin" + +if [ -f "$DIR/$ETFS" ]; then + if [ -f "$DIR/$EFISYS" ]; then + + CAT="BOOT.CAT" + LABEL="${BASE%.*}" + LABEL="${LABEL::32}" + ISO="$TMP/$LABEL.tmp" + rm -f "$ISO" + + genisoimage -b "$ETFS" -no-emul-boot -c "$CAT" -iso-level 4 -J -l -D -N -joliet-long -relaxed-filenames -quiet -V "$LABEL" -udf \ + -boot-info-table -eltorito-alt-boot -eltorito-boot "$EFISYS" -no-emul-boot -o "$ISO" -allow-limited-size "$DIR" + + else + error "Failed to locate file 'efisys_noprompt.bin' in ISO image, $FB" + fi +else + error "Failed to locate file 'etfsboot.com' in ISO image, $FB" +fi mv "$ISO" "$STORAGE/$BASE" - rm -rf "$TMP" +echo return 0