Browse Source

feat: Improved installation (#486)

Kroese 1 năm trước cách đây
mục cha
commit
eb0b0fe80c
3 tập tin đã thay đổi với 77 bổ sung77 xóa
  1. 1 1
      Dockerfile
  2. 16 8
      readme.md
  3. 60 68
      src/install.sh

+ 1 - 1
Dockerfile

@@ -1,5 +1,5 @@
 FROM scratch
-COPY --from=qemux/qemu-docker:5.02 / /
+COPY --from=qemux/qemu-docker:5.03 / /
 
 ARG DEBCONF_NOWARNINGS "yes"
 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?
 
-  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
   environment:
     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
   volumes:
     - /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?
 
@@ -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?
 
-  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
   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 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.
 
-  - 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'.
 
   - 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!
  

+ 60 - 68
src/install.sh

@@ -12,32 +12,58 @@ hasDisk() {
   [ -b "/disk1" ] && return 0
   [ -b "/dev/disk1" ] && 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
 }
 
 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
 
-  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() {
 
   html "Starting $APP..."
 
-  if [ -n "$CUSTOM" ]; then
-
-    ISO="$CUSTOM"
-
-  else
+  if [ -z "$CUSTOM" ]; then
 
     local file="${VERSION/\//}.iso"
 
@@ -49,59 +75,26 @@ startInstall() {
 
     fi
 
-    ISO="$STORAGE/$file"
+    BOOT="$STORAGE/$file"
 
-    ! migrateFiles "$ISO" "$VERSION" && error "Migration failed!" && exit 57
+    ! migrateFiles "$BOOT" "$VERSION" && error "Migration failed!" && exit 57
 
   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"
   mkdir -p "$TMP"
 
   if [ -z "$CUSTOM" ]; then
 
-    BOOT="$ISO"
-    ISO=$(basename "$ISO")
+    ISO=$(basename "$BOOT")
     ISO="$TMP/$ISO"
 
     if [ -f "$BOOT" ] && [ -s "$BOOT" ]; then
       mv -f "$BOOT" "$ISO"
     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
 
   rm -f "$BOOT"
@@ -112,26 +105,34 @@ finishInstall() {
 
   local iso="$1"
   local aborted="$2"
+  local base byte
 
   if [ ! -s "$iso" ] || [ ! -f "$iso" ]; then
     error "Failed to find ISO file: $iso" && return 1
   fi
 
-  if [ -w "$iso" ] && [[ "$aborted" != [Yy1]* ]]; then
+  if [[ "$aborted" != [Yy1]* ]]; then
     # 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
-      error "Failed to set magic byte in ISO file: $iso" && return 1
+      warn "failed to set magic byte in ISO file: $iso"
     fi
   fi
 
   rm -f "$STORAGE/windows.old"
+  rm -f "$STORAGE/windows.base"
   rm -f "$STORAGE/windows.boot"
   rm -f "$STORAGE/windows.mode"
 
   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 [[ "${BOOT_MODE,,}" == "windows_legacy" ]]; then
       echo "$BOOT_MODE" > "$STORAGE/windows.mode"
@@ -180,7 +181,6 @@ detectCustom() {
   local size base
 
   CUSTOM=""
-  ORIGINAL=""
 
   if [[ "${VERSION,,}" != "http"* ]]; then
     base="${VERSION/\/storage\//}"
@@ -202,15 +202,9 @@ detectCustom() {
   size="$(stat -c%s "$file")"
   [ -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
 }
@@ -1045,13 +1039,11 @@ bootWindows() {
 
   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
 
-  BOOT="$ISO"
-
   [[ "${PLATFORM,,}" == "arm64" ]] && VGA="virtio-gpu"
 
   if [ -s "$STORAGE/windows.mode" ] && [ -f "$STORAGE/windows.mode" ]; then