浏览代码

feat: Improved installation (#486)

Kroese 1 年之前
父节点
当前提交
eb0b0fe80c
共有 3 个文件被更改,包括 77 次插入77 次删除
  1. 1 1
      Dockerfile
  2. 16 8
      readme.md
  3. 60 68
      src/install.sh

+ 1 - 1
Dockerfile

@@ -1,5 +1,5 @@
 FROM scratch
 FROM scratch
-COPY --from=qemux/qemu-docker:5.02 / /
+COPY --from=qemux/qemu-docker:5.03 / /
 
 
 ARG DEBCONF_NOWARNINGS "yes"
 ARG DEBCONF_NOWARNINGS "yes"
 ARG DEBIAN_FRONTEND "noninteractive"
 ARG DEBIAN_FRONTEND "noninteractive"

+ 16 - 8
readme.md

@@ -138,21 +138,21 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
 
 
 * ### How do I install a custom image?
 * ### How do I install a custom image?
 
 
-  In order to download any ISO image that is not part of the list above, start a fresh container with the URL of that ISO specified in the `VERSION` environment variable, for example:
+  In order to download an unsupported ISO image that is not selectable from the list above, specify the URL of that ISO in the `VERSION` environment variable, for example:
   
   
   ```yaml
   ```yaml
   environment:
   environment:
     VERSION: "https://example.com/win.iso"
     VERSION: "https://example.com/win.iso"
   ```
   ```
 
 
-  Alternatively, you can also use a local file directly, and skip the download altogether, by binding it in your compose file in this way:
+  Alternatively, you can also skip the download and use a local file instead, by binding it in your compose file in this way:
   
   
   ```yaml
   ```yaml
   volumes:
   volumes:
     - /home/user/example.iso:/custom.iso
     - /home/user/example.iso:/custom.iso
   ```
   ```
 
 
-  Replace the example path `/home/user/example.iso` with the filename of your desired ISO file. The value of `VERSION` will be ignored in this case.
+  Replace the example path `/home/user/example.iso` with the filename of your desired ISO file, the value of `VERSION` will be ignored in this case.
 
 
 * ### How do I customize the installation?
 * ### How do I customize the installation?
 
 
@@ -180,9 +180,9 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
 
 
 * ### How do I perform a manual installation?
 * ### How do I perform a manual installation?
 
 
-  It's best to use the automatic installation, as it optimizes various settings for use with this container. These tweaks will give you maximum performance and prevent common issues.
+  It's best to use the automatic installation, as it optimizes various settings to give you maximum performance and prevent common issues.
 
 
-  However, if you insist on performing the installation manually, start a fresh container with the following environment variable:
+  However, if you insist on performing the installation manually, add the following environment variable to your compose file:
 
 
   ```yaml
   ```yaml
   environment:
   environment:
@@ -193,17 +193,25 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
 
 
   - Start the container and connect to [port 8006](http://localhost:8006) of the container in your web browser. After the download is finished, you will see the Windows installation screen.
   - Start the container and connect to [port 8006](http://localhost:8006) of the container in your web browser. After the download is finished, you will see the Windows installation screen.
 
 
-  - Start the installation by clicking `Install now`. On the next screen, press 'OK' when prompted to `Load driver` and select the `VirtIO SCSI` driver from the list that matches your Windows version. So for Windows 11, select `D:\amd64\w11\vioscsi.inf` and click 'Next'.
+  - Start the installation by clicking `Install now`. On the next screen, press 'OK' when prompted to `Load driver`.
+
+  -  Select the `VirtIO SCSI` driver from the list that matches your Windows version. So for Windows 11, select `D:\amd64\w11\vioscsi.inf` and click 'Next'.
 
 
   - Accept the license agreement and select your preferred Windows edition, like Home or Pro.
   - Accept the license agreement and select your preferred Windows edition, like Home or Pro.
 
 
-  - Choose `Custom: Install Windows only (advanced)`, and click `Load driver` on the next screen. Select 'Browse' and navigate to the `D:\NetKVM\w11\amd64` folder, and click 'OK'. Select the `VirtIO Ethernet Adapter` from the list and click 'Next'.
+  - Choose `Custom: Install Windows only (advanced)`, and click `Load driver` on the next screen.
+
+  - Select 'Browse' and navigate to the `D:\NetKVM\w11\amd64` folder, and click 'OK'.
+
+  - Select the `VirtIO Ethernet Adapter` from the list and click 'Next'.
 
 
   - Select `Drive 0` and click 'Next'.
   - Select `Drive 0` and click 'Next'.
 
 
   - Wait until Windows finishes copying files and completes the installation.
   - Wait until Windows finishes copying files and completes the installation.
 
 
-  - Once you see the desktop, open File Explorer and navigate to the CD-ROM drive (E:). Double-click on `virtio-win-gt-x64.msi` and proceed to install the VirtIO drivers.
+  - Once you see the desktop, open File Explorer and navigate to the CD-ROM drive (`E:\`).
+
+  - Double-click on `virtio-win-gt-x64.msi` and proceed to install the VirtIO drivers.
 
 
   Enjoy your brand new machine, and don't forget to star this repo!
   Enjoy your brand new machine, and don't forget to star this repo!
  
  

+ 60 - 68
src/install.sh

@@ -12,32 +12,58 @@ hasDisk() {
   [ -b "/disk1" ] && return 0
   [ -b "/disk1" ] && return 0
   [ -b "/dev/disk1" ] && return 0
   [ -b "/dev/disk1" ] && return 0
   [ -b "${DEVICE:-}" ] && return 0
   [ -b "${DEVICE:-}" ] && return 0
-
-  if [ -s "$STORAGE/data.img" ] || [ -s "$STORAGE/data.qcow2" ]; then
-    return 0
-  fi
+  [ -s "$STORAGE/data.img" ]  && return 0
+  [ -s "$STORAGE/data.qcow2" ] && return 0
 
 
   return 1
   return 1
 }
 }
 
 
 skipInstall() {
 skipInstall() {
 
 
-  if hasDisk && [ -f "$STORAGE/windows.boot" ]; then
-    return 0
+  local iso="$1"
+  local magic byte
+  local boot="$STORAGE/windows.boot"
+  local previous="$STORAGE/windows.base"
+
+  if [ -f "$previous" ]; then
+    previous=$(<"$previous")
+    if [ -n "$previous" ]; then
+      previous="$STORAGE/$previous"
+      if [[ "${previous,,}" != "${iso,,}" ]]; then
+        if [ -f "$boot" ] && hasDisk; then
+          info "Detected that the version was changed, but ignoring this because Windows is already installed."
+          info "Please start with an empty /storage folder, if you want to install a different version of Windows."
+          return 0
+        fi
+        [ -f "$previous" ] && rm -f "$previous"
+        return 1
+      fi
+    fi
   fi
   fi
 
 
-  return 1
+  [ -f "$boot" ] && hasDisk && return 0
+
+  [ ! -f "$iso" ] && return 1
+  [ ! -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="$(printf '%s' "$magic" | od -A n -t x1 -v | tr -d ' \n')"
+  byte="16" && [[ "$MANUAL" == [Yy1]* ]] && byte="17"
+
+  if [[ "$magic" != "$byte" ]]; then
+    info "The ISO will be processed again because the configuration was changed..."
+    return 1
+  fi
+
+  return 0
 }
 }
 
 
 startInstall() {
 startInstall() {
 
 
   html "Starting $APP..."
   html "Starting $APP..."
 
 
-  if [ -n "$CUSTOM" ]; then
-
-    ISO="$CUSTOM"
-
-  else
+  if [ -z "$CUSTOM" ]; then
 
 
     local file="${VERSION/\//}.iso"
     local file="${VERSION/\//}.iso"
 
 
@@ -49,59 +75,26 @@ startInstall() {
 
 
     fi
     fi
 
 
-    ISO="$STORAGE/$file"
+    BOOT="$STORAGE/$file"
 
 
-    ! migrateFiles "$ISO" "$VERSION" && error "Migration failed!" && exit 57
+    ! migrateFiles "$BOOT" "$VERSION" && error "Migration failed!" && exit 57
 
 
   fi
   fi
 
 
-  skipInstall && return 1
-
-  if [ -f "$ISO" ] && [ -s "$ISO" ]; then
-
-    local magic
-    local auto="16"
-    local manual="17"
-    local byte="$auto"
-    [[ "$MANUAL" == [Yy1]* ]] && byte="$manual"
-
-    # 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="$(printf '%s' "$magic" | od -A n -t x1 -v | tr -d ' \n')"
-
-    if [[ "$magic" == "$byte" ]]; then
-      if [ -z "$CUSTOM" ] || [ -n "$ORIGINAL" ]; then
-        return 1
-      fi
-    fi
-
-  fi
+  skipInstall "$BOOT" && return 1
 
 
   rm -rf "$TMP"
   rm -rf "$TMP"
   mkdir -p "$TMP"
   mkdir -p "$TMP"
 
 
   if [ -z "$CUSTOM" ]; then
   if [ -z "$CUSTOM" ]; then
 
 
-    BOOT="$ISO"
-    ISO=$(basename "$ISO")
+    ISO=$(basename "$BOOT")
     ISO="$TMP/$ISO"
     ISO="$TMP/$ISO"
 
 
     if [ -f "$BOOT" ] && [ -s "$BOOT" ]; then
     if [ -f "$BOOT" ] && [ -s "$BOOT" ]; then
       mv -f "$BOOT" "$ISO"
       mv -f "$BOOT" "$ISO"
     fi
     fi
 
 
-  else
-
-    if [ -n "$ORIGINAL" ]; then
-      rm -f "$ISO"
-      ISO="$ORIGINAL"
-      CUSTOM="$ISO"
-    fi
-
-    local size
-    size="$(stat -c%s "$ISO")"
-    BOOT="$STORAGE/windows.$size.iso"
-
   fi
   fi
 
 
   rm -f "$BOOT"
   rm -f "$BOOT"
@@ -112,26 +105,34 @@ finishInstall() {
 
 
   local iso="$1"
   local iso="$1"
   local aborted="$2"
   local aborted="$2"
+  local base byte
 
 
   if [ ! -s "$iso" ] || [ ! -f "$iso" ]; then
   if [ ! -s "$iso" ] || [ ! -f "$iso" ]; then
     error "Failed to find ISO file: $iso" && return 1
     error "Failed to find ISO file: $iso" && return 1
   fi
   fi
 
 
-  if [ -w "$iso" ] && [[ "$aborted" != [Yy1]* ]]; then
+  if [[ "$aborted" != [Yy1]* ]]; then
     # Mark ISO as prepared via magic byte
     # Mark ISO as prepared via magic byte
-    local byte="16"
-    [[ "$MANUAL" == [Yy1]* ]] && byte="17"
+    byte="16" && [[ "$MANUAL" == [Yy1]* ]] && byte="17"
     if ! printf '%b' "\x$byte" | dd of="$iso" bs=1 seek=0 count=1 conv=notrunc status=none; then
     if ! printf '%b' "\x$byte" | dd of="$iso" bs=1 seek=0 count=1 conv=notrunc status=none; then
-      error "Failed to set magic byte in ISO file: $iso" && return 1
+      warn "failed to set magic byte in ISO file: $iso"
     fi
     fi
   fi
   fi
 
 
   rm -f "$STORAGE/windows.old"
   rm -f "$STORAGE/windows.old"
+  rm -f "$STORAGE/windows.base"
   rm -f "$STORAGE/windows.boot"
   rm -f "$STORAGE/windows.boot"
   rm -f "$STORAGE/windows.mode"
   rm -f "$STORAGE/windows.mode"
 
 
   cp -f /run/version "$STORAGE/windows.ver"
   cp -f /run/version "$STORAGE/windows.ver"
 
 
+  if [[ "$iso" == "$STORAGE/"* ]]; then
+    if [[ "$aborted" != [Yy1]* ]] || [ -z "$CUSTOM" ]; then
+      base=$(basename "$iso")
+      echo "$base" > "$STORAGE/windows.base"
+    fi
+  fi
+
   if [[ "${PLATFORM,,}" == "x64" ]]; then
   if [[ "${PLATFORM,,}" == "x64" ]]; then
     if [[ "${BOOT_MODE,,}" == "windows_legacy" ]]; then
     if [[ "${BOOT_MODE,,}" == "windows_legacy" ]]; then
       echo "$BOOT_MODE" > "$STORAGE/windows.mode"
       echo "$BOOT_MODE" > "$STORAGE/windows.mode"
@@ -180,7 +181,6 @@ detectCustom() {
   local size base
   local size base
 
 
   CUSTOM=""
   CUSTOM=""
-  ORIGINAL=""
 
 
   if [[ "${VERSION,,}" != "http"* ]]; then
   if [[ "${VERSION,,}" != "http"* ]]; then
     base="${VERSION/\/storage\//}"
     base="${VERSION/\/storage\//}"
@@ -202,15 +202,9 @@ detectCustom() {
   size="$(stat -c%s "$file")"
   size="$(stat -c%s "$file")"
   [ -z "$size" ] || [[ "$size" == "0" ]] && return 0
   [ -z "$size" ] || [[ "$size" == "0" ]] && return 0
 
 
-  base="$STORAGE/windows.$size.iso"
-
-  if [ -f "$base" ] && [ -s "$base" ]; then
-    CUSTOM="$base"
-    ORIGINAL="$file"
-  else
-    rm -f "$base"
-    CUSTOM="$file"
-  fi
+  ISO="$file"
+  CUSTOM="$ISO"
+  BOOT="$STORAGE/windows.$size.iso"
 
 
   return 0
   return 0
 }
 }
@@ -1045,13 +1039,11 @@ bootWindows() {
 
 
   rm -rf "$TMP"
   rm -rf "$TMP"
 
 
-  if [ ! -f "$ISO" ] || [ ! -s "$ISO" ]; then
-    ISO="/custom.iso"
-    [ ! -f "$ISO" ] && ISO="${STORAGE}$ISO"
+  if [ ! -f "$BOOT" ] || [ ! -s "$BOOT" ]; then
+    BOOT="/custom.iso"
+    [ ! -f "$BOOT" ] && BOOT="${STORAGE}$BOOT"
   fi
   fi
 
 
-  BOOT="$ISO"
-
   [[ "${PLATFORM,,}" == "arm64" ]] && VGA="virtio-gpu"
   [[ "${PLATFORM,,}" == "arm64" ]] && VGA="virtio-gpu"
 
 
   if [ -s "$STORAGE/windows.mode" ] && [ -f "$STORAGE/windows.mode" ]; then
   if [ -s "$STORAGE/windows.mode" ] && [ -f "$STORAGE/windows.mode" ]; then