feat: Improved installation (#486)
This commit is contained in:
parent
47d2d2294c
commit
eb0b0fe80c
@ -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"
|
||||||
|
24
readme.md
24
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!
|
||||||
|
|
||||||
|
126
src/install.sh
126
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
|
||||||
|
[ -s "$STORAGE/data.img" ] && return 0
|
||||||
if [ -s "$STORAGE/data.img" ] || [ -s "$STORAGE/data.qcow2" ]; then
|
[ -s "$STORAGE/data.qcow2" ] && return 0
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
skipInstall() {
|
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
|
return 0
|
||||||
fi
|
fi
|
||||||
|
[ -f "$previous" ] && rm -f "$previous"
|
||||||
return 1
|
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() {
|
startInstall() {
|
||||||
|
|
||||||
html "Starting $APP..."
|
html "Starting $APP..."
|
||||||
|
|
||||||
if [ -n "$CUSTOM" ]; then
|
if [ -z "$CUSTOM" ]; then
|
||||||
|
|
||||||
ISO="$CUSTOM"
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
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
|
skipInstall "$BOOT" && 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
|
|
||||||
|
|
||||||
rm -rf "$TMP"
|
rm -rf "$TMP"
|
||||||
mkdir -p "$TMP"
|
mkdir -p "$TMP"
|
||||||
|
|
||||||
if [ -z "$CUSTOM" ]; then
|
if [ -z "$CUSTOM" ]; then
|
||||||
|
|
||||||
BOOT="$ISO"
|
ISO=$(basename "$BOOT")
|
||||||
ISO=$(basename "$ISO")
|
|
||||||
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"
|
byte="16" && [[ "$MANUAL" == [Yy1]* ]] && byte="17"
|
||||||
[[ "$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"
|
ISO="$file"
|
||||||
|
CUSTOM="$ISO"
|
||||||
if [ -f "$base" ] && [ -s "$base" ]; then
|
BOOT="$STORAGE/windows.$size.iso"
|
||||||
CUSTOM="$base"
|
|
||||||
ORIGINAL="$file"
|
|
||||||
else
|
|
||||||
rm -f "$base"
|
|
||||||
CUSTOM="$file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@ -1045,13 +1039,11 @@ bootWindows() {
|
|||||||
|
|
||||||
rm -rf "$TMP"
|
rm -rf "$TMP"
|
||||||
|
|
||||||
if [ ! -f "$ISO" ] || [ ! -s "$ISO" ]; then
|
if [ ! -f "$BOOT" ] || [ ! -s "$BOOT" ]; then
|
||||||
ISO="/custom.iso"
|
BOOT="/custom.iso"
|
||||||
[ ! -f "$ISO" ] && ISO="${STORAGE}$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
|
||||||
|
Loading…
Reference in New Issue
Block a user