Unverified Commit eb0b0fe8 authored by Kroese's avatar Kroese Committed by GitHub
Browse files

feat: Improved installation (#486)

parent 47d2d229
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
  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

  [ -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