Compare commits
76 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2822cfdc4b | ||
![]() |
810a69f5b7 | ||
![]() |
0ea09e57fc | ||
![]() |
03cdae6bd3 | ||
![]() |
f96e342cc5 | ||
![]() |
94cd48815b | ||
![]() |
0b7a9d45c5 | ||
![]() |
5816d03252 | ||
![]() |
bd0cec587c | ||
![]() |
8e51697a64 | ||
![]() |
7d900d3e97 | ||
![]() |
a4e4d84ca3 | ||
![]() |
f87bd50d70 | ||
![]() |
5b1108d6f5 | ||
![]() |
a74690db69 | ||
![]() |
de0479d7af | ||
![]() |
10197dfebb | ||
![]() |
38d03f4bfa | ||
![]() |
7797df5d35 | ||
![]() |
0c50a08808 | ||
![]() |
d5c9b7a2aa | ||
![]() |
cb7c215745 | ||
![]() |
e8b3b8dbbc | ||
![]() |
9f361e61ae | ||
![]() |
6b829625f6 | ||
![]() |
455935e2b3 | ||
![]() |
ba37a4c352 | ||
![]() |
e19f278c38 | ||
![]() |
db81ac3ebf | ||
![]() |
6318dbc9be | ||
![]() |
81b80c662a | ||
![]() |
a120d7c8c4 | ||
![]() |
60b48bc6f3 | ||
![]() |
d435ff52f8 | ||
![]() |
c791f2a2fe | ||
![]() |
6c800a97bf | ||
![]() |
afba96b912 | ||
![]() |
76bc9799ea | ||
![]() |
9d840bc012 | ||
![]() |
0751b7cb16 | ||
![]() |
0b0c2dc1d8 | ||
![]() |
70cb1ae98c | ||
![]() |
517ad6418d | ||
![]() |
2037a1783a | ||
![]() |
68b2536858 | ||
![]() |
157ca3e80c | ||
![]() |
b37137ab29 | ||
![]() |
d77408340f | ||
![]() |
ec346984fd | ||
![]() |
2dbed4ead7 | ||
![]() |
66d5c41083 | ||
![]() |
e1a59dfe48 | ||
![]() |
837f007c6c | ||
![]() |
5606964164 | ||
![]() |
0e639c5f30 | ||
![]() |
8a0245156d | ||
![]() |
0b8185477e | ||
![]() |
de644aeb69 | ||
![]() |
c0f15f6dc2 | ||
![]() |
23696ef3d3 | ||
![]() |
3d48fafab1 | ||
![]() |
47329a3791 | ||
![]() |
8fe463a7bc | ||
![]() |
908024ade5 | ||
![]() |
59a73ab9da | ||
![]() |
04f7822b6b | ||
![]() |
4f5a54d9e2 | ||
![]() |
d978d437c9 | ||
![]() |
fc6ada2f26 | ||
![]() |
24c6643d00 | ||
![]() |
0a6af455d4 | ||
![]() |
f0437fe9d1 | ||
![]() |
aacfb171d0 | ||
![]() |
9384681417 | ||
![]() |
fa993d7363 | ||
![]() |
f208547bb7 |
20 changed files with 513 additions and 367 deletions
6
.devcontainer.json
Normal file
6
.devcontainer.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"name": "windows",
|
||||||
|
"service": "windows",
|
||||||
|
"forwardPorts": [8006],
|
||||||
|
"dockerComposeFile": "compose.yml"
|
||||||
|
}
|
2
.github/ISSUE_TEMPLATE/1-issue.yml
vendored
2
.github/ISSUE_TEMPLATE/1-issue.yml
vendored
|
@ -21,6 +21,7 @@ body:
|
||||||
attributes:
|
attributes:
|
||||||
label: Docker compose
|
label: Docker compose
|
||||||
description: The compose file (or otherwise the `docker run` command used).
|
description: The compose file (or otherwise the `docker run` command used).
|
||||||
|
render: yaml
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
@ -28,6 +29,7 @@ body:
|
||||||
attributes:
|
attributes:
|
||||||
label: Docker log
|
label: Docker log
|
||||||
description: The logfile of the container (as shown by `docker logs windows`).
|
description: The logfile of the container (as shown by `docker logs windows`).
|
||||||
|
render: shell
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
|
2
.github/ISSUE_TEMPLATE/3-bug.yml
vendored
2
.github/ISSUE_TEMPLATE/3-bug.yml
vendored
|
@ -23,6 +23,7 @@ body:
|
||||||
attributes:
|
attributes:
|
||||||
label: Docker compose
|
label: Docker compose
|
||||||
description: The compose file (or otherwise the `docker run` command used).
|
description: The compose file (or otherwise the `docker run` command used).
|
||||||
|
render: yaml
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
@ -30,6 +31,7 @@ body:
|
||||||
attributes:
|
attributes:
|
||||||
label: Docker log
|
label: Docker log
|
||||||
description: The logfile of the container (as shown by `docker logs windows`).
|
description: The logfile of the container (as shown by `docker logs windows`).
|
||||||
|
render: shell
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
|
@ -50,7 +50,7 @@ jobs:
|
||||||
labels: |
|
labels: |
|
||||||
org.opencontainers.image.title=${{ vars.NAME }}
|
org.opencontainers.image.title=${{ vars.NAME }}
|
||||||
env:
|
env:
|
||||||
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest
|
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
|
||||||
-
|
-
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
@ -74,7 +74,7 @@ jobs:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
provenance: false
|
provenance: false
|
||||||
platforms: linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
annotations: ${{ steps.meta.outputs.annotations }}
|
annotations: ${{ steps.meta.outputs.annotations }}
|
||||||
|
|
15
Dockerfile
15
Dockerfile
|
@ -1,5 +1,5 @@
|
||||||
FROM scratch
|
FROM scratch
|
||||||
COPY --from=qemux/qemu-arm:2.27 / /
|
COPY --from=qemux/qemu-arm:7.12 / /
|
||||||
|
|
||||||
ARG VERSION_ARG="0.00"
|
ARG VERSION_ARG="0.00"
|
||||||
ARG DEBCONF_NOWARNINGS="yes"
|
ARG DEBCONF_NOWARNINGS="yes"
|
||||||
|
@ -9,19 +9,14 @@ ARG DEBCONF_NONINTERACTIVE_SEEN="true"
|
||||||
RUN set -eu && \
|
RUN set -eu && \
|
||||||
apt-get update && \
|
apt-get update && \
|
||||||
apt-get --no-install-recommends -y install \
|
apt-get --no-install-recommends -y install \
|
||||||
bc \
|
|
||||||
jq \
|
|
||||||
curl \
|
|
||||||
7zip \
|
|
||||||
wsdd \
|
wsdd \
|
||||||
samba \
|
samba \
|
||||||
xz-utils \
|
|
||||||
wimtools \
|
wimtools \
|
||||||
dos2unix \
|
dos2unix \
|
||||||
cabextract \
|
cabextract \
|
||||||
genisoimage \
|
|
||||||
libxml2-utils \
|
libxml2-utils \
|
||||||
libarchive-tools && \
|
libarchive-tools \
|
||||||
|
netcat-openbsd && \
|
||||||
apt-get clean && \
|
apt-get clean && \
|
||||||
echo "$VERSION_ARG" > /run/version && \
|
echo "$VERSION_ARG" > /run/version && \
|
||||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||||
|
@ -29,10 +24,10 @@ RUN set -eu && \
|
||||||
COPY --chmod=755 ./src /run/
|
COPY --chmod=755 ./src /run/
|
||||||
COPY --chmod=755 ./assets /run/assets
|
COPY --chmod=755 ./assets /run/assets
|
||||||
|
|
||||||
ADD --chmod=664 https://github.com/qemus/virtiso-arm/releases/download/v0.1.266-1/virtio-win-0.1.266.tar.xz /drivers.txz
|
ADD --chmod=664 https://github.com/qemus/virtiso-arm/releases/download/v0.1.271-1/virtio-win-0.1.271.tar.xz /var/drivers.txz
|
||||||
|
|
||||||
VOLUME /storage
|
VOLUME /storage
|
||||||
EXPOSE 8006 3389
|
EXPOSE 3389 8006
|
||||||
|
|
||||||
ENV VERSION="11"
|
ENV VERSION="11"
|
||||||
ENV RAM_SIZE="4G"
|
ENV RAM_SIZE="4G"
|
||||||
|
|
|
@ -326,11 +326,6 @@
|
||||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "AllowInsecureGuestAuth" /t REG_DWORD /d 1 /f</CommandLine>
|
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "AllowInsecureGuestAuth" /t REG_DWORD /d 1 /f</CommandLine>
|
||||||
<Description>Allow guest access to network shares</Description>
|
<Description>Allow guest access to network shares</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
|
||||||
<Order>2</Order>
|
|
||||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LimitBlankPasswordUse /t REG_DWORD /d 0 /f</CommandLine>
|
|
||||||
<Description>Allow RDP login with blank password</Description>
|
|
||||||
</SynchronousCommand>
|
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>3</Order>
|
<Order>3</Order>
|
||||||
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" /v "DevicePasswordLessBuildVersion" /t REG_DWORD /d 0 /f</CommandLine>
|
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" /v "DevicePasswordLessBuildVersion" /t REG_DWORD /d 0 /f</CommandLine>
|
||||||
|
@ -418,6 +413,11 @@
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>20</Order>
|
<Order>20</Order>
|
||||||
|
<CommandLine>cmd /C echo 20.20.20.1 host.lan >> %WINDIR%\system32\drivers\etc\hosts</CommandLine>
|
||||||
|
<Description>Add entry in hosts file</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>21</Order>
|
||||||
<CommandLine>cmd /C if exist "C:\OEM\install.bat" start "Install" "cmd /C C:\OEM\install.bat"</CommandLine>
|
<CommandLine>cmd /C if exist "C:\OEM\install.bat" start "Install" "cmd /C C:\OEM\install.bat"</CommandLine>
|
||||||
<Description>Execute custom script from the OEM folder if exists</Description>
|
<Description>Execute custom script from the OEM folder if exists</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
|
|
|
@ -329,11 +329,6 @@
|
||||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "AllowInsecureGuestAuth" /t REG_DWORD /d 1 /f</CommandLine>
|
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "AllowInsecureGuestAuth" /t REG_DWORD /d 1 /f</CommandLine>
|
||||||
<Description>Allow guest access to network shares</Description>
|
<Description>Allow guest access to network shares</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
|
||||||
<Order>2</Order>
|
|
||||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LimitBlankPasswordUse /t REG_DWORD /d 0 /f</CommandLine>
|
|
||||||
<Description>Allow RDP login with blank password</Description>
|
|
||||||
</SynchronousCommand>
|
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>3</Order>
|
<Order>3</Order>
|
||||||
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" /v "DevicePasswordLessBuildVersion" /t REG_DWORD /d 0 /f</CommandLine>
|
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" /v "DevicePasswordLessBuildVersion" /t REG_DWORD /d 0 /f</CommandLine>
|
||||||
|
@ -421,6 +416,11 @@
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>20</Order>
|
<Order>20</Order>
|
||||||
|
<CommandLine>cmd /C echo 20.20.20.1 host.lan >> %WINDIR%\system32\drivers\etc\hosts</CommandLine>
|
||||||
|
<Description>Add entry in hosts file</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>21</Order>
|
||||||
<CommandLine>cmd /C if exist "C:\OEM\install.bat" start "Install" "cmd /C C:\OEM\install.bat"</CommandLine>
|
<CommandLine>cmd /C if exist "C:\OEM\install.bat" start "Install" "cmd /C C:\OEM\install.bat"</CommandLine>
|
||||||
<Description>Execute custom script from the OEM folder if exists</Description>
|
<Description>Execute custom script from the OEM folder if exists</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
|
|
|
@ -326,11 +326,6 @@
|
||||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "AllowInsecureGuestAuth" /t REG_DWORD /d 1 /f</CommandLine>
|
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "AllowInsecureGuestAuth" /t REG_DWORD /d 1 /f</CommandLine>
|
||||||
<Description>Allow guest access to network shares</Description>
|
<Description>Allow guest access to network shares</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
|
||||||
<Order>2</Order>
|
|
||||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LimitBlankPasswordUse /t REG_DWORD /d 0 /f</CommandLine>
|
|
||||||
<Description>Allow RDP login with blank password</Description>
|
|
||||||
</SynchronousCommand>
|
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>3</Order>
|
<Order>3</Order>
|
||||||
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" /v "DevicePasswordLessBuildVersion" /t REG_DWORD /d 0 /f</CommandLine>
|
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" /v "DevicePasswordLessBuildVersion" /t REG_DWORD /d 0 /f</CommandLine>
|
||||||
|
@ -418,6 +413,11 @@
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>20</Order>
|
<Order>20</Order>
|
||||||
|
<CommandLine>cmd /C echo 20.20.20.1 host.lan >> %WINDIR%\system32\drivers\etc\hosts</CommandLine>
|
||||||
|
<Description>Add entry in hosts file</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>21</Order>
|
||||||
<CommandLine>cmd /C if exist "C:\OEM\install.bat" start "Install" "cmd /C C:\OEM\install.bat"</CommandLine>
|
<CommandLine>cmd /C if exist "C:\OEM\install.bat" start "Install" "cmd /C C:\OEM\install.bat"</CommandLine>
|
||||||
<Description>Execute custom script from the OEM folder if exists</Description>
|
<Description>Execute custom script from the OEM folder if exists</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
|
|
|
@ -268,6 +268,11 @@
|
||||||
<Path>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\FirstNetwork" /v Category /t REG_DWORD /d 1 /f</Path>
|
<Path>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\FirstNetwork" /v Category /t REG_DWORD /d 1 /f</Path>
|
||||||
<Description>Set Network Location to Home</Description>
|
<Description>Set Network Location to Home</Description>
|
||||||
</RunSynchronousCommand>
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>26</Order>
|
||||||
|
<Path>pnputil -i -a C:\Windows\Drivers\viogpudo\viogpudo.inf</Path>
|
||||||
|
<Description>Install VirtIO display driver</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
</RunSynchronous>
|
</RunSynchronous>
|
||||||
</component>
|
</component>
|
||||||
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||||
|
@ -350,11 +355,6 @@
|
||||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "RequireSecuritySignature" /t REG_DWORD /d 0 /f</CommandLine>
|
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "RequireSecuritySignature" /t REG_DWORD /d 0 /f</CommandLine>
|
||||||
<Description>Disable SMB signing requirement</Description>
|
<Description>Disable SMB signing requirement</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
|
||||||
<Order>3</Order>
|
|
||||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LimitBlankPasswordUse /t REG_DWORD /d 0 /f</CommandLine>
|
|
||||||
<Description>Allow RDP login with blank password</Description>
|
|
||||||
</SynchronousCommand>
|
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>4</Order>
|
<Order>4</Order>
|
||||||
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" /v "DevicePasswordLessBuildVersion" /t REG_DWORD /d 0 /f</CommandLine>
|
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" /v "DevicePasswordLessBuildVersion" /t REG_DWORD /d 0 /f</CommandLine>
|
||||||
|
@ -447,13 +447,13 @@
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>22</Order>
|
<Order>22</Order>
|
||||||
<CommandLine>pnputil -i -a C:\Windows\Drivers\viogpudo\viogpudo.inf</CommandLine>
|
<CommandLine>cmd /C rd /q C:\Windows.old</CommandLine>
|
||||||
<Description>Install VirtIO display driver</Description>
|
<Description>Remove empty Windows.old folder</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>23</Order>
|
<Order>23</Order>
|
||||||
<CommandLine>cmd /C rd /q C:\Windows.old</CommandLine>
|
<CommandLine>cmd /C echo 20.20.20.1 host.lan >> %WINDIR%\system32\drivers\etc\hosts</CommandLine>
|
||||||
<Description>Remove empty Windows.old folder</Description>
|
<Description>Add entry in hosts file</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>24</Order>
|
<Order>24</Order>
|
||||||
|
|
|
@ -267,6 +267,11 @@
|
||||||
<Path>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\FirstNetwork" /v Category /t REG_DWORD /d 1 /f</Path>
|
<Path>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\FirstNetwork" /v Category /t REG_DWORD /d 1 /f</Path>
|
||||||
<Description>Set Network Location to Home</Description>
|
<Description>Set Network Location to Home</Description>
|
||||||
</RunSynchronousCommand>
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>26</Order>
|
||||||
|
<Path>pnputil -i -a C:\Windows\Drivers\viogpudo\viogpudo.inf</Path>
|
||||||
|
<Description>Install VirtIO display driver</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
</RunSynchronous>
|
</RunSynchronous>
|
||||||
</component>
|
</component>
|
||||||
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||||
|
@ -349,11 +354,6 @@
|
||||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "RequireSecuritySignature" /t REG_DWORD /d 0 /f</CommandLine>
|
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "RequireSecuritySignature" /t REG_DWORD /d 0 /f</CommandLine>
|
||||||
<Description>Disable SMB signing requirement</Description>
|
<Description>Disable SMB signing requirement</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
|
||||||
<Order>3</Order>
|
|
||||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LimitBlankPasswordUse /t REG_DWORD /d 0 /f</CommandLine>
|
|
||||||
<Description>Allow RDP login with blank password</Description>
|
|
||||||
</SynchronousCommand>
|
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>4</Order>
|
<Order>4</Order>
|
||||||
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" /v "DevicePasswordLessBuildVersion" /t REG_DWORD /d 0 /f</CommandLine>
|
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" /v "DevicePasswordLessBuildVersion" /t REG_DWORD /d 0 /f</CommandLine>
|
||||||
|
@ -446,13 +446,13 @@
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>22</Order>
|
<Order>22</Order>
|
||||||
<CommandLine>pnputil -i -a C:\Windows\Drivers\viogpudo\viogpudo.inf</CommandLine>
|
<CommandLine>cmd /C rd /q C:\Windows.old</CommandLine>
|
||||||
<Description>Install VirtIO display driver</Description>
|
<Description>Remove empty Windows.old folder</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>23</Order>
|
<Order>23</Order>
|
||||||
<CommandLine>cmd /C rd /q C:\Windows.old</CommandLine>
|
<CommandLine>cmd /C echo 20.20.20.1 host.lan >> %WINDIR%\system32\drivers\etc\hosts</CommandLine>
|
||||||
<Description>Remove empty Windows.old folder</Description>
|
<Description>Add entry in hosts file</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>24</Order>
|
<Order>24</Order>
|
||||||
|
|
|
@ -268,6 +268,11 @@
|
||||||
<Path>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\FirstNetwork" /v Category /t REG_DWORD /d 1 /f</Path>
|
<Path>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\FirstNetwork" /v Category /t REG_DWORD /d 1 /f</Path>
|
||||||
<Description>Set Network Location to Home</Description>
|
<Description>Set Network Location to Home</Description>
|
||||||
</RunSynchronousCommand>
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>26</Order>
|
||||||
|
<Path>pnputil -i -a C:\Windows\Drivers\viogpudo\viogpudo.inf</Path>
|
||||||
|
<Description>Install VirtIO display driver</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
</RunSynchronous>
|
</RunSynchronous>
|
||||||
</component>
|
</component>
|
||||||
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="arm64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||||
|
@ -350,11 +355,6 @@
|
||||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "RequireSecuritySignature" /t REG_DWORD /d 0 /f</CommandLine>
|
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v "RequireSecuritySignature" /t REG_DWORD /d 0 /f</CommandLine>
|
||||||
<Description>Disable SMB signing requirement</Description>
|
<Description>Disable SMB signing requirement</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
|
||||||
<Order>3</Order>
|
|
||||||
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LimitBlankPasswordUse /t REG_DWORD /d 0 /f</CommandLine>
|
|
||||||
<Description>Allow RDP login with blank password</Description>
|
|
||||||
</SynchronousCommand>
|
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>4</Order>
|
<Order>4</Order>
|
||||||
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" /v "DevicePasswordLessBuildVersion" /t REG_DWORD /d 0 /f</CommandLine>
|
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" /v "DevicePasswordLessBuildVersion" /t REG_DWORD /d 0 /f</CommandLine>
|
||||||
|
@ -447,13 +447,13 @@
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>22</Order>
|
<Order>22</Order>
|
||||||
<CommandLine>pnputil -i -a C:\Windows\Drivers\viogpudo\viogpudo.inf</CommandLine>
|
<CommandLine>cmd /C rd /q C:\Windows.old</CommandLine>
|
||||||
<Description>Install VirtIO display driver</Description>
|
<Description>Remove empty Windows.old folder</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>23</Order>
|
<Order>23</Order>
|
||||||
<CommandLine>cmd /C rd /q C:\Windows.old</CommandLine>
|
<CommandLine>cmd /C echo 20.20.20.1 host.lan >> %WINDIR%\system32\drivers\etc\hosts</CommandLine>
|
||||||
<Description>Remove empty Windows.old folder</Description>
|
<Description>Add entry in hosts file</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>24</Order>
|
<Order>24</Order>
|
||||||
|
|
|
@ -13,5 +13,7 @@ services:
|
||||||
- 8006:8006
|
- 8006:8006
|
||||||
- 3389:3389/tcp
|
- 3389:3389/tcp
|
||||||
- 3389:3389/udp
|
- 3389:3389/udp
|
||||||
|
volumes:
|
||||||
|
- ./windows:/storage
|
||||||
restart: always
|
restart: always
|
||||||
stop_grace_period: 2m
|
stop_grace_period: 2m
|
||||||
|
|
|
@ -10,12 +10,21 @@ spec:
|
||||||
requests:
|
requests:
|
||||||
storage: 64Gi
|
storage: 64Gi
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: apps/v1
|
||||||
kind: Pod
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: windows
|
name: windows
|
||||||
labels:
|
labels:
|
||||||
name: windows
|
name: windows
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: windows
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: windows
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: windows
|
- name: windows
|
||||||
|
@ -23,17 +32,21 @@ spec:
|
||||||
env:
|
env:
|
||||||
- name: VERSION
|
- name: VERSION
|
||||||
value: "11"
|
value: "11"
|
||||||
- name: RAM_SIZE
|
|
||||||
value: "4G"
|
|
||||||
- name: CPU_CORES
|
|
||||||
value: "2"
|
|
||||||
- name: DISK_SIZE
|
- name: DISK_SIZE
|
||||||
value: "64G"
|
value: "64G"
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8006
|
- containerPort: 8006
|
||||||
|
name: http
|
||||||
|
protocol: TCP
|
||||||
- containerPort: 3389
|
- containerPort: 3389
|
||||||
|
name: rdp
|
||||||
|
protocol: TCP
|
||||||
- containerPort: 3389
|
- containerPort: 3389
|
||||||
|
name: udp
|
||||||
protocol: UDP
|
protocol: UDP
|
||||||
|
- containerPort: 5900
|
||||||
|
name: vnc
|
||||||
|
protocol: TCP
|
||||||
securityContext:
|
securityContext:
|
||||||
capabilities:
|
capabilities:
|
||||||
add:
|
add:
|
||||||
|
@ -64,14 +77,24 @@ kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: windows
|
name: windows
|
||||||
spec:
|
spec:
|
||||||
|
internalTrafficPolicy: Cluster
|
||||||
ports:
|
ports:
|
||||||
- name: tcp-8006
|
- name: http
|
||||||
port: 8006
|
port: 8006
|
||||||
- name: tcp-3389
|
protocol: TCP
|
||||||
|
targetPort: 8006
|
||||||
|
- name: rdp
|
||||||
port: 3389
|
port: 3389
|
||||||
- name: udp-3389
|
protocol: TCP
|
||||||
|
targetPort: 3389
|
||||||
|
- name: udp
|
||||||
port: 3389
|
port: 3389
|
||||||
protocol: UDP
|
protocol: UDP
|
||||||
|
targetPort: 3389
|
||||||
|
- name: vnc
|
||||||
|
port: 5900
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: 5900
|
||||||
selector:
|
selector:
|
||||||
name: windows
|
app: windows
|
||||||
type: NodePort
|
type: ClusterIP
|
||||||
|
|
186
readme.md
186
readme.md
|
@ -26,7 +26,7 @@ Windows for ARM in a Docker container, for devices like the Raspberry Pi 5 and m
|
||||||
|
|
||||||
## Usage 🐳
|
## Usage 🐳
|
||||||
|
|
||||||
Via Docker Compose:
|
##### Via Docker Compose:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
|
@ -44,29 +44,27 @@ services:
|
||||||
- 8006:8006
|
- 8006:8006
|
||||||
- 3389:3389/tcp
|
- 3389:3389/tcp
|
||||||
- 3389:3389/udp
|
- 3389:3389/udp
|
||||||
|
volumes:
|
||||||
|
- ./windows:/storage
|
||||||
restart: always
|
restart: always
|
||||||
stop_grace_period: 2m
|
stop_grace_period: 2m
|
||||||
```
|
```
|
||||||
|
|
||||||
Via Docker CLI:
|
##### Via Docker CLI:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -it --rm -p 8006:8006 --device=/dev/kvm --device=/dev/net/tun --cap-add NET_ADMIN --stop-timeout 120 dockurr/windows
|
docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --device=/dev/net/tun --cap-add NET_ADMIN -v "${PWD:-.}/windows:/storage" --stop-timeout 120 dockurr/windows
|
||||||
```
|
```
|
||||||
|
|
||||||
Via Kubernetes:
|
##### Via Kubernetes:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl apply -f https://raw.githubusercontent.com/dockur/windows-arm/refs/heads/master/kubernetes.yml
|
kubectl apply -f https://raw.githubusercontent.com/dockur/windows/refs/heads/master/kubernetes.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
## Compatibility ⚙️
|
##### Via Github Codespaces:
|
||||||
|
|
||||||
| **Product** | **Platform** | |
|
[](https://codespaces.new/dockur/windows-arm)
|
||||||
|---|---|---|
|
|
||||||
| Docker Engine | Linux| ✅ |
|
|
||||||
| Docker Desktop | Linux | ❌ |
|
|
||||||
| Docker Desktop | macOS | ❌ |
|
|
||||||
|
|
||||||
## FAQ 💬
|
## FAQ 💬
|
||||||
|
|
||||||
|
@ -74,7 +72,7 @@ kubectl apply -f https://raw.githubusercontent.com/dockur/windows-arm/refs/heads
|
||||||
|
|
||||||
Very simple! These are the steps:
|
Very simple! These are the steps:
|
||||||
|
|
||||||
- Start the container and connect to [port 8006](http://localhost:8006) using your web browser.
|
- Start the container and connect to [port 8006](http://127.0.0.1:8006/) using your web browser.
|
||||||
|
|
||||||
- Sit back and relax while the magic happens, the whole installation will be performed fully automatic.
|
- Sit back and relax while the magic happens, the whole installation will be performed fully automatic.
|
||||||
|
|
||||||
|
@ -93,15 +91,15 @@ kubectl apply -f https://raw.githubusercontent.com/dockur/windows-arm/refs/heads
|
||||||
|
|
||||||
Select from the values below:
|
Select from the values below:
|
||||||
|
|
||||||
| **Value** | **Version** | **Platform** | **Size** |
|
| **Value** | **Version** | **Size** |
|
||||||
|---|---|---|---|
|
|---|---|---|
|
||||||
| `11` | Windows 11 Pro | ARM64 | 5.0 GB |
|
| `11` | Windows 11 Pro | 4.8 GB |
|
||||||
| `11l` | Windows 11 LTSC | ARM64 | 3.9 GB |
|
| `11l` | Windows 11 LTSC | 4.7 GB |
|
||||||
| `11e` | Windows 11 Enterprise | ARM64 | 4.8 GB |
|
| `11e` | Windows 11 Enterprise | 4.8 GB |
|
||||||
|||||
|
||||
|
||||||
| `10` | Windows 10 Pro | ARM64 | 3.5 GB |
|
| `10` | Windows 10 Pro | 3.5 GB |
|
||||||
| `10l` | Windows 10 LTSC | ARM64 | 4.1 GB |
|
| `10l` | Windows 10 LTSC | 4.1 GB |
|
||||||
| `10e` | Windows 10 Enterprise | ARM64 | 3.4 GB |
|
| `10e` | Windows 10 Enterprise | 3.4 GB |
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> To install x64 versions of Windows, use [dockur/windows](https://github.com/dockur/windows/).
|
> To install x64 versions of Windows, use [dockur/windows](https://github.com/dockur/windows/).
|
||||||
|
@ -112,10 +110,10 @@ kubectl apply -f https://raw.githubusercontent.com/dockur/windows-arm/refs/heads
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
volumes:
|
volumes:
|
||||||
- /var/win:/storage
|
- ./windows:/storage
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace the example path `/var/win` with the desired storage folder.
|
Replace the example path `./windows` with the desired storage folder or named volume.
|
||||||
|
|
||||||
### How do I change the size of the disk?
|
### How do I change the size of the disk?
|
||||||
|
|
||||||
|
@ -133,71 +131,29 @@ kubectl apply -f https://raw.githubusercontent.com/dockur/windows-arm/refs/heads
|
||||||
|
|
||||||
The display output is a simple framebuffer, just so that the screen can be visible during installation as it doesn't require any drivers.
|
The display output is a simple framebuffer, just so that the screen can be visible during installation as it doesn't require any drivers.
|
||||||
|
|
||||||
After Windows is fully installed, you can add the following to your compose file:
|
To add a virtual graphics cards to your machine that allows for higher resolutions, you can add the following to your compose file after Windows is fully installed:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
VGA: "virtio-gpu"
|
VGA: "virtio-gpu"
|
||||||
```
|
```
|
||||||
|
|
||||||
to add a virtual graphics cards to your machine that allows for higher resolutions.
|
|
||||||
|
|
||||||
### How do I share files with the host?
|
### How do I share files with the host?
|
||||||
|
|
||||||
Open 'File Explorer' and click on the 'Network' section, you will see a computer called `host.lan`. Double-click it and it will show a folder called `Data`, which can be bound to any folder on your host via the compose file:
|
Open 'File Explorer' and click on the 'Network' section, you will see a computer called `host.lan`.
|
||||||
|
|
||||||
|
Double-click it and it will show a folder called `Data`, which can be bound to any folder on your host via the compose file:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
volumes:
|
volumes:
|
||||||
- /home/user/example:/data
|
- ./example:/data
|
||||||
```
|
```
|
||||||
|
|
||||||
The example folder `/home/user/example` will be available as ` \\host.lan\Data`.
|
The example folder `./example` will be available as ` \\host.lan\Data`.
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> You can map this path to a drive letter in Windows, for easier access.
|
> You can map this path to a drive letter in Windows, for easier access.
|
||||||
|
|
||||||
### How do I install a custom image?
|
|
||||||
|
|
||||||
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 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.
|
|
||||||
|
|
||||||
### How do I run a script after installation?
|
|
||||||
|
|
||||||
To run your own script after installation, you can create a file called `install.bat` and place it in a folder together with any additional files it needs (software to be installed for example).
|
|
||||||
|
|
||||||
Then bind that folder in your compose file like this:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
volumes:
|
|
||||||
- /home/user/example:/oem
|
|
||||||
```
|
|
||||||
|
|
||||||
The example folder `/home/user/example` will be copied to `C:\OEM` during installation and the containing `install.bat` will be executed during the last step.
|
|
||||||
|
|
||||||
### How do I perform a manual installation?
|
|
||||||
|
|
||||||
It's best to stick to the automatic installation, as it adjusts various settings to prevent common issues when running Windows inside a virtual environment.
|
|
||||||
|
|
||||||
However, if you insist on performing the installation manually, add the following environment variable to your compose file:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
environment:
|
|
||||||
MANUAL: "Y"
|
|
||||||
```
|
|
||||||
|
|
||||||
### How do I change the amount of CPU or RAM?
|
### How do I change the amount of CPU or RAM?
|
||||||
|
|
||||||
By default, the container will be allowed to use a maximum of 2 CPU cores and 4 GB of RAM.
|
By default, the container will be allowed to use a maximum of 2 CPU cores and 4 GB of RAM.
|
||||||
|
@ -212,9 +168,9 @@ The example folder `/home/user/example` will be available as ` \\host.lan\Data`.
|
||||||
|
|
||||||
### How do I configure the username and password?
|
### How do I configure the username and password?
|
||||||
|
|
||||||
By default, a user called `Docker` is created during the installation, with an empty password.
|
By default, a user called `Docker` is created during installation and its password is `admin`.
|
||||||
|
|
||||||
If you want to use different credentials, you can change them in your compose file:
|
If you want to use different credentials, you can configure them in your compose file (only before installation):
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
|
@ -224,7 +180,9 @@ The example folder `/home/user/example` will be available as ` \\host.lan\Data`.
|
||||||
|
|
||||||
### How do I select the Windows language?
|
### How do I select the Windows language?
|
||||||
|
|
||||||
By default, the English version of Windows will be downloaded. But you can add the `LANGUAGE` environment variable to your compose file, in order to specify an alternative language:
|
By default, the English version of Windows will be downloaded.
|
||||||
|
|
||||||
|
But before installation you can add the `LANGUAGE` environment variable to your compose file, in order to specify an alternative language:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
|
@ -235,7 +193,7 @@ The example folder `/home/user/example` will be available as ` \\host.lan\Data`.
|
||||||
|
|
||||||
### How do I select the keyboard layout?
|
### How do I select the keyboard layout?
|
||||||
|
|
||||||
If you want to use a keyboard layout or locale that is not the default for your selected language, you can add the `KEYBOARD` and `REGION` variables with a culture code, like this:
|
If you want to use a keyboard layout or locale that is not the default for your selected language, you can add `KEYBOARD` and `REGION` variables like this (before installation):
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
|
@ -243,14 +201,53 @@ The example folder `/home/user/example` will be available as ` \\host.lan\Data`.
|
||||||
KEYBOARD: "en-US"
|
KEYBOARD: "en-US"
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!NOTE]
|
### How do I install a custom image?
|
||||||
> Changing these values will have no effect after the installation has been performed already. Use the control panel inside Windows in that case.
|
|
||||||
|
In order to download an unsupported ISO image, specify its URL in the `VERSION` environment variable:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
VERSION: "https://example.com/win.iso"
|
||||||
|
```
|
||||||
|
|
||||||
|
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:
|
||||||
|
- ./example.iso:/boot.iso
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace the example path `./example.iso` with the filename of your desired ISO file. The value of `VERSION` will be ignored in this case.
|
||||||
|
|
||||||
|
### How do I run a script after installation?
|
||||||
|
|
||||||
|
To run your own script after installation, you can create a file called `install.bat` and place it in a folder together with any additional files it needs (software to be installed for example).
|
||||||
|
|
||||||
|
Then bind that folder in your compose file like this:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
volumes:
|
||||||
|
- ./example:/oem
|
||||||
|
```
|
||||||
|
|
||||||
|
The example folder `./example` will be copied to `C:\OEM` and the containing `install.bat` will be executed during the last step of the automatic installation.
|
||||||
|
|
||||||
|
### How do I perform a manual installation?
|
||||||
|
|
||||||
|
It's recommended to stick to the automatic installation, as it adjusts various settings to prevent common issues when running Windows inside a virtual environment.
|
||||||
|
|
||||||
|
However, if you insist on performing the installation manually at your own risk, add the following environment variable to your compose file:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
MANUAL: "Y"
|
||||||
|
```
|
||||||
|
|
||||||
### How do I connect using RDP?
|
### How do I connect using RDP?
|
||||||
|
|
||||||
The web-viewer is mainly meant to be used during installation, as its picture quality is low, and it has no audio or clipboard for example.
|
The web-viewer is mainly meant to be used during installation, as its picture quality is low, and it has no audio or clipboard for example.
|
||||||
|
|
||||||
So for a better experience you can connect using any Microsoft Remote Desktop client to the IP of the container, using the username `Docker` and by leaving the password empty.
|
So for a better experience you can connect using any Microsoft Remote Desktop client to the IP of the container, using the username `Docker` and password `admin`.
|
||||||
|
|
||||||
There is a RDP client for [Android](https://play.google.com/store/apps/details?id=com.microsoft.rdc.androidx) available from the Play Store and one for [iOS](https://apps.apple.com/nl/app/microsoft-remote-desktop/id714464092?l=en-GB) in the Apple Store. For Linux you can use [FreeRDP](https://www.freerdp.com/) and on Windows just type `mstsc` in the search box.
|
There is a RDP client for [Android](https://play.google.com/store/apps/details?id=com.microsoft.rdc.androidx) available from the Play Store and one for [iOS](https://apps.apple.com/nl/app/microsoft-remote-desktop/id714464092?l=en-GB) in the Apple Store. For Linux you can use [FreeRDP](https://www.freerdp.com/) and on Windows just type `mstsc` in the search box.
|
||||||
|
|
||||||
|
@ -295,7 +292,7 @@ The example folder `/home/user/example` will be available as ` \\host.lan\Data`.
|
||||||
|
|
||||||
After configuring the container for [macvlan](#how-do-i-assign-an-individual-ip-address-to-the-container), it is possible for Windows to become part of your home network by requesting an IP from your router, just like a real PC.
|
After configuring the container for [macvlan](#how-do-i-assign-an-individual-ip-address-to-the-container), it is possible for Windows to become part of your home network by requesting an IP from your router, just like a real PC.
|
||||||
|
|
||||||
To enable this mode, add the following lines to your compose file:
|
To enable this mode, in which the container and Windows will have separate IP addresses, add the following lines to your compose file:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
|
@ -306,9 +303,6 @@ The example folder `/home/user/example` will be available as ` \\host.lan\Data`.
|
||||||
- 'c *:* rwm'
|
- 'c *:* rwm'
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> In this mode, the container and Windows will each have their own separate IPs.
|
|
||||||
|
|
||||||
### How do I add multiple disks?
|
### How do I add multiple disks?
|
||||||
|
|
||||||
To create additional disks, modify your compose file like this:
|
To create additional disks, modify your compose file like this:
|
||||||
|
@ -318,18 +312,18 @@ The example folder `/home/user/example` will be available as ` \\host.lan\Data`.
|
||||||
DISK2_SIZE: "32G"
|
DISK2_SIZE: "32G"
|
||||||
DISK3_SIZE: "64G"
|
DISK3_SIZE: "64G"
|
||||||
volumes:
|
volumes:
|
||||||
- /home/example:/storage2
|
- ./example2:/storage2
|
||||||
- /mnt/data/example:/storage3
|
- ./example3:/storage3
|
||||||
```
|
```
|
||||||
|
|
||||||
### How do I pass-through a disk?
|
### How do I pass-through a disk?
|
||||||
|
|
||||||
It is possible to pass-through disk devices directly by adding them to your compose file in this way:
|
It is possible to pass-through disk devices or partitions directly by adding them to your compose file in this way:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
devices:
|
devices:
|
||||||
- /dev/sdb:/disk1
|
- /dev/sdb:/disk1
|
||||||
- /dev/sdc:/disk2
|
- /dev/sdc1:/disk2
|
||||||
```
|
```
|
||||||
|
|
||||||
Use `/disk1` if you want it to become your main drive (which will be formatted during installation), and use `/disk2` and higher to add them as secondary drives (which will stay untouched).
|
Use `/disk1` if you want it to become your main drive (which will be formatted during installation), and use `/disk2` and higher to add them as secondary drives (which will stay untouched).
|
||||||
|
@ -345,14 +339,20 @@ The example folder `/home/user/example` will be available as ` \\host.lan\Data`.
|
||||||
- /dev/bus/usb
|
- /dev/bus/usb
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!IMPORTANT]
|
If the device is a USB disk drive, please wait until after the installation is completed before connecting it. Otherwise the installation may fail, as the order of the disks can get rearranged.
|
||||||
> If the device is a USB disk drive, please wait until after the installation is completed before connecting it. Otherwise the installation may fail, as the order of the disks can get rearranged.
|
|
||||||
|
|
||||||
### How do I verify if my system supports KVM?
|
### How do I verify if my system supports KVM?
|
||||||
|
|
||||||
Only Linux and Windows 11 support KVM virtualization, macOS and Windows 10 do not unfortunately.
|
First check if your software is compatible using this chart:
|
||||||
|
|
||||||
You can run the following commands in Linux to check your system:
|
| **Product** | **Linux** | **Win11** | **Win10** | **macOS** |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| Docker CLI | ✅ | ✅ | ❌ | ❌ |
|
||||||
|
| Docker Desktop | ❌ | ✅ | ❌ | ❌ |
|
||||||
|
| Podman CLI | ✅ | ✅ | ❌ | ❌ |
|
||||||
|
| Podman Desktop | ✅ | ✅ | ❌ | ❌ |
|
||||||
|
|
||||||
|
After that you can run the following commands in Linux to check your system:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt install cpu-checker
|
sudo apt install cpu-checker
|
||||||
|
@ -367,11 +367,11 @@ The example folder `/home/user/example` will be available as ` \\host.lan\Data`.
|
||||||
|
|
||||||
- you are not using a cloud provider, as most of them do not allow nested virtualization for their VPS's.
|
- you are not using a cloud provider, as most of them do not allow nested virtualization for their VPS's.
|
||||||
|
|
||||||
If you do not receive any error from `kvm-ok` but the container still complains about KVM, please check whether:
|
If you did not receive any error from `kvm-ok` but the container still complains about a missing KVM device, it could help to add `privileged: true` to your compose file (or `sudo` to your `docker` command) to rule out any permission issue.
|
||||||
|
|
||||||
- you are not using "Docker Desktop for Linux" as it does not support KVM, instead make use of Docker Engine directly.
|
### How do I run a Linux desktop in a container?
|
||||||
|
|
||||||
- it could help to add `privileged: true` to your compose file (or `sudo` to your `docker run` command), to rule out any permission issue.
|
You can use [qemus/qemu-arm](https://github.com/qemus/qemu-arm) in that case.
|
||||||
|
|
||||||
### Is this project legal?
|
### Is this project legal?
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
: "${KEY:=""}"
|
||||||
: "${WIDTH:=""}"
|
: "${WIDTH:=""}"
|
||||||
: "${HEIGHT:=""}"
|
: "${HEIGHT:=""}"
|
||||||
: "${VERIFY:=""}"
|
: "${VERIFY:=""}"
|
||||||
|
@ -16,7 +17,6 @@ set -Eeuo pipefail
|
||||||
: "${PASSWORD:=""}"
|
: "${PASSWORD:=""}"
|
||||||
|
|
||||||
MIRRORS=2
|
MIRRORS=2
|
||||||
PLATFORM="ARM64"
|
|
||||||
|
|
||||||
parseVersion() {
|
parseVersion() {
|
||||||
|
|
||||||
|
@ -61,20 +61,23 @@ parseVersion() {
|
||||||
"8e" | "81e" | "8.1e" | "win8e" | "win81e" | "windows 8e" )
|
"8e" | "81e" | "8.1e" | "win8e" | "win81e" | "windows 8e" )
|
||||||
error "Windows 8 $msg" && return 1
|
error "Windows 8 $msg" && return 1
|
||||||
;;
|
;;
|
||||||
"7" | "7e" | "win7" | "win7e" | "windows7" | "windows 7" | \
|
"7" | "win7" | "windows7" | "windows 7" | "7u" | "win7u" | "windows7u" | "windows 7u" | "7e" | \
|
||||||
"7u" | "win7u" | "windows7u" | "windows 7u" | \
|
"win7e" | "windows7e" | "windows 7e" | "7x86" | "win7x86" | "win732" | "windows7x86" | "7ux86" | \
|
||||||
"7x86" | "win7x86" | "windows7x86" | "win7x86-enterprise" )
|
"7u32" | "win7x86-ultimate" | "7ex86" | "7e32" | "win7x86-enterprise" )
|
||||||
error "Windows 7 $msg" && return 1
|
error "Windows 7 $msg" && return 1
|
||||||
;;
|
;;
|
||||||
"vista" | "ve" | "6" | "winvista" | "windowsvista" | "windows vista" | \
|
"vista" | "vs" | "6" | "winvista" | "windowsvista" | "windows vista" | "vistu" | "vu" | "6u" | "winvistu" | \
|
||||||
"vistu" | "vu" | "6u" | "winvistu" | "windowsvistu" | "windows vistu" | \
|
"viste" | "ve" | "6e" | "winviste" | "vistax86" | "vista32" | "6x86" | "winvistax86" | "windowsvistax86" | \
|
||||||
"vistax86" | "vex86" | "6x86" | "winvistax86" | "windowsvistax86" | "winvistax86-enterprise" )
|
"vux86" | "vu32" | "winvistax86-ultimate" | "vex86" | "ve32" | "winvistax86-enterprise" )
|
||||||
error "Windows Vista $msg" && return 1
|
error "Windows Vista $msg" && return 1
|
||||||
;;
|
;;
|
||||||
"xp" | "xp32" | "xpx86" | "5" | "5x86" | "winxp" | "winxp86" | "windowsxp" | "windows xp" | \
|
"xp" | "xp32" | "xpx86" | "5" | "5x86" | "winxp" | "winxp86" | "windowsxp" | "windows xp" | \
|
||||||
"xp64" | "xpx64" | "5x64" | "winxp64" | "winxpx64" | "windowsxp64" | "windowsxpx64" )
|
"xp64" | "xpx64" | "5x64" | "winxp64" | "winxpx64" | "windowsxp64" | "windowsxpx64" )
|
||||||
error "Windows XP $msg" && return 1
|
error "Windows XP $msg" && return 1
|
||||||
;;
|
;;
|
||||||
|
"2k" | "2000" | "win2k" | "win2000" | "windows2k" | "windows2000" )
|
||||||
|
error "Windows 2000 $msg" && return 1
|
||||||
|
;;
|
||||||
"25" | "2025" | "win25" | "win2025" | "windows2025" | "windows 2025" )
|
"25" | "2025" | "win25" | "win2025" | "windows2025" | "windows 2025" )
|
||||||
error "Windows Server 2025 $msg" && return 1
|
error "Windows Server 2025 $msg" && return 1
|
||||||
;;
|
;;
|
||||||
|
@ -87,6 +90,9 @@ parseVersion() {
|
||||||
"16" | "2016" | "win16" | "win2016" | "windows2016" | "windows 2016" )
|
"16" | "2016" | "win16" | "win2016" | "windows2016" | "windows 2016" )
|
||||||
error "Windows Server 2016 $msg" && return 1
|
error "Windows Server 2016 $msg" && return 1
|
||||||
;;
|
;;
|
||||||
|
"hv" | "hyperv" | "hyper v" | "hyper-v" | "19hv" | "2019hv" | "win2019hv" )
|
||||||
|
error "Hyper-V Server 2019 $msg" && return 1
|
||||||
|
;;
|
||||||
"2012" | "2012r2" | "win2012" | "win2012r2" | "windows2012" | "windows 2012" )
|
"2012" | "2012r2" | "win2012" | "win2012r2" | "windows2012" | "windows 2012" )
|
||||||
error "Windows Server 2012 $msg" && return 1
|
error "Windows Server 2012 $msg" && return 1
|
||||||
;;
|
;;
|
||||||
|
@ -544,6 +550,7 @@ getMido() {
|
||||||
local id="$1"
|
local id="$1"
|
||||||
local lang="$2"
|
local lang="$2"
|
||||||
local ret="$3"
|
local ret="$3"
|
||||||
|
local url=""
|
||||||
local sum=""
|
local sum=""
|
||||||
local size=""
|
local size=""
|
||||||
|
|
||||||
|
@ -563,7 +570,7 @@ getMido() {
|
||||||
case "${ret,,}" in
|
case "${ret,,}" in
|
||||||
"sum" ) echo "$sum" ;;
|
"sum" ) echo "$sum" ;;
|
||||||
"size" ) echo "$size" ;;
|
"size" ) echo "$size" ;;
|
||||||
*) echo "";;
|
*) echo "$url";;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -585,19 +592,18 @@ getLink1() {
|
||||||
|
|
||||||
case "${id,,}" in
|
case "${id,,}" in
|
||||||
"win11arm64" | "win11arm64-enterprise" | "win11arm64-enterprise-eval" )
|
"win11arm64" | "win11arm64-enterprise" | "win11arm64-enterprise-eval" )
|
||||||
size=6326812672
|
size=5219411968
|
||||||
sum="464c75909b9c37864e144886445a2faa67ac86f0845a68cca3f017b97f810e8d"
|
sum="dbd54452c3c20b4625f511dae3c3e057270448fb661232d4fa66279f59a63157"
|
||||||
url="11/en-us_windows_11_23h2_arm64.iso"
|
url="11/en-us_windows_11_24h2_arm64.iso"
|
||||||
;;
|
;;
|
||||||
"win11arm64-ltsc" | "win11arm64-enterprise-ltsc-eval" )
|
"win11arm64-ltsc" | "win11arm64-enterprise-ltsc-eval" )
|
||||||
[[ "${lang,,}" != "en" ]] && [[ "${lang,,}" != "en-us" ]] && return 0
|
|
||||||
size=5121449984
|
size=5121449984
|
||||||
sum="f8f068cdc90c894a55d8c8530db7c193234ba57bb11d33b71383839ac41246b4"
|
sum="f8f068cdc90c894a55d8c8530db7c193234ba57bb11d33b71383839ac41246b4"
|
||||||
url="11/X23-81950_26100.1742.240906-0331.ge_release_svc_refresh_CLIENT_ENTERPRISES_OEM_A64FRE_en-us.iso"
|
url="11/X23-81950_26100.1742.240906-0331.ge_release_svc_refresh_CLIENT_ENTERPRISES_OEM_A64FRE_en-us.iso"
|
||||||
;;
|
;;
|
||||||
"win10arm64" | "win10arm64-enterprise" | "win10arm64-enterprise-eval" )
|
"win10arm64" | "win10arm64-enterprise" | "win10arm64-enterprise-eval" )
|
||||||
size=4846794752
|
size=4689637376
|
||||||
sum="6d2688f95fa1d359d68ed0c38c3f38de7b3713c893410e15be9d1e706a4a58c7"
|
sum="7b43e64f4e3b961a83f9b70efa4b9d863bc5c348fe86d75917ac974116d17227"
|
||||||
url="10/en-us_windows_10_22h2_arm64.iso"
|
url="10/en-us_windows_10_22h2_arm64.iso"
|
||||||
;;
|
;;
|
||||||
"win10arm64-ltsc" | "win10arm64-enterprise-ltsc-eval" )
|
"win10arm64-ltsc" | "win10arm64-enterprise-ltsc-eval" )
|
||||||
|
@ -639,6 +645,31 @@ getLink2() {
|
||||||
sum="812dae6b5bf5215db63b61ae10d8f0ffd3aa8529a18d96e9ced53341e2c676ec"
|
sum="812dae6b5bf5215db63b61ae10d8f0ffd3aa8529a18d96e9ced53341e2c676ec"
|
||||||
url="tiny11-core-arm64/tiny11%20core%20arm64.iso"
|
url="tiny11-core-arm64/tiny11%20core%20arm64.iso"
|
||||||
;;
|
;;
|
||||||
|
"win11arm64" )
|
||||||
|
size=5460387840
|
||||||
|
sum="57d1dfb2c6690a99fe99226540333c6c97d3fd2b557a50dfe3d68c3f675ef2b0"
|
||||||
|
url="windows-11-24h2-arm64-iso/Win11_24H2_English_Arm64.iso"
|
||||||
|
;;
|
||||||
|
"win11arm64-enterprise" | "win11arm64-enterprise-eval" )
|
||||||
|
size=6872444928
|
||||||
|
sum="2bf0fd1d5abd267cd0ae8066fea200b3538e60c3e572428c0ec86d4716b61cb7"
|
||||||
|
url="win11-23h2-en-fr/ARM64/SW_DVD9_Win_Pro_11_23H2_Arm64_English_Pro_Ent_EDU_N_MLF_X23-59519.ISO"
|
||||||
|
;;
|
||||||
|
"win11arm64-ltsc" | "win11arm64-enterprise-ltsc-eval" )
|
||||||
|
size=5121449984
|
||||||
|
sum="f8f068cdc90c894a55d8c8530db7c193234ba57bb11d33b71383839ac41246b4"
|
||||||
|
url="Windows11LTSC/X23-81950_26100.1742.240906-0331.ge_release_svc_refresh_CLIENT_ENTERPRISES_OEM_A64FRE_en-us.iso"
|
||||||
|
;;
|
||||||
|
"win10arm64" | "win10arm64-enterprise" | "win10arm64-enterprise-eval" )
|
||||||
|
size=5192060928
|
||||||
|
sum="101079b911c8c3dd9c9a88499a16b930fbf00cbaf901761d8265bb3a8fcd9ea9"
|
||||||
|
url="win-pro-10-22-h-2.15-arm-64-eng-intl-pro-ent-edu-n-mlf-x-23-67222/Win_Pro_10_22H2.15_Arm64_Eng_Intl_Pro_Ent_EDU_N_MLF_X23-67222.ISO"
|
||||||
|
;;
|
||||||
|
"win10arm64-ltsc" | "win10arm64-enterprise-ltsc-eval" )
|
||||||
|
size=4430471168
|
||||||
|
sum="d265df49b30a1477d010c79185a7bc88591a1be4b3eb690c994bed828ea17c00"
|
||||||
|
url="windows-10-enterprise-ltsc-full-collection/en-us_windows_10_iot_enterprise_ltsc_2021_arm64_dvd_e8d4fc46.iso"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case "${ret,,}" in
|
case "${ret,,}" in
|
||||||
|
@ -762,7 +793,7 @@ addFolder() {
|
||||||
cp -Lr "$folder/." "$dest" || return 1
|
cp -Lr "$folder/." "$dest" || return 1
|
||||||
|
|
||||||
local file
|
local file
|
||||||
file=$(find "$dest" -maxdepth 1 -type f -iname install.bat | head -n 1)
|
file=$(find "$dest" -maxdepth 1 -type f -iname install.bat -print -quit)
|
||||||
[ -f "$file" ] && unix2dos -q "$file"
|
[ -f "$file" ] && unix2dos -q "$file"
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
16
src/entry.sh
16
src/entry.sh
|
@ -1,16 +1,18 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
: "${APP:="Windows"}"
|
||||||
|
: "${MACHINE:="virt"}"
|
||||||
|
: "${PLATFORM:="arm64"}"
|
||||||
: "${BOOT_MODE:="windows"}"
|
: "${BOOT_MODE:="windows"}"
|
||||||
|
: "${SUPPORT:="https://github.com/dockur/windows-arm"}"
|
||||||
APP="Windows"
|
|
||||||
SUPPORT="https://github.com/dockur/windows-arm"
|
|
||||||
|
|
||||||
cd /run
|
cd /run
|
||||||
|
|
||||||
|
. utils.sh # Load functions
|
||||||
. reset.sh # Initialize system
|
. reset.sh # Initialize system
|
||||||
. define.sh # Define versions
|
. define.sh # Define versions
|
||||||
. mido.sh # Download code
|
. mido.sh # Download Windows
|
||||||
. install.sh # Run installation
|
. install.sh # Run installation
|
||||||
. disk.sh # Initialize disks
|
. disk.sh # Initialize disks
|
||||||
. display.sh # Initialize graphics
|
. display.sh # Initialize graphics
|
||||||
|
@ -37,8 +39,10 @@ fi
|
||||||
terminal
|
terminal
|
||||||
( sleep 30; boot ) &
|
( sleep 30; boot ) &
|
||||||
tail -fn +0 "$QEMU_LOG" 2>/dev/null &
|
tail -fn +0 "$QEMU_LOG" 2>/dev/null &
|
||||||
cat "$QEMU_TERM" 2> /dev/null | tee "$QEMU_PTY" &
|
cat "$QEMU_TERM" 2> /dev/null | tee "$QEMU_PTY" | \
|
||||||
wait $! || :
|
sed -u -e 's/\x1B\[[=0-9;]*[a-z]//gi' \
|
||||||
|
-e 's/failed to load Boot/skipped Boot/g' \
|
||||||
|
-e 's/0): Not Found/0)/g' & wait $! || :
|
||||||
|
|
||||||
sleep 1 & wait $!
|
sleep 1 & wait $!
|
||||||
[ ! -f "$QEMU_END" ] && finish 0
|
[ ! -f "$QEMU_END" ] && finish 0
|
||||||
|
|
230
src/install.sh
230
src/install.sh
|
@ -10,21 +10,31 @@ EFISYS="efi/microsoft/boot/efisys_noprompt.bin"
|
||||||
skipInstall() {
|
skipInstall() {
|
||||||
|
|
||||||
local iso="$1"
|
local iso="$1"
|
||||||
|
local method=""
|
||||||
local magic byte
|
local magic byte
|
||||||
local boot="$STORAGE/windows.boot"
|
local boot="$STORAGE/windows.boot"
|
||||||
local previous="$STORAGE/windows.base"
|
local previous="$STORAGE/windows.base"
|
||||||
|
|
||||||
if [ -f "$previous" ]; then
|
if [ -f "$previous" ]; then
|
||||||
previous=$(<"$previous")
|
previous=$(<"$previous")
|
||||||
|
previous="${previous//[![:print:]]/}"
|
||||||
if [ -n "$previous" ]; then
|
if [ -n "$previous" ]; then
|
||||||
previous="$STORAGE/$previous"
|
if [[ "${STORAGE,,}/${previous,,}" != "${iso,,}" ]]; then
|
||||||
if [[ "${previous,,}" != "${iso,,}" ]]; then
|
|
||||||
if [ -f "$boot" ] && hasDisk; then
|
if [ -f "$boot" ] && hasDisk; then
|
||||||
info "Detected that the version was changed, but ignoring this because Windows is already installed."
|
if [[ "${iso,,}" == "${STORAGE,,}/windows."* ]]; then
|
||||||
|
method="your custom .iso file"
|
||||||
|
else
|
||||||
|
if [[ "${previous,,}" != "windows."* ]]; then
|
||||||
|
method="the VERSION variable"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ -n "$method" ]; then
|
||||||
|
info "Detected that $method 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."
|
info "Please start with an empty /storage folder, if you want to install a different version of Windows."
|
||||||
|
fi
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
[ -f "$previous" ] && rm -f "$previous"
|
rm -f "$STORAGE/$previous"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -118,6 +128,8 @@ finishInstall() {
|
||||||
|
|
||||||
rm -f "$STORAGE/windows.old"
|
rm -f "$STORAGE/windows.old"
|
||||||
rm -f "$STORAGE/windows.vga"
|
rm -f "$STORAGE/windows.vga"
|
||||||
|
rm -f "$STORAGE/windows.net"
|
||||||
|
rm -f "$STORAGE/windows.usb"
|
||||||
rm -f "$STORAGE/windows.args"
|
rm -f "$STORAGE/windows.args"
|
||||||
rm -f "$STORAGE/windows.base"
|
rm -f "$STORAGE/windows.base"
|
||||||
rm -f "$STORAGE/windows.boot"
|
rm -f "$STORAGE/windows.boot"
|
||||||
|
@ -160,10 +172,22 @@ finishInstall() {
|
||||||
echo "$ARGS" > "$STORAGE/windows.args"
|
echo "$ARGS" > "$STORAGE/windows.args"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -n "${VGA:-}" ] && [[ "${VGA:-}" != "virtio"* ]]; then
|
||||||
|
echo "$VGA" > "$STORAGE/windows.vga"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${USB:-}" ] && [[ "${USB:-}" != "qemu-xhci"* ]]; then
|
||||||
|
echo "$USB" > "$STORAGE/windows.usb"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -n "${DISK_TYPE:-}" ] && [[ "${DISK_TYPE:-}" != "scsi" ]]; then
|
if [ -n "${DISK_TYPE:-}" ] && [[ "${DISK_TYPE:-}" != "scsi" ]]; then
|
||||||
echo "$DISK_TYPE" > "$STORAGE/windows.type"
|
echo "$DISK_TYPE" > "$STORAGE/windows.type"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -n "${ADAPTER:-}" ] && [[ "${ADAPTER:-}" != "virtio-net-pci" ]]; then
|
||||||
|
echo "$ADAPTER" > "$STORAGE/windows.net"
|
||||||
|
fi
|
||||||
|
|
||||||
rm -rf "$TMP"
|
rm -rf "$TMP"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -175,8 +199,9 @@ abortInstall() {
|
||||||
local efi
|
local efi
|
||||||
|
|
||||||
[[ "${iso,,}" == *".esd" ]] && exit 60
|
[[ "${iso,,}" == *".esd" ]] && exit 60
|
||||||
|
[[ "${UNPACK:-}" == [Yy1]* ]] && exit 60
|
||||||
|
|
||||||
efi=$(find "$dir" -maxdepth 1 -type d -iname efi | head -n 1)
|
efi=$(find "$dir" -maxdepth 1 -type d -iname efi -print -quit)
|
||||||
|
|
||||||
if [ -z "$efi" ]; then
|
if [ -z "$efi" ]; then
|
||||||
[[ "${PLATFORM,,}" == "x64" ]] && BOOT_MODE="windows_legacy"
|
[[ "${PLATFORM,,}" == "x64" ]] && BOOT_MODE="windows_legacy"
|
||||||
|
@ -197,13 +222,23 @@ abortInstall() {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
detectCustom() {
|
findFile() {
|
||||||
|
|
||||||
local file base
|
local dir file base
|
||||||
CUSTOM=""
|
local fname="$1"
|
||||||
|
local boot="$STORAGE/windows.boot"
|
||||||
|
|
||||||
file=$(find / -maxdepth 1 -type f -iname custom.iso | head -n 1)
|
dir=$(find / -maxdepth 1 -type d -iname "$fname" -print -quit)
|
||||||
[ ! -s "$file" ] && file=$(find "$STORAGE" -maxdepth 1 -type f -iname custom.iso | head -n 1)
|
[ ! -d "$dir" ] && dir=$(find "$STORAGE" -maxdepth 1 -type d -iname "$fname" -print -quit)
|
||||||
|
|
||||||
|
if [ -d "$dir" ]; then
|
||||||
|
if ! hasDisk || [ ! -f "$boot" ]; then
|
||||||
|
error "The bind $dir maps to a file that does not exist!" && return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
file=$(find / -maxdepth 1 -type f -iname "$fname" -print -quit)
|
||||||
|
[ ! -s "$file" ] && file=$(find "$STORAGE" -maxdepth 1 -type f -iname "$fname" -print -quit)
|
||||||
|
|
||||||
if [ ! -s "$file" ] && [[ "${VERSION,,}" != "http"* ]]; then
|
if [ ! -s "$file" ] && [[ "${VERSION,,}" != "http"* ]]; then
|
||||||
base=$(basename "$VERSION")
|
base=$(basename "$VERSION")
|
||||||
|
@ -219,12 +254,25 @@ detectCustom() {
|
||||||
[ -z "$size" ] || [[ "$size" == "0" ]] && return 0
|
[ -z "$size" ] || [[ "$size" == "0" ]] && return 0
|
||||||
|
|
||||||
ISO="$file"
|
ISO="$file"
|
||||||
CUSTOM="$ISO"
|
CUSTOM="$file"
|
||||||
BOOT="$STORAGE/windows.$size.iso"
|
BOOT="$STORAGE/windows.$size.iso"
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
detectCustom() {
|
||||||
|
|
||||||
|
CUSTOM=""
|
||||||
|
|
||||||
|
! findFile "custom.iso" && return 1
|
||||||
|
[ -n "$CUSTOM" ] && return 0
|
||||||
|
|
||||||
|
! findFile "boot.iso" && return 1
|
||||||
|
[ -n "$CUSTOM" ] && return 0
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
extractESD() {
|
extractESD() {
|
||||||
|
|
||||||
local iso="$1"
|
local iso="$1"
|
||||||
|
@ -244,12 +292,12 @@ extractESD() {
|
||||||
mkdir -p "$dir"
|
mkdir -p "$dir"
|
||||||
|
|
||||||
size=16106127360
|
size=16106127360
|
||||||
size_gb=$(( (size + 1073741823)/1073741824 ))
|
size_gb=$(formatBytes "$size")
|
||||||
space=$(df --output=avail -B 1 "$dir" | tail -n 1)
|
space=$(df --output=avail -B 1 "$dir" | tail -n 1)
|
||||||
space_gb=$(( (space + 1073741823)/1073741824 ))
|
space_gb=$(formatBytes "$space")
|
||||||
|
|
||||||
if (( size > space )); then
|
if (( size > space )); then
|
||||||
error "Not enough free space in $STORAGE, have $space_gb GB available but need at least $size_gb GB." && return 1
|
error "Not enough free space in $STORAGE, have $space_gb available but need at least $size_gb." && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local esdImageCount
|
local esdImageCount
|
||||||
|
@ -314,7 +362,7 @@ extractImage() {
|
||||||
local dir="$2"
|
local dir="$2"
|
||||||
local version="$3"
|
local version="$3"
|
||||||
local desc="local ISO"
|
local desc="local ISO"
|
||||||
local size size_gb space space_gb
|
local file size size_gb space space_gb
|
||||||
|
|
||||||
if [ -z "$CUSTOM" ]; then
|
if [ -z "$CUSTOM" ]; then
|
||||||
desc="downloaded ISO"
|
desc="downloaded ISO"
|
||||||
|
@ -335,16 +383,16 @@ extractImage() {
|
||||||
mkdir -p "$dir"
|
mkdir -p "$dir"
|
||||||
|
|
||||||
size=$(stat -c%s "$iso")
|
size=$(stat -c%s "$iso")
|
||||||
size_gb=$(( (size + 1073741823)/1073741824 ))
|
size_gb=$(formatBytes "$size")
|
||||||
space=$(df --output=avail -B 1 "$dir" | tail -n 1)
|
space=$(df --output=avail -B 1 "$dir" | tail -n 1)
|
||||||
space_gb=$(( (space + 1073741823)/1073741824 ))
|
space_gb=$(formatBytes "$space")
|
||||||
|
|
||||||
if ((size<100000000)); then
|
if ((size<100000000)); then
|
||||||
error "Invalid ISO file: Size is smaller than 100 MB" && return 1
|
error "Invalid ISO file: Size is smaller than 100 MB" && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if (( size > space )); then
|
if (( size > space )); then
|
||||||
error "Not enough free space in $STORAGE, have $space_gb GB available but need at least $size_gb GB." && return 1
|
error "Not enough free space in $STORAGE, have $space_gb available but need at least $size_gb." && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -rf "$dir"
|
rm -rf "$dir"
|
||||||
|
@ -353,8 +401,27 @@ extractImage() {
|
||||||
error "Failed to extract ISO file: $iso" && return 1
|
error "Failed to extract ISO file: $iso" && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "${UNPACK:-}" != [Yy1]* ]]; then
|
||||||
|
|
||||||
LABEL=$(isoinfo -d -i "$iso" | sed -n 's/Volume id: //p')
|
LABEL=$(isoinfo -d -i "$iso" | sed -n 's/Volume id: //p')
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
file=$(find "$dir" -maxdepth 1 -type f -iname "*.iso" -print -quit)
|
||||||
|
|
||||||
|
if [ -z "$file" ]; then
|
||||||
|
error "Failed to find any .iso file in archive!" && return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! 7z x "$file" -o"$dir" > /dev/null; then
|
||||||
|
error "Failed to extract archive!" && return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
LABEL=$(isoinfo -d -i "$file" | sed -n 's/Volume id: //p')
|
||||||
|
rm -f "$file"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,6 +554,10 @@ setXML() {
|
||||||
|
|
||||||
local file="/custom.xml"
|
local file="/custom.xml"
|
||||||
|
|
||||||
|
if [ -d "$file" ]; then
|
||||||
|
error "The bind $file maps to a file that does not exist!" && exit 67
|
||||||
|
fi
|
||||||
|
|
||||||
[ ! -f "$file" ] || [ ! -s "$file" ] && file="$STORAGE/custom.xml"
|
[ ! -f "$file" ] || [ ! -s "$file" ] && file="$STORAGE/custom.xml"
|
||||||
[ ! -f "$file" ] || [ ! -s "$file" ] && file="/run/assets/custom.xml"
|
[ ! -f "$file" ] || [ ! -s "$file" ] && file="/run/assets/custom.xml"
|
||||||
[ ! -f "$file" ] || [ ! -s "$file" ] && file="$1"
|
[ ! -f "$file" ] || [ ! -s "$file" ] && file="$1"
|
||||||
|
@ -531,14 +602,14 @@ detectImage() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local src wim info
|
local src wim info
|
||||||
src=$(find "$dir" -maxdepth 1 -type d -iname sources | head -n 1)
|
src=$(find "$dir" -maxdepth 1 -type d -iname sources -print -quit)
|
||||||
|
|
||||||
if [ ! -d "$src" ]; then
|
if [ ! -d "$src" ]; then
|
||||||
warn "failed to locate 'sources' folder in ISO image, $FB" && return 1
|
warn "failed to locate 'sources' folder in ISO image, $FB" && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
wim=$(find "$src" -maxdepth 1 -type f -iname install.wim | head -n 1)
|
wim=$(find "$src" -maxdepth 1 -type f -iname install.wim -print -quit)
|
||||||
[ ! -f "$wim" ] && wim=$(find "$src" -maxdepth 1 -type f -iname install.esd | head -n 1)
|
[ ! -f "$wim" ] && wim=$(find "$src" -maxdepth 1 -type f -iname install.esd -print -quit)
|
||||||
|
|
||||||
if [ ! -f "$wim" ]; then
|
if [ ! -f "$wim" ]; then
|
||||||
warn "failed to locate 'install.wim' or 'install.esd' in ISO image, $FB" && return 1
|
warn "failed to locate 'install.wim' or 'install.esd' in ISO image, $FB" && return 1
|
||||||
|
@ -571,6 +642,10 @@ detectImage() {
|
||||||
info "Detected: $desc"
|
info "Detected: $desc"
|
||||||
setXML "" && return 0
|
setXML "" && return 0
|
||||||
|
|
||||||
|
if [[ "$DETECTED" == "win81x86"* ]] || [[ "$DETECTED" == "win10x86"* ]]; then
|
||||||
|
error "The 32-bit version of $desc is not supported!" && return 1
|
||||||
|
fi
|
||||||
|
|
||||||
msg="the answer file for $desc was not found ($DETECTED.xml)"
|
msg="the answer file for $desc was not found ($DETECTED.xml)"
|
||||||
local fallback="/run/assets/${DETECTED%%-*}.xml"
|
local fallback="/run/assets/${DETECTED%%-*}.xml"
|
||||||
|
|
||||||
|
@ -618,6 +693,10 @@ updateXML() {
|
||||||
local language="$2"
|
local language="$2"
|
||||||
local culture region user admin pass keyboard
|
local culture region user admin pass keyboard
|
||||||
|
|
||||||
|
if [ -n "${VM_NET_IP:-}" ]; then
|
||||||
|
sed -i "s/ 20.20.20.1 / ${VM_NET_IP%.*}.1 /g" "$asset"
|
||||||
|
fi
|
||||||
|
|
||||||
[ -z "$HEIGHT" ] && HEIGHT="720"
|
[ -z "$HEIGHT" ] && HEIGHT="720"
|
||||||
[ -z "$WIDTH" ] && WIDTH="1280"
|
[ -z "$WIDTH" ] && WIDTH="1280"
|
||||||
|
|
||||||
|
@ -655,22 +734,28 @@ updateXML() {
|
||||||
sed -i "s/<Username>Docker<\/Username>/<Username>$user<\/Username>/g" "$asset"
|
sed -i "s/<Username>Docker<\/Username>/<Username>$user<\/Username>/g" "$asset"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$PASSWORD" ]; then
|
[ -n "$PASSWORD" ] && pass="$PASSWORD" || pass="admin"
|
||||||
pass=$(printf '%s' "${PASSWORD}Password" | iconv -f utf-8 -t utf-16le | base64 -w 0)
|
|
||||||
admin=$(printf '%s' "${PASSWORD}AdministratorPassword" | iconv -f utf-8 -t utf-16le | base64 -w 0)
|
pw=$(printf '%s' "${pass}Password" | iconv -f utf-8 -t utf-16le | base64 -w 0)
|
||||||
|
admin=$(printf '%s' "${pass}AdministratorPassword" | iconv -f utf-8 -t utf-16le | base64 -w 0)
|
||||||
|
|
||||||
sed -i "s/<Value>password<\/Value>/<Value>$admin<\/Value>/g" "$asset"
|
sed -i "s/<Value>password<\/Value>/<Value>$admin<\/Value>/g" "$asset"
|
||||||
sed -i "s/<PlainText>true<\/PlainText>/<PlainText>false<\/PlainText>/g" "$asset"
|
sed -i "s/<PlainText>true<\/PlainText>/<PlainText>false<\/PlainText>/g" "$asset"
|
||||||
sed -z "s/<Password>...........<Value \/>/<Password>\n <Value>$pass<\/Value>/g" -i "$asset"
|
sed -z "s/<Password>...........<Value \/>/<Password>\n <Value>$pw<\/Value>/g" -i "$asset"
|
||||||
sed -z "s/<Password>...............<Value \/>/<Password>\n <Value>$pass<\/Value>/g" -i "$asset"
|
sed -z "s/<Password>...............<Value \/>/<Password>\n <Value>$pw<\/Value>/g" -i "$asset"
|
||||||
sed -z "s/<AdministratorPassword>...........<Value \/>/<AdministratorPassword>\n <Value>$admin<\/Value>/g" -i "$asset"
|
sed -z "s/<AdministratorPassword>...........<Value \/>/<AdministratorPassword>\n <Value>$admin<\/Value>/g" -i "$asset"
|
||||||
sed -z "s/<AdministratorPassword>...............<Value \/>/<AdministratorPassword>\n <Value>$admin<\/Value>/g" -i "$asset"
|
sed -z "s/<AdministratorPassword>...............<Value \/>/<AdministratorPassword>\n <Value>$admin<\/Value>/g" -i "$asset"
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$EDITION" ]; then
|
if [ -n "$EDITION" ]; then
|
||||||
[[ "${EDITION^^}" == "CORE" ]] && EDITION="STANDARDCORE"
|
[[ "${EDITION^^}" == "CORE" ]] && EDITION="STANDARDCORE"
|
||||||
sed -i "s/SERVERSTANDARD<\/Value>/SERVER${EDITION^^}<\/Value>/g" "$asset"
|
sed -i "s/SERVERSTANDARD<\/Value>/SERVER${EDITION^^}<\/Value>/g" "$asset"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -n "$KEY" ]; then
|
||||||
|
sed -i '/<ProductKey>/,/<\/ProductKey>/d' "$asset"
|
||||||
|
sed -i "s/<\/UserData>/ <ProductKey>\n <Key>${KEY}<\/Key>\n <WillShowUI>OnError<\/WillShowUI>\n <\/ProductKey>\n <\/UserData>/g" "$asset"
|
||||||
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,7 +792,11 @@ addDriver() {
|
||||||
|
|
||||||
if [ -z "$folder" ]; then
|
if [ -z "$folder" ]; then
|
||||||
desc=$(printVersion "$id" "$id")
|
desc=$(printVersion "$id" "$id")
|
||||||
|
if [[ "${id,,}" != *"x86"* ]]; then
|
||||||
warn "no \"$driver\" driver available for \"$desc\" !" && return 0
|
warn "no \"$driver\" driver available for \"$desc\" !" && return 0
|
||||||
|
else
|
||||||
|
warn "no \"$driver\" driver available for the 32-bit version of \"$desc\" !" && return 0
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[ ! -d "$path/$driver/$folder" ] && return 0
|
[ ! -d "$path/$driver/$folder" ] && return 0
|
||||||
|
@ -745,7 +834,7 @@ addDrivers() {
|
||||||
warn "Windows version unknown, falling back to Windows 11 drivers..."
|
warn "Windows version unknown, falling back to Windows 11 drivers..."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! bsdtar -xf /drivers.txz -C "$drivers"; then
|
if ! bsdtar -xf /var/drivers.txz -C "$drivers"; then
|
||||||
error "Failed to extract drivers from archive!" && return 1
|
error "Failed to extract drivers from archive!" && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -758,7 +847,7 @@ addDrivers() {
|
||||||
addDriver "$version" "$drivers" "$target" "qxl" || return 1
|
addDriver "$version" "$drivers" "$target" "qxl" || return 1
|
||||||
addDriver "$version" "$drivers" "$target" "viofs" || return 1
|
addDriver "$version" "$drivers" "$target" "viofs" || return 1
|
||||||
addDriver "$version" "$drivers" "$target" "sriov" || return 1
|
addDriver "$version" "$drivers" "$target" "sriov" || return 1
|
||||||
# Disable temporarily : addDriver "$version" "$drivers" "$target" "smbus" || return 1
|
addDriver "$version" "$drivers" "$target" "smbus" || return 1
|
||||||
addDriver "$version" "$drivers" "$target" "qxldod" || return 1
|
addDriver "$version" "$drivers" "$target" "qxldod" || return 1
|
||||||
addDriver "$version" "$drivers" "$target" "viorng" || return 1
|
addDriver "$version" "$drivers" "$target" "viorng" || return 1
|
||||||
addDriver "$version" "$drivers" "$target" "viostor" || return 1
|
addDriver "$version" "$drivers" "$target" "viostor" || return 1
|
||||||
|
@ -766,7 +855,7 @@ addDrivers() {
|
||||||
addDriver "$version" "$drivers" "$target" "NetKVM" || return 1
|
addDriver "$version" "$drivers" "$target" "NetKVM" || return 1
|
||||||
addDriver "$version" "$drivers" "$target" "Balloon" || return 1
|
addDriver "$version" "$drivers" "$target" "Balloon" || return 1
|
||||||
addDriver "$version" "$drivers" "$target" "vioscsi" || return 1
|
addDriver "$version" "$drivers" "$target" "vioscsi" || return 1
|
||||||
# Disable temporarily : addDriver "$version" "$drivers" "$target" "pvpanic" || return 1
|
addDriver "$version" "$drivers" "$target" "pvpanic" || return 1
|
||||||
addDriver "$version" "$drivers" "$target" "vioinput" || return 1
|
addDriver "$version" "$drivers" "$target" "vioinput" || return 1
|
||||||
addDriver "$version" "$drivers" "$target" "viogpudo" || return 1
|
addDriver "$version" "$drivers" "$target" "viogpudo" || return 1
|
||||||
addDriver "$version" "$drivers" "$target" "vioserial" || return 1
|
addDriver "$version" "$drivers" "$target" "vioserial" || return 1
|
||||||
|
@ -814,14 +903,14 @@ updateImage() {
|
||||||
rm -rf "$tmp"
|
rm -rf "$tmp"
|
||||||
mkdir -p "$tmp"
|
mkdir -p "$tmp"
|
||||||
|
|
||||||
src=$(find "$dir" -maxdepth 1 -type d -iname sources | head -n 1)
|
src=$(find "$dir" -maxdepth 1 -type d -iname sources -print -quit)
|
||||||
|
|
||||||
if [ ! -d "$src" ]; then
|
if [ ! -d "$src" ]; then
|
||||||
error "failed to locate 'sources' folder in ISO image, $FB" && return 1
|
error "failed to locate 'sources' folder in ISO image, $FB" && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
wim=$(find "$src" -maxdepth 1 -type f -iname boot.wim | head -n 1)
|
wim=$(find "$src" -maxdepth 1 -type f -iname boot.wim -print -quit)
|
||||||
[ ! -f "$wim" ] && wim=$(find "$src" -maxdepth 1 -type f -iname boot.esd | head -n 1)
|
[ ! -f "$wim" ] && wim=$(find "$src" -maxdepth 1 -type f -iname boot.esd -print -quit)
|
||||||
|
|
||||||
if [ ! -f "$wim" ]; then
|
if [ ! -f "$wim" ]; then
|
||||||
error "failed to locate 'boot.wim' or 'boot.esd' in ISO image, $FB" && return 1
|
error "failed to locate 'boot.wim' or 'boot.esd' in ISO image, $FB" && return 1
|
||||||
|
@ -884,7 +973,7 @@ updateImage() {
|
||||||
|
|
||||||
local find="$file"
|
local find="$file"
|
||||||
[[ "$MANUAL" == [Yy1]* ]] && find="$org"
|
[[ "$MANUAL" == [Yy1]* ]] && find="$org"
|
||||||
path=$(find "$dir" -maxdepth 1 -type f -iname "$find" | head -n 1)
|
path=$(find "$dir" -maxdepth 1 -type f -iname "$find" -print -quit)
|
||||||
|
|
||||||
if [ -f "$path" ]; then
|
if [ -f "$path" ]; then
|
||||||
if [[ "$MANUAL" != [Yy1]* ]]; then
|
if [[ "$MANUAL" != [Yy1]* ]]; then
|
||||||
|
@ -938,12 +1027,12 @@ buildImage() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
size=$(du -h -b --max-depth=0 "$dir" | cut -f1)
|
size=$(du -h -b --max-depth=0 "$dir" | cut -f1)
|
||||||
size_gb=$(( (size + 1073741823)/1073741824 ))
|
size_gb=$(formatBytes "$size")
|
||||||
space=$(df --output=avail -B 1 "$TMP" | tail -n 1)
|
space=$(df --output=avail -B 1 "$TMP" | tail -n 1)
|
||||||
space_gb=$(( (space + 1073741823)/1073741824 ))
|
space_gb=$(formatBytes "$space")
|
||||||
|
|
||||||
if (( size > space )); then
|
if (( size > space )); then
|
||||||
error "Not enough free space in $STORAGE, have $space_gb GB available but need at least $size_gb GB." && return 1
|
error "Not enough free space in $STORAGE, have $space_gb available but need at least $size_gb." && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "${BOOT_MODE,,}" != "windows_legacy" ]]; then
|
if [[ "${BOOT_MODE,,}" != "windows_legacy" ]]; then
|
||||||
|
@ -987,52 +1076,47 @@ bootWindows() {
|
||||||
|
|
||||||
if [ -f "$STORAGE/windows.args" ]; then
|
if [ -f "$STORAGE/windows.args" ]; then
|
||||||
ARGS=$(<"$STORAGE/windows.args")
|
ARGS=$(<"$STORAGE/windows.args")
|
||||||
|
ARGS="${ARGS//[![:print:]]/}"
|
||||||
ARGUMENTS="$ARGS ${ARGUMENTS:-}"
|
ARGUMENTS="$ARGS ${ARGUMENTS:-}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -s "$STORAGE/windows.vga" ] && [ -f "$STORAGE/windows.vga" ]; then
|
||||||
|
if [ -z "${VGA:-}" ]; then
|
||||||
|
VGA=$(<"$STORAGE/windows.vga")
|
||||||
|
VGA="${VGA//[![:print:]]/}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -s "$STORAGE/windows.usb" ] && [ -f "$STORAGE/windows.usb" ]; then
|
||||||
|
if [ -z "${USB:-}" ]; then
|
||||||
|
USB=$(<"$STORAGE/windows.usb")
|
||||||
|
USB="${USB//[![:print:]]/}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -s "$STORAGE/windows.net" ] && [ -f "$STORAGE/windows.net" ]; then
|
||||||
|
if [ -z "${ADAPTER:-}" ]; then
|
||||||
|
ADAPTER=$(<"$STORAGE/windows.net")
|
||||||
|
ADAPTER="${ADAPTER//[![:print:]]/}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -s "$STORAGE/windows.type" ] && [ -f "$STORAGE/windows.type" ]; then
|
if [ -s "$STORAGE/windows.type" ] && [ -f "$STORAGE/windows.type" ]; then
|
||||||
[ -z "${DISK_TYPE:-}" ] && DISK_TYPE=$(<"$STORAGE/windows.type")
|
if [ -z "${DISK_TYPE:-}" ]; then
|
||||||
|
DISK_TYPE=$(<"$STORAGE/windows.type")
|
||||||
|
DISK_TYPE="${DISK_TYPE//[![:print:]]/}"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -s "$STORAGE/windows.mode" ] && [ -f "$STORAGE/windows.mode" ]; then
|
if [ -s "$STORAGE/windows.mode" ] && [ -f "$STORAGE/windows.mode" ]; then
|
||||||
BOOT_MODE=$(<"$STORAGE/windows.mode")
|
BOOT_MODE=$(<"$STORAGE/windows.mode")
|
||||||
|
BOOT_MODE="${BOOT_MODE//[![:print:]]/}"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -s "$STORAGE/windows.old" ] && [ -f "$STORAGE/windows.old" ]; then
|
if [ -s "$STORAGE/windows.old" ] && [ -f "$STORAGE/windows.old" ]; then
|
||||||
[[ "${PLATFORM,,}" == "x64" ]] && MACHINE=$(<"$STORAGE/windows.old")
|
if [[ "${PLATFORM,,}" == "x64" ]]; then
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Migrations
|
|
||||||
|
|
||||||
[[ "${PLATFORM,,}" != "x64" ]] && return 0
|
|
||||||
|
|
||||||
if [ -f "$STORAGE/windows.old" ]; then
|
|
||||||
MACHINE=$(<"$STORAGE/windows.old")
|
MACHINE=$(<"$STORAGE/windows.old")
|
||||||
[ -z "$MACHINE" ] && MACHINE="q35"
|
MACHINE="${MACHINE//[![:print:]]/}"
|
||||||
BOOT_MODE="windows_legacy"
|
|
||||||
echo "$BOOT_MODE" > "$STORAGE/windows.mode"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
local creation="1.10"
|
|
||||||
local minimal="2.14"
|
|
||||||
|
|
||||||
if [ -f "$STORAGE/windows.ver" ]; then
|
|
||||||
creation=$(<"$STORAGE/windows.ver")
|
|
||||||
[[ "${creation}" != *"."* ]] && creation="$minimal"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Force secure boot on installs created prior to v2.14
|
|
||||||
if (( $(echo "$creation < $minimal" | bc -l) )); then
|
|
||||||
if [[ "${BOOT_MODE,,}" == "windows" ]]; then
|
|
||||||
BOOT_MODE="windows_secure"
|
|
||||||
echo "$BOOT_MODE" > "$STORAGE/windows.mode"
|
|
||||||
if [ -f "$STORAGE/windows.rom" ] && [ ! -f "$STORAGE/$BOOT_MODE.rom" ]; then
|
|
||||||
mv -f "$STORAGE/windows.rom" "$STORAGE/$BOOT_MODE.rom"
|
|
||||||
fi
|
|
||||||
if [ -f "$STORAGE/windows.vars" ] && [ ! -f "$STORAGE/$BOOT_MODE.vars" ]; then
|
|
||||||
mv -f "$STORAGE/windows.vars" "$STORAGE/$BOOT_MODE.vars"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
93
src/mido.sh
93
src/mido.sh
|
@ -93,6 +93,7 @@ download_windows() {
|
||||||
|
|
||||||
# uuidgen: For MacOS (installed by default) and other systems (e.g. with no /proc) that don't have a kernel interface for generating random UUIDs
|
# uuidgen: For MacOS (installed by default) and other systems (e.g. with no /proc) that don't have a kernel interface for generating random UUIDs
|
||||||
session_id=$(cat /proc/sys/kernel/random/uuid 2> /dev/null || uuidgen --random)
|
session_id=$(cat /proc/sys/kernel/random/uuid 2> /dev/null || uuidgen --random)
|
||||||
|
session_id="${session_id//[![:print:]]/}"
|
||||||
|
|
||||||
# Get product edition ID for latest release of given Windows version
|
# Get product edition ID for latest release of given Windows version
|
||||||
# Product edition ID: This specifies both the Windows release (e.g. 22H2) and edition ("multi-edition" is default, either Home/Pro/Edu/etc., we select "Pro" in the answer files) in one number
|
# Product edition ID: This specifies both the Windows release (e.g. 22H2) and edition ("multi-edition" is default, either Home/Pro/Edu/etc., we select "Pro" in the answer files) in one number
|
||||||
|
@ -208,6 +209,9 @@ download_windows_eval() {
|
||||||
"win2022-eval" )
|
"win2022-eval" )
|
||||||
enterprise_type="server"
|
enterprise_type="server"
|
||||||
windows_version="windows-server-2022" ;;
|
windows_version="windows-server-2022" ;;
|
||||||
|
"win2019-hv" )
|
||||||
|
enterprise_type="server"
|
||||||
|
windows_version="hyper-v-server-2019" ;;
|
||||||
"win2019-eval" )
|
"win2019-eval" )
|
||||||
enterprise_type="server"
|
enterprise_type="server"
|
||||||
windows_version="windows-server-2019" ;;
|
windows_version="windows-server-2019" ;;
|
||||||
|
@ -310,7 +314,7 @@ getWindows() {
|
||||||
info "$msg" && html "$msg"
|
info "$msg" && html "$msg"
|
||||||
|
|
||||||
case "${version,,}" in
|
case "${version,,}" in
|
||||||
"win2008r2" | "win81${PLATFORM,,}-enterprise"* | "win11${PLATFORM,,}-enterprise-iot"* | "win11${PLATFORM,,}-enterprise-ltsc"* )
|
"win2008r2" | "win81${PLATFORM,,}"* | "win11${PLATFORM,,}-enterprise-iot"* | "win11${PLATFORM,,}-enterprise-ltsc"* )
|
||||||
if [[ "${lang,,}" != "en" ]] && [[ "${lang,,}" != "en-"* ]]; then
|
if [[ "${lang,,}" != "en" ]] && [[ "${lang,,}" != "en-"* ]]; then
|
||||||
error "No download in the $language language available for $edition!"
|
error "No download in the $language language available for $edition!"
|
||||||
MIDO_URL="" && return 1
|
MIDO_URL="" && return 1
|
||||||
|
@ -335,7 +339,7 @@ getWindows() {
|
||||||
"win11${PLATFORM,,}-enterprise"* | "win10${PLATFORM,,}-enterprise"* )
|
"win11${PLATFORM,,}-enterprise"* | "win10${PLATFORM,,}-enterprise"* )
|
||||||
download_windows_eval "$version" "$lang" "$edition" && return 0
|
download_windows_eval "$version" "$lang" "$edition" && return 0
|
||||||
;;
|
;;
|
||||||
"win2025-eval" | "win2022-eval" | "win2019-eval" | "win2016-eval" | "win2012r2-eval" )
|
"win2025-eval" | "win2022-eval" | "win2019-eval" | "win2019-hv" | "win2016-eval" | "win2012r2-eval" )
|
||||||
download_windows_eval "$version" "$lang" "$edition" && return 0
|
download_windows_eval "$version" "$lang" "$edition" && return 0
|
||||||
;;
|
;;
|
||||||
"win81${PLATFORM,,}-enterprise"* | "win2008r2" )
|
"win81${PLATFORM,,}-enterprise"* | "win2008r2" )
|
||||||
|
@ -343,53 +347,10 @@ getWindows() {
|
||||||
* ) error "Invalid VERSION specified, value \"$version\" is not recognized!" ;;
|
* ) error "Invalid VERSION specified, value \"$version\" is not recognized!" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [[ "${PLATFORM,,}" != "x64" ]]; then
|
MIDO_URL=$(getMido "$version" "$lang" "")
|
||||||
MIDO_URL=""
|
[ -z "$MIDO_URL" ] && return 1
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${lang,,}" != "en" ]] && [[ "${lang,,}" != "en-"* ]]; then
|
|
||||||
MIDO_URL=""
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "${version,,}" in
|
|
||||||
"win81${PLATFORM,,}-enterprise"* )
|
|
||||||
MIDO_URL="https://download.microsoft.com/download/B/9/9/B999286E-0A47-406D-8B3D-5B5AD7373A4A/9600.17050.WINBLUE_REFRESH.140317-1640_X64FRE_ENTERPRISE_EVAL_EN-US-IR3_CENA_X64FREE_EN-US_DV9.ISO"
|
|
||||||
return 0
|
return 0
|
||||||
;;
|
|
||||||
"win11${PLATFORM,,}-enterprise-iot"* | "win11${PLATFORM,,}-enterprise-ltsc"* )
|
|
||||||
MIDO_URL="https://software-static.download.prss.microsoft.com/dbazure/888969d5-f34g-4e03-ac9d-1f9786c66749/26100.1.240331-1435.ge_release_CLIENT_IOT_LTSC_EVAL_x64FRE_en-us.iso"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"win2025-eval" )
|
|
||||||
MIDO_URL="https://software-static.download.prss.microsoft.com/dbazure/888969d5-f34g-4e03-ac9d-1f9786c66749/26100.1.240331-1435.ge_release_SERVER_EVAL_x64FRE_en-us.iso"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"win2022-eval" )
|
|
||||||
MIDO_URL="https://software-static.download.prss.microsoft.com/sg/download/888969d5-f34g-4e03-ac9d-1f9786c66749/SERVER_EVAL_x64FRE_en-us.iso"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"win2019-eval" )
|
|
||||||
MIDO_URL="https://software-download.microsoft.com/download/pr/17763.737.190906-2324.rs5_release_svc_refresh_SERVER_EVAL_x64FRE_en-us_1.iso"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"win2016-eval" )
|
|
||||||
MIDO_URL="https://software-download.microsoft.com/download/pr/Windows_Server_2016_Datacenter_EVAL_en-us_14393_refresh.ISO"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"win2012r2-eval" )
|
|
||||||
MIDO_URL="https://download.microsoft.com/download/6/2/A/62A76ABB-9990-4EFC-A4FE-C7D698DAEB96/9600.17050.WINBLUE_REFRESH.140317-1640_X64FRE_SERVER_EVAL_EN-US-IR3_SSS_X64FREE_EN-US_DV9.ISO"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"win2008r2" )
|
|
||||||
MIDO_URL="https://download.microsoft.com/download/4/1/D/41DEA7E0-B30D-4012-A1E3-F24DC03BA1BB/7601.17514.101119-1850_x64fre_server_eval_en-us-GRMSXEVAL_EN_DVD.iso"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
MIDO_URL=""
|
|
||||||
return 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCatalog() {
|
getCatalog() {
|
||||||
|
@ -511,6 +472,18 @@ getESD() {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isCompressed() {
|
||||||
|
|
||||||
|
local file="$1"
|
||||||
|
|
||||||
|
case "${file,,}" in
|
||||||
|
*".7z" | *".zip" | *".rar" | *".lzma" | *".bz" | *".bz2" )
|
||||||
|
return 0 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
verifyFile() {
|
verifyFile() {
|
||||||
|
|
||||||
local iso="$1"
|
local iso="$1"
|
||||||
|
@ -519,7 +492,9 @@ verifyFile() {
|
||||||
local check="$4"
|
local check="$4"
|
||||||
|
|
||||||
if [ -n "$size" ] && [[ "$total" != "$size" ]] && [[ "$size" != "0" ]]; then
|
if [ -n "$size" ] && [[ "$total" != "$size" ]] && [[ "$size" != "0" ]]; then
|
||||||
warn "The downloaded file has an unexpected size: $total bytes, while expected value was: $size bytes. Please report this at $SUPPORT/issues"
|
if [[ "$VERIFY" == [Yy1]* ]] || [[ "$DEBUG" == [Yy1]* ]]; then
|
||||||
|
warn "The downloaded file has a different size ( $total bytes) than expected ( $size bytes). Please report this at $SUPPORT/issues"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local hash=""
|
local hash=""
|
||||||
|
@ -542,7 +517,7 @@ verifyFile() {
|
||||||
info "Succesfully verified ISO!" && return 0
|
info "Succesfully verified ISO!" && return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
error "The downloaded file has an invalid $algo checksum: $hash , while expected value was: $check. Please report this at $SUPPORT/issues"
|
error "The downloaded file has an unknown $algo checksum: $hash , as the expected value was: $check. Please report this at $SUPPORT/issues"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,14 +529,17 @@ downloadFile() {
|
||||||
local size="$4"
|
local size="$4"
|
||||||
local lang="$5"
|
local lang="$5"
|
||||||
local desc="$6"
|
local desc="$6"
|
||||||
local rc total progress domain dots space folder
|
local msg="Downloading $desc"
|
||||||
|
local rc total total_gb progress domain dots agent space folder
|
||||||
|
|
||||||
rm -f "$iso"
|
rm -f "$iso"
|
||||||
|
agent=$(get_agent)
|
||||||
|
|
||||||
if [ -n "$size" ] && [[ "$size" != "0" ]]; then
|
if [ -n "$size" ] && [[ "$size" != "0" ]]; then
|
||||||
folder=$(dirname -- "$iso")
|
folder=$(dirname -- "$iso")
|
||||||
space=$(df --output=avail -B 1 "$folder" | tail -n 1)
|
space=$(df --output=avail -B 1 "$folder" | tail -n 1)
|
||||||
(( size > space )) && error "Not enough free space left to download file!" && return 1
|
total_gb=$(formatBytes "$space")
|
||||||
|
(( size > space )) && error "Not enough free space to download file, only $total_gb left!" && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if running with interactive TTY or redirected to docker log
|
# Check if running with interactive TTY or redirected to docker log
|
||||||
|
@ -571,8 +549,8 @@ downloadFile() {
|
||||||
progress="--progress=dot:giga"
|
progress="--progress=dot:giga"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local msg="Downloading $desc"
|
|
||||||
html "$msg..."
|
html "$msg..."
|
||||||
|
/run/progress.sh "$iso" "$size" "$msg ([P])..." &
|
||||||
|
|
||||||
domain=$(echo "$url" | awk -F/ '{print $3}')
|
domain=$(echo "$url" | awk -F/ '{print $3}')
|
||||||
dots=$(echo "$domain" | tr -cd '.' | wc -c)
|
dots=$(echo "$domain" | tr -cd '.' | wc -c)
|
||||||
|
@ -583,25 +561,26 @@ downloadFile() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
info "$msg..."
|
info "$msg..."
|
||||||
/run/progress.sh "$iso" "$size" "$msg ([P])..." &
|
|
||||||
|
|
||||||
{ wget "$url" -O "$iso" -q --timeout=30 --no-http-keep-alive --show-progress "$progress"; rc=$?; } || :
|
{ wget "$url" -O "$iso" -q --timeout=30 --no-http-keep-alive --user-agent "$agent" --show-progress "$progress"; rc=$?; } || :
|
||||||
|
|
||||||
fKill "progress.sh"
|
fKill "progress.sh"
|
||||||
|
|
||||||
if (( rc == 0 )) && [ -f "$iso" ]; then
|
if (( rc == 0 )) && [ -f "$iso" ]; then
|
||||||
total=$(stat -c%s "$iso")
|
total=$(stat -c%s "$iso")
|
||||||
|
total_gb=$(formatBytes "$total")
|
||||||
if [ "$total" -lt 100000000 ]; then
|
if [ "$total" -lt 100000000 ]; then
|
||||||
error "Invalid download link: $url (is only $total bytes?). Please report this at $SUPPORT/issues." && return 1
|
error "Invalid download link: $url (is only $total_gb ?). Please report this at $SUPPORT/issues" && return 1
|
||||||
fi
|
fi
|
||||||
verifyFile "$iso" "$size" "$total" "$sum" || return 1
|
verifyFile "$iso" "$size" "$total" "$sum" || return 1
|
||||||
|
isCompressed "$url" && UNPACK="Y"
|
||||||
html "Download finished successfully..." && return 0
|
html "Download finished successfully..." && return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg="Failed to download $url"
|
msg="Failed to download $url"
|
||||||
(( rc == 3 )) && error "$msg , cannot write file (disk full?)" && return 1
|
(( rc == 3 )) && error "$msg , cannot write file (disk full?)" && return 1
|
||||||
(( rc == 4 )) && error "$msg , network failure!" && return 1
|
(( rc == 4 )) && error "$msg , network failure!" && return 1
|
||||||
(( rc == 8 )) && error "$msg , server issued an error response!" && return 1
|
(( rc == 8 )) && error "$msg , server issued an error response! Please report this at $SUPPORT/issues" && return 1
|
||||||
|
|
||||||
error "$msg , reason: $rc"
|
error "$msg , reason: $rc"
|
||||||
return 1
|
return 1
|
||||||
|
@ -619,12 +598,14 @@ downloadImage() {
|
||||||
local msg="Will retry after $delay seconds..."
|
local msg="Will retry after $delay seconds..."
|
||||||
|
|
||||||
if [[ "${version,,}" == "http"* ]]; then
|
if [[ "${version,,}" == "http"* ]]; then
|
||||||
|
|
||||||
base=$(basename "$iso")
|
base=$(basename "$iso")
|
||||||
desc=$(fromFile "$base")
|
desc=$(fromFile "$base")
|
||||||
downloadFile "$iso" "$version" "" "" "" "$desc" && return 0
|
downloadFile "$iso" "$version" "" "" "" "$desc" && return 0
|
||||||
info "$msg" && html "$msg" && sleep "$delay"
|
info "$msg" && html "$msg" && sleep "$delay"
|
||||||
downloadFile "$iso" "$version" "" "" "" "$desc" && return 0
|
downloadFile "$iso" "$version" "" "" "" "$desc" && return 0
|
||||||
rm -f "$iso"
|
rm -f "$iso"
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ boot() {
|
||||||
|
|
||||||
if [ -s "$QEMU_PTY" ]; then
|
if [ -s "$QEMU_PTY" ]; then
|
||||||
if [ "$(stat -c%s "$QEMU_PTY")" -gt 7 ]; then
|
if [ "$(stat -c%s "$QEMU_PTY")" -gt 7 ]; then
|
||||||
info "Windows started succesfully, visit http://localhost:8006/ to view the screen..."
|
info "Windows started succesfully, visit http://127.0.0.1:8006/ to view the screen..."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
26
src/samba.sh
26
src/samba.sh
|
@ -14,16 +14,21 @@ if [[ "$DHCP" == [Yy1]* ]]; then
|
||||||
interface="$VM_NET_DEV"
|
interface="$VM_NET_DEV"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "${NETWORK,,}" == "user"* ]]; then
|
||||||
|
interface="127.0.0.1"
|
||||||
|
fi
|
||||||
|
|
||||||
addShare() {
|
addShare() {
|
||||||
local dir="$1"
|
local dir="$1"
|
||||||
local name="$2"
|
local name="$2"
|
||||||
local comment="$3"
|
local comment="$3"
|
||||||
|
|
||||||
mkdir -p "$dir" || return 1
|
mkdir -p "$dir" || return 1
|
||||||
|
ls -A "$dir" >/dev/null 2>&1 || return 1
|
||||||
|
|
||||||
if [ -z "$(ls -A "$dir")" ]; then
|
if [ -z "$(ls -A "$dir")" ]; then
|
||||||
|
|
||||||
chmod 777 "$dir"
|
chmod 777 "$dir" || return 1
|
||||||
|
|
||||||
{ echo "--------------------------------------------------------"
|
{ echo "--------------------------------------------------------"
|
||||||
echo " $APP for Docker v$(</run/version)..."
|
echo " $APP for Docker v$(</run/version)..."
|
||||||
|
@ -87,10 +92,17 @@ share="/data"
|
||||||
[ ! -d "$share" ] && [ -d "/shared" ] && share="/shared"
|
[ ! -d "$share" ] && [ -d "/shared" ] && share="/shared"
|
||||||
[ ! -d "$share" ] && [ -d "$STORAGE/shared" ] && share="$STORAGE/shared"
|
[ ! -d "$share" ] && [ -d "$STORAGE/shared" ] && share="$STORAGE/shared"
|
||||||
|
|
||||||
addShare "$share" "Data" "Shared" || error "Failed to create shared folder!"
|
if ! addShare "$share" "Data" "Shared"; then
|
||||||
|
error "Failed to add shared folder '$share'. Please check its permissions." && return 0
|
||||||
|
fi
|
||||||
|
|
||||||
[ -d "/data2" ] && addShare "/data2" "Data2" "Shared"
|
if [ -d "/data2" ]; then
|
||||||
[ -d "/data3" ] && addShare "/data3" "Data3" "Shared"
|
addShare "/data2" "Data2" "Shared" || error "Failed to add shared folder '/data2'. Please check its permissions."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d "/data3" ]; then
|
||||||
|
addShare "/data3" "Data3" "Shared" || error "Failed to add shared folder '/data3'. Please check its permissions."
|
||||||
|
fi
|
||||||
|
|
||||||
IFS=',' read -r -a dirs <<< "${SHARES:-}"
|
IFS=',' read -r -a dirs <<< "${SHARES:-}"
|
||||||
for dir in "${dirs[@]}"; do
|
for dir in "${dirs[@]}"; do
|
||||||
|
@ -99,12 +111,16 @@ for dir in "${dirs[@]}"; do
|
||||||
addShare "$dir" "$dir_name" "Shared $dir_name" || error "Failed to create shared folder for $dir!"
|
addShare "$dir" "$dir_name" "Shared $dir_name" || error "Failed to create shared folder for $dir!"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Fix Samba permissions
|
||||||
|
[ -d /run/samba/msg.lock ] && chmod -R 0755 /run/samba/msg.lock
|
||||||
|
[ -d /var/log/samba/cores ] && chmod -R 0700 /var/log/samba/cores
|
||||||
|
[ -d /var/cache/samba/msg.lock ] && chmod -R 0755 /var/cache/samba/msg.lock
|
||||||
|
|
||||||
if ! smbd; then
|
if ! smbd; then
|
||||||
error "Samba daemon failed to start!"
|
error "Samba daemon failed to start!"
|
||||||
smbd -i --debug-stdout || true
|
smbd -i --debug-stdout || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Enable Web Service Discovery
|
|
||||||
wsdd -i "$interface" -p -n "$hostname" &
|
wsdd -i "$interface" -p -n "$hostname" &
|
||||||
echo "$!" > /var/run/wsdd.pid
|
echo "$!" > /var/run/wsdd.pid
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue