Compare commits
No commits in common. "master" and "v4.03" have entirely different histories.
20 changed files with 596 additions and 706 deletions
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"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,7 +21,6 @@ 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
|
||||||
|
@ -29,7 +28,6 @@ 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,7 +23,6 @@ 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
|
||||||
|
@ -31,7 +30,6 @@ 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,index
|
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest
|
||||||
-
|
-
|
||||||
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/amd64,linux/arm64
|
platforms: 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 }}
|
||||||
|
|
17
Dockerfile
17
Dockerfile
|
@ -1,7 +1,7 @@
|
||||||
FROM scratch
|
FROM scratch
|
||||||
COPY --from=qemux/qemu-arm:7.12 / /
|
COPY --from=qemux/qemu-arm:2.20 / /
|
||||||
|
|
||||||
ARG VERSION_ARG="0.00"
|
ARG VERSION_ARG="4.00"
|
||||||
ARG DEBCONF_NOWARNINGS="yes"
|
ARG DEBCONF_NOWARNINGS="yes"
|
||||||
ARG DEBIAN_FRONTEND="noninteractive"
|
ARG DEBIAN_FRONTEND="noninteractive"
|
||||||
ARG DEBCONF_NONINTERACTIVE_SEEN="true"
|
ARG DEBCONF_NONINTERACTIVE_SEEN="true"
|
||||||
|
@ -9,14 +9,18 @@ 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 \
|
||||||
|
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/*
|
||||||
|
@ -24,10 +28,11 @@ 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.271-1/virtio-win-0.1.271.tar.xz /var/drivers.txz
|
ADD --chmod=755 https://raw.githubusercontent.com/christgau/wsdd/v0.8/src/wsdd.py /usr/sbin/wsdd
|
||||||
|
ADD --chmod=664 https://github.com/qemus/virtiso-arm/releases/download/v0.1.262-2/virtio-win-0.1.262.tar.xz /drivers.txz
|
||||||
|
|
||||||
|
EXPOSE 8006 3389
|
||||||
VOLUME /storage
|
VOLUME /storage
|
||||||
EXPOSE 3389 8006
|
|
||||||
|
|
||||||
ENV VERSION="11"
|
ENV VERSION="11"
|
||||||
ENV RAM_SIZE="4G"
|
ENV RAM_SIZE="4G"
|
||||||
|
|
|
@ -326,6 +326,11 @@
|
||||||
<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>
|
||||||
|
@ -413,11 +418,6 @@
|
||||||
</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,6 +329,11 @@
|
||||||
<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>
|
||||||
|
@ -416,11 +421,6 @@
|
||||||
</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,6 +326,11 @@
|
||||||
<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>
|
||||||
|
@ -413,11 +418,6 @@
|
||||||
</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,11 +268,6 @@
|
||||||
<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">
|
||||||
|
@ -355,6 +350,11 @@
|
||||||
<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>cmd /C rd /q C:\Windows.old</CommandLine>
|
<CommandLine>pnputil -i -a C:\Windows\Drivers\viogpudo\viogpudo.inf</CommandLine>
|
||||||
<Description>Remove empty Windows.old folder</Description>
|
<Description>Install VirtIO display driver</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>23</Order>
|
<Order>23</Order>
|
||||||
<CommandLine>cmd /C echo 20.20.20.1 host.lan >> %WINDIR%\system32\drivers\etc\hosts</CommandLine>
|
<CommandLine>cmd /C rd /q C:\Windows.old</CommandLine>
|
||||||
<Description>Add entry in hosts file</Description>
|
<Description>Remove empty Windows.old folder</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>24</Order>
|
<Order>24</Order>
|
||||||
|
|
|
@ -267,11 +267,6 @@
|
||||||
<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">
|
||||||
|
@ -354,6 +349,11 @@
|
||||||
<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>cmd /C rd /q C:\Windows.old</CommandLine>
|
<CommandLine>pnputil -i -a C:\Windows\Drivers\viogpudo\viogpudo.inf</CommandLine>
|
||||||
<Description>Remove empty Windows.old folder</Description>
|
<Description>Install VirtIO display driver</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>23</Order>
|
<Order>23</Order>
|
||||||
<CommandLine>cmd /C echo 20.20.20.1 host.lan >> %WINDIR%\system32\drivers\etc\hosts</CommandLine>
|
<CommandLine>cmd /C rd /q C:\Windows.old</CommandLine>
|
||||||
<Description>Add entry in hosts file</Description>
|
<Description>Remove empty Windows.old folder</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>24</Order>
|
<Order>24</Order>
|
||||||
|
|
|
@ -268,11 +268,6 @@
|
||||||
<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">
|
||||||
|
@ -355,6 +350,11 @@
|
||||||
<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>cmd /C rd /q C:\Windows.old</CommandLine>
|
<CommandLine>pnputil -i -a C:\Windows\Drivers\viogpudo\viogpudo.inf</CommandLine>
|
||||||
<Description>Remove empty Windows.old folder</Description>
|
<Description>Install VirtIO display driver</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>23</Order>
|
<Order>23</Order>
|
||||||
<CommandLine>cmd /C echo 20.20.20.1 host.lan >> %WINDIR%\system32\drivers\etc\hosts</CommandLine>
|
<CommandLine>cmd /C rd /q C:\Windows.old</CommandLine>
|
||||||
<Description>Add entry in hosts file</Description>
|
<Description>Remove empty Windows.old folder</Description>
|
||||||
</SynchronousCommand>
|
</SynchronousCommand>
|
||||||
<SynchronousCommand wcm:action="add">
|
<SynchronousCommand wcm:action="add">
|
||||||
<Order>24</Order>
|
<Order>24</Order>
|
||||||
|
|
|
@ -1,19 +1,15 @@
|
||||||
services:
|
services:
|
||||||
windows:
|
windows:
|
||||||
image: dockurr/windows
|
|
||||||
container_name: windows
|
container_name: windows
|
||||||
|
image: dockurr/windows-arm
|
||||||
environment:
|
environment:
|
||||||
VERSION: "11"
|
VERSION: "11"
|
||||||
devices:
|
devices:
|
||||||
- /dev/kvm
|
- /dev/kvm
|
||||||
- /dev/net/tun
|
|
||||||
cap_add:
|
cap_add:
|
||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
ports:
|
ports:
|
||||||
- 8006:8006
|
- 8006:8006
|
||||||
- 3389:3389/tcp
|
- 3389:3389/tcp
|
||||||
- 3389:3389/udp
|
- 3389:3389/udp
|
||||||
volumes:
|
|
||||||
- ./windows:/storage
|
|
||||||
restart: always
|
|
||||||
stop_grace_period: 2m
|
stop_grace_period: 2m
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
---
|
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: PersistentVolumeClaim
|
kind: PersistentVolumeClaim
|
||||||
metadata:
|
metadata:
|
||||||
|
@ -10,91 +9,66 @@ spec:
|
||||||
requests:
|
requests:
|
||||||
storage: 64Gi
|
storage: 64Gi
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: v1
|
||||||
kind: Deployment
|
kind: Pod
|
||||||
metadata:
|
metadata:
|
||||||
name: windows
|
name: windows
|
||||||
labels:
|
labels:
|
||||||
name: windows
|
name: windows
|
||||||
spec:
|
spec:
|
||||||
replicas: 1
|
terminationGracePeriodSeconds: 120 # the Kubernetes default is 30 seconds and it may be not enough
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: windows
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: windows
|
|
||||||
spec:
|
|
||||||
containers:
|
containers:
|
||||||
- name: windows
|
- name: windows
|
||||||
image: dockurr/windows
|
image: dockurr/windows-arm
|
||||||
|
ports:
|
||||||
|
- containerPort: 8006
|
||||||
|
protocol: TCP
|
||||||
|
- containerPort: 3389
|
||||||
|
protocol: TCP
|
||||||
|
- containerPort: 3389
|
||||||
|
protocol: UDP
|
||||||
|
securityContext:
|
||||||
|
privileged: true
|
||||||
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:
|
|
||||||
- containerPort: 8006
|
|
||||||
name: http
|
|
||||||
protocol: TCP
|
|
||||||
- containerPort: 3389
|
|
||||||
name: rdp
|
|
||||||
protocol: TCP
|
|
||||||
- containerPort: 3389
|
|
||||||
name: udp
|
|
||||||
protocol: UDP
|
|
||||||
- containerPort: 5900
|
|
||||||
name: vnc
|
|
||||||
protocol: TCP
|
|
||||||
securityContext:
|
|
||||||
capabilities:
|
|
||||||
add:
|
|
||||||
- NET_ADMIN
|
|
||||||
privileged: true
|
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /storage
|
- mountPath: /storage
|
||||||
name: storage
|
name: storage
|
||||||
- mountPath: /dev/kvm
|
- mountPath: /dev/kvm
|
||||||
name: dev-kvm
|
name: dev-kvm
|
||||||
- mountPath: /dev/net/tun
|
|
||||||
name: dev-tun
|
|
||||||
terminationGracePeriodSeconds: 120
|
|
||||||
volumes:
|
volumes:
|
||||||
- name: storage
|
- name: storage
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: windows-pvc
|
claimName: windows-pvc
|
||||||
- hostPath:
|
- name: dev-kvm
|
||||||
|
hostPath:
|
||||||
path: /dev/kvm
|
path: /dev/kvm
|
||||||
name: dev-kvm
|
|
||||||
- hostPath:
|
|
||||||
path: /dev/net/tun
|
|
||||||
type: CharDevice
|
|
||||||
name: dev-tun
|
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: windows
|
name: windows
|
||||||
spec:
|
spec:
|
||||||
internalTrafficPolicy: Cluster
|
type: NodePort
|
||||||
ports:
|
|
||||||
- name: http
|
|
||||||
port: 8006
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: 8006
|
|
||||||
- name: rdp
|
|
||||||
port: 3389
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: 3389
|
|
||||||
- name: udp
|
|
||||||
port: 3389
|
|
||||||
protocol: UDP
|
|
||||||
targetPort: 3389
|
|
||||||
- name: vnc
|
|
||||||
port: 5900
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: 5900
|
|
||||||
selector:
|
selector:
|
||||||
app: windows
|
name: windows
|
||||||
type: ClusterIP
|
ports:
|
||||||
|
- name: tcp-8006
|
||||||
|
protocol: TCP
|
||||||
|
port: 8006
|
||||||
|
targetPort: 8006
|
||||||
|
- name: tcp-3389
|
||||||
|
protocol: TCP
|
||||||
|
port: 3389
|
||||||
|
targetPort: 3389
|
||||||
|
- name: udp-3389
|
||||||
|
protocol: UDP
|
||||||
|
port: 3389
|
||||||
|
targetPort: 3389
|
||||||
|
|
204
readme.md
204
readme.md
|
@ -26,45 +26,45 @@ 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:
|
||||||
windows:
|
windows:
|
||||||
image: dockurr/windows
|
|
||||||
container_name: windows
|
container_name: windows
|
||||||
|
image: dockurr/windows-arm
|
||||||
environment:
|
environment:
|
||||||
VERSION: "11"
|
VERSION: "11"
|
||||||
devices:
|
devices:
|
||||||
- /dev/kvm
|
- /dev/kvm
|
||||||
- /dev/net/tun
|
|
||||||
cap_add:
|
cap_add:
|
||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
ports:
|
ports:
|
||||||
- 8006:8006
|
- 8006:8006
|
||||||
- 3389:3389/tcp
|
- 3389:3389/tcp
|
||||||
- 3389:3389/udp
|
- 3389:3389/udp
|
||||||
volumes:
|
|
||||||
- ./windows:/storage
|
|
||||||
restart: always
|
|
||||||
stop_grace_period: 2m
|
stop_grace_period: 2m
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Via Docker CLI:
|
Via Docker CLI:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
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
|
docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN --stop-timeout 120 dockurr/windows-arm
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Via Kubernetes:
|
Via Kubernetes:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl apply -f https://raw.githubusercontent.com/dockur/windows/refs/heads/master/kubernetes.yml
|
kubectl apply -f https://raw.githubusercontent.com/dockur/windows-arm/refs/heads/master/kubernetes.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Via Github Codespaces:
|
## Compatibility ⚙️
|
||||||
|
|
||||||
[](https://codespaces.new/dockur/windows-arm)
|
| **Product** | **Platform** | |
|
||||||
|
|---|---|---|
|
||||||
|
| Docker Engine | Linux| ✅ |
|
||||||
|
| Docker Desktop | Linux | ❌ |
|
||||||
|
| Docker Desktop | macOS | ❌ |
|
||||||
|
|
||||||
## FAQ 💬
|
## FAQ 💬
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ kubectl apply -f https://raw.githubusercontent.com/dockur/windows/refs/heads/mas
|
||||||
|
|
||||||
Very simple! These are the steps:
|
Very simple! These are the steps:
|
||||||
|
|
||||||
- Start the container and connect to [port 8006](http://127.0.0.1:8006/) using your web browser.
|
- Start the container and connect to [port 8006](http://localhost: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.
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ kubectl apply -f https://raw.githubusercontent.com/dockur/windows/refs/heads/mas
|
||||||
|
|
||||||
### How do I select the Windows version?
|
### How do I select the Windows version?
|
||||||
|
|
||||||
By default, Windows 11 Pro will be installed. But you can add the `VERSION` environment variable to your compose file, in order to specify an alternative Windows version to be downloaded:
|
By default, Windows 11 will be installed. But you can add the `VERSION` environment variable to your compose file, in order to specify an alternative Windows version to be downloaded:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
|
@ -91,15 +91,15 @@ kubectl apply -f https://raw.githubusercontent.com/dockur/windows/refs/heads/mas
|
||||||
|
|
||||||
Select from the values below:
|
Select from the values below:
|
||||||
|
|
||||||
| **Value** | **Version** | **Size** |
|
| **Value** | **Version** | **Platform** | **Size** |
|
||||||
|---|---|---|
|
|---|---|---|---|
|
||||||
| `11` | Windows 11 Pro | 4.8 GB |
|
| `11` | Windows 11 Pro | ARM64 | 4.9 GB |
|
||||||
| `11l` | Windows 11 LTSC | 4.7 GB |
|
| `11l` | Windows 11 LTSC | ARM64 | 4.8 GB |
|
||||||
| `11e` | Windows 11 Enterprise | 4.8 GB |
|
| `11e` | Windows 11 Enterprise | ARM64 | 4.8 GB |
|
||||||
||||
|
|||||
|
||||||
| `10` | Windows 10 Pro | 3.5 GB |
|
| `10` | Windows 10 Pro | ARM64 | 3.5 GB |
|
||||||
| `10l` | Windows 10 LTSC | 4.1 GB |
|
| `10l` | Windows 10 LTSC | ARM64 | 4.1 GB |
|
||||||
| `10e` | Windows 10 Enterprise | 3.4 GB |
|
| `10e` | Windows 10 Enterprise | ARM64 | 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/).
|
||||||
|
@ -110,10 +110,10 @@ kubectl apply -f https://raw.githubusercontent.com/dockur/windows/refs/heads/mas
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
volumes:
|
volumes:
|
||||||
- ./windows:/storage
|
- /var/win:/storage
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace the example path `./windows` with the desired storage folder or named volume.
|
Replace the example path `/var/win` with the desired storage folder.
|
||||||
|
|
||||||
### How do I change the size of the disk?
|
### How do I change the size of the disk?
|
||||||
|
|
||||||
|
@ -129,31 +129,71 @@ kubectl apply -f https://raw.githubusercontent.com/dockur/windows/refs/heads/mas
|
||||||
|
|
||||||
### How do I increase the display resolution?
|
### How do I increase the display resolution?
|
||||||
|
|
||||||
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, so that the screen can be visible during installation as it doesn't require any drivers.
|
||||||
|
|
||||||
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:
|
After Windows is fully installed, you can add the following to your compose file:
|
||||||
|
|
||||||
```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`.
|
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:
|
||||||
|
|
||||||
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:
|
||||||
- ./example:/data
|
- /home/user/example:/data
|
||||||
```
|
```
|
||||||
|
|
||||||
The example folder `./example` will be available as ` \\host.lan\Data`.
|
The example folder `/home/user/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.
|
||||||
|
@ -168,9 +208,9 @@ The example folder `./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 installation and its password is `admin`.
|
By default, a user called `Docker` is created during the installation, with an empty password.
|
||||||
|
|
||||||
If you want to use different credentials, you can configure them in your compose file (only before installation):
|
If you want to use different credentials, you can change them in your compose file:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
|
@ -180,9 +220,7 @@ The example folder `./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.
|
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:
|
||||||
|
|
||||||
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:
|
||||||
|
@ -193,7 +231,7 @@ The example folder `./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 `KEYBOARD` and `REGION` variables like this (before installation):
|
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:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
|
@ -201,53 +239,14 @@ The example folder `./example` will be available as ` \\host.lan\Data`.
|
||||||
KEYBOARD: "en-US"
|
KEYBOARD: "en-US"
|
||||||
```
|
```
|
||||||
|
|
||||||
### How do I install a custom image?
|
> [!NOTE]
|
||||||
|
> 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 password `admin`.
|
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.
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
@ -292,7 +291,7 @@ The example folder `./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, in which the container and Windows will have separate IP addresses, add the following lines to your compose file:
|
To enable this mode, add the following lines to your compose file:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
|
@ -303,6 +302,9 @@ The example folder `./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:
|
||||||
|
@ -312,18 +314,18 @@ The example folder `./example` will be available as ` \\host.lan\Data`.
|
||||||
DISK2_SIZE: "32G"
|
DISK2_SIZE: "32G"
|
||||||
DISK3_SIZE: "64G"
|
DISK3_SIZE: "64G"
|
||||||
volumes:
|
volumes:
|
||||||
- ./example2:/storage2
|
- /home/example:/storage2
|
||||||
- ./example3:/storage3
|
- /mnt/data/example:/storage3
|
||||||
```
|
```
|
||||||
|
|
||||||
### How do I pass-through a disk?
|
### How do I pass-through a disk?
|
||||||
|
|
||||||
It is possible to pass-through disk devices or partitions directly by adding them to your compose file in this way:
|
It is possible to pass-through disk devices directly by adding them to your compose file in this way:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
devices:
|
devices:
|
||||||
- /dev/sdb:/disk1
|
- /dev/sdb:/disk1
|
||||||
- /dev/sdc1:/disk2
|
- /dev/sdc:/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).
|
||||||
|
@ -339,20 +341,14 @@ The example folder `./example` will be available as ` \\host.lan\Data`.
|
||||||
- /dev/bus/usb
|
- /dev/bus/usb
|
||||||
```
|
```
|
||||||
|
|
||||||
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.
|
> [!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.
|
||||||
|
|
||||||
### How do I verify if my system supports KVM?
|
### How do I verify if my system supports KVM?
|
||||||
|
|
||||||
First check if your software is compatible using this chart:
|
Only Linux and Windows 11 support KVM virtualization, macOS and Windows 10 do not unfortunately.
|
||||||
|
|
||||||
| **Product** | **Linux** | **Win11** | **Win10** | **macOS** |
|
You can run the following commands in Linux to check your system:
|
||||||
|---|---|---|---|---|
|
|
||||||
| 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 +363,11 @@ The example folder `./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 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.
|
If you do not receive any error from `kvm-ok` but the container still complains about KVM, please check whether:
|
||||||
|
|
||||||
### How do I run a Linux desktop in a container?
|
- you are not using "Docker Desktop for Linux" as it does not support KVM, instead make use of Docker Engine directly.
|
||||||
|
|
||||||
You can use [qemus/qemu-arm](https://github.com/qemus/qemu-arm) in that case.
|
- it could help to add `privileged: true` to your compose file (or `sudo` to your `docker run` command), to rule out any permission issue.
|
||||||
|
|
||||||
### Is this project legal?
|
### Is this project legal?
|
||||||
|
|
||||||
|
@ -385,12 +381,12 @@ The example folder `./example` will be available as ` \\host.lan\Data`.
|
||||||
*The product names, logos, brands, and other trademarks referred to within this project are the property of their respective trademark holders. This project is not affiliated, sponsored, or endorsed by Microsoft Corporation.*
|
*The product names, logos, brands, and other trademarks referred to within this project are the property of their respective trademark holders. This project is not affiliated, sponsored, or endorsed by Microsoft Corporation.*
|
||||||
|
|
||||||
[build_url]: https://github.com/dockur/windows-arm/
|
[build_url]: https://github.com/dockur/windows-arm/
|
||||||
[hub_url]: https://hub.docker.com/r/dockurr/windows/
|
[hub_url]: https://hub.docker.com/r/dockurr/windows-arm/
|
||||||
[tag_url]: https://hub.docker.com/r/dockurr/windows/tags
|
[tag_url]: https://hub.docker.com/r/dockurr/windows-arm/tags
|
||||||
[pkg_url]: https://github.com/dockur/windows/pkgs/container/windows
|
[pkg_url]: https://github.com/dockur/windows-arm/pkgs/container/windows-arm
|
||||||
|
|
||||||
[Build]: https://github.com/dockur/windows-arm/actions/workflows/build.yml/badge.svg
|
[Build]: https://github.com/dockur/windows-arm/actions/workflows/build.yml/badge.svg
|
||||||
[Size]: https://img.shields.io/docker/image-size/dockurr/windows-arm/latest?color=066da5&label=size
|
[Size]: https://img.shields.io/docker/image-size/dockurr/windows-arm/latest?color=066da5&label=size
|
||||||
[Pulls]: https://img.shields.io/docker/pulls/dockurr/windows.svg?style=flat&label=pulls&logo=docker
|
[Pulls]: https://img.shields.io/docker/pulls/dockurr/windows-arm.svg?style=flat&label=pulls&logo=docker
|
||||||
[Version]: https://img.shields.io/docker/v/dockurr/windows/latest?arch=arm64&sort=semver&color=066da5
|
[Version]: https://img.shields.io/docker/v/dockurr/windows-arm/latest?arch=arm64&sort=semver&color=066da5
|
||||||
[Package]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fipitio.github.io%2Fbackage%2Fdockur%2Fwindows%2Fwindows.json&query=%24.downloads&logo=github&style=flat&color=066da5&label=pulls
|
[Package]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fipitio.github.io%2Fbackage%2Fdockur%2Fwindows-arm%2Fwindows-arm.json&query=%24.downloads&logo=github&style=flat&color=066da5&label=pulls
|
||||||
|
|
309
src/define.sh
309
src/define.sh
|
@ -1,12 +1,10 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
: "${KEY:=""}"
|
: "${XRES:=""}"
|
||||||
: "${WIDTH:=""}"
|
: "${YRES:=""}"
|
||||||
: "${HEIGHT:=""}"
|
|
||||||
: "${VERIFY:=""}"
|
: "${VERIFY:=""}"
|
||||||
: "${REGION:=""}"
|
: "${REGION:=""}"
|
||||||
: "${EDITION:=""}"
|
|
||||||
: "${MANUAL:=""}"
|
: "${MANUAL:=""}"
|
||||||
: "${REMOVE:=""}"
|
: "${REMOVE:=""}"
|
||||||
: "${VERSION:=""}"
|
: "${VERSION:=""}"
|
||||||
|
@ -17,6 +15,7 @@ set -Eeuo pipefail
|
||||||
: "${PASSWORD:=""}"
|
: "${PASSWORD:=""}"
|
||||||
|
|
||||||
MIRRORS=2
|
MIRRORS=2
|
||||||
|
PLATFORM="ARM64"
|
||||||
|
|
||||||
parseVersion() {
|
parseVersion() {
|
||||||
|
|
||||||
|
@ -61,23 +60,20 @@ 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" | "win7" | "windows7" | "windows 7" | "7u" | "win7u" | "windows7u" | "windows 7u" | "7e" | \
|
"7" | "7e" | "win7" | "win7e" | "windows7" | "windows 7" | \
|
||||||
"win7e" | "windows7e" | "windows 7e" | "7x86" | "win7x86" | "win732" | "windows7x86" | "7ux86" | \
|
"7u" | "win7u" | "windows7u" | "windows 7u" | \
|
||||||
"7u32" | "win7x86-ultimate" | "7ex86" | "7e32" | "win7x86-enterprise" )
|
"7x86" | "win7x86" | "windows7x86" | "win7x86-enterprise" )
|
||||||
error "Windows 7 $msg" && return 1
|
error "Windows 7 $msg" && return 1
|
||||||
;;
|
;;
|
||||||
"vista" | "vs" | "6" | "winvista" | "windowsvista" | "windows vista" | "vistu" | "vu" | "6u" | "winvistu" | \
|
"vista" | "ve" | "6" | "winvista" | "windowsvista" | "windows vista" | \
|
||||||
"viste" | "ve" | "6e" | "winviste" | "vistax86" | "vista32" | "6x86" | "winvistax86" | "windowsvistax86" | \
|
"vistu" | "vu" | "6u" | "winvistu" | "windowsvistu" | "windows vistu" | \
|
||||||
"vux86" | "vu32" | "winvistax86-ultimate" | "vex86" | "ve32" | "winvistax86-enterprise" )
|
"vistax86" | "vex86" | "6x86" | "winvistax86" | "windowsvistax86" | "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
|
||||||
;;
|
;;
|
||||||
|
@ -90,9 +86,6 @@ 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
|
||||||
;;
|
;;
|
||||||
|
@ -102,13 +95,11 @@ parseVersion() {
|
||||||
"2003" | "2003r2" | "win2003" | "win2003r2" | "windows2003" | "windows 2003" )
|
"2003" | "2003r2" | "win2003" | "win2003r2" | "windows2003" | "windows 2003" )
|
||||||
error "Windows Server 2003 $msg" && return 1
|
error "Windows Server 2003 $msg" && return 1
|
||||||
;;
|
;;
|
||||||
"tiny11" | "tiny 11" )
|
|
||||||
VERSION="tiny11"
|
|
||||||
[ -z "$DETECTED" ] && DETECTED="win11arm64"
|
|
||||||
;;
|
|
||||||
"core11" | "core 11" )
|
"core11" | "core 11" )
|
||||||
VERSION="core11"
|
error "Tiny 11 Core $msg" && return 1
|
||||||
[ -z "$DETECTED" ] && DETECTED="win11arm64"
|
;;
|
||||||
|
"tiny11" | "tiny 11" )
|
||||||
|
error "Tiny 11 $msg" && return 1
|
||||||
;;
|
;;
|
||||||
"tiny10" | "tiny 10" )
|
"tiny10" | "tiny 10" )
|
||||||
error "Tiny 10 $msg" && return 1
|
error "Tiny 10 $msg" && return 1
|
||||||
|
@ -124,203 +115,163 @@ getLanguage() {
|
||||||
local ret="$2"
|
local ret="$2"
|
||||||
local lang=""
|
local lang=""
|
||||||
local desc=""
|
local desc=""
|
||||||
local short=""
|
|
||||||
local culture=""
|
local culture=""
|
||||||
|
|
||||||
case "${id,,}" in
|
case "${id,,}" in
|
||||||
"ar" | "ar-"* )
|
"ar" | "ar-"* )
|
||||||
short="ar"
|
|
||||||
lang="Arabic"
|
lang="Arabic"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="ar-SA" ;;
|
culture="ar-SA" ;;
|
||||||
"bg" | "bg-"* )
|
"bg" | "bg-"* )
|
||||||
short="bg"
|
|
||||||
lang="Bulgarian"
|
lang="Bulgarian"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="bg-BG" ;;
|
culture="bg-BG" ;;
|
||||||
"cs" | "cs-"* | "cz" | "cz-"* )
|
"cs" | "cs-"* | "cz" | "cz-"* )
|
||||||
short="cs"
|
|
||||||
lang="Czech"
|
lang="Czech"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="cs-CZ" ;;
|
culture="cs-CZ" ;;
|
||||||
"da" | "da-"* | "dk" | "dk-"* )
|
"da" | "da-"* | "dk" | "dk-"* )
|
||||||
short="da"
|
|
||||||
lang="Danish"
|
lang="Danish"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="da-DK" ;;
|
culture="da-DK" ;;
|
||||||
"de" | "de-"* )
|
"de" | "de-"* )
|
||||||
short="de"
|
|
||||||
lang="German"
|
lang="German"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="de-DE" ;;
|
culture="de-DE" ;;
|
||||||
"el" | "el-"* | "gr" | "gr-"* )
|
"el" | "el-"* | "gr" | "gr-"* )
|
||||||
short="el"
|
|
||||||
lang="Greek"
|
lang="Greek"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="el-GR" ;;
|
culture="el-GR" ;;
|
||||||
"gb" | "en-gb" )
|
"gb" | "en-gb" )
|
||||||
short="en-gb"
|
|
||||||
lang="English International"
|
lang="English International"
|
||||||
desc="English"
|
desc="English"
|
||||||
culture="en-GB" ;;
|
culture="en-GB" ;;
|
||||||
"en" | "en-"* )
|
"en" | "en-"* )
|
||||||
short="en"
|
lang="English (United States)"
|
||||||
lang="English"
|
|
||||||
desc="English"
|
desc="English"
|
||||||
culture="en-US" ;;
|
culture="en-US" ;;
|
||||||
"mx" | "es-mx" )
|
"mx" | "es-mx" )
|
||||||
short="mx"
|
|
||||||
lang="Spanish (Mexico)"
|
lang="Spanish (Mexico)"
|
||||||
desc="Spanish"
|
desc="Spanish"
|
||||||
culture="es-MX" ;;
|
culture="es-MX" ;;
|
||||||
"es" | "es-"* )
|
"es" | "es-"* )
|
||||||
short="es"
|
|
||||||
lang="Spanish"
|
lang="Spanish"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="es-ES" ;;
|
culture="es-ES" ;;
|
||||||
"et" | "et-"* )
|
"et" | "et-"* )
|
||||||
short="et"
|
|
||||||
lang="Estonian"
|
lang="Estonian"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="et-EE" ;;
|
culture="et-EE" ;;
|
||||||
"fi" | "fi-"* )
|
"fi" | "fi-"* )
|
||||||
short="fi"
|
|
||||||
lang="Finnish"
|
lang="Finnish"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="fi-FI" ;;
|
culture="fi-FI" ;;
|
||||||
"ca" | "fr-ca" )
|
"ca" | "fr-ca" )
|
||||||
short="ca"
|
|
||||||
lang="French Canadian"
|
lang="French Canadian"
|
||||||
desc="French"
|
desc="French"
|
||||||
culture="fr-CA" ;;
|
culture="fr-CA" ;;
|
||||||
"fr" | "fr-"* )
|
"fr" | "fr-"* )
|
||||||
short="fr"
|
|
||||||
lang="French"
|
lang="French"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="fr-FR" ;;
|
culture="fr-FR" ;;
|
||||||
"he" | "he-"* | "il" | "il-"* )
|
"he" | "he-"* | "il" | "il-"* )
|
||||||
short="he"
|
|
||||||
lang="Hebrew"
|
lang="Hebrew"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="he-IL" ;;
|
culture="he-IL" ;;
|
||||||
"hr" | "hr-"* | "cr" | "cr-"* )
|
"hr" | "hr-"* | "cr" | "cr-"* )
|
||||||
short="hr"
|
|
||||||
lang="Croatian"
|
lang="Croatian"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="hr-HR" ;;
|
culture="hr-HR" ;;
|
||||||
"hu" | "hu-"* )
|
"hu" | "hu-"* )
|
||||||
short="hu"
|
|
||||||
lang="Hungarian"
|
lang="Hungarian"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="hu-HU" ;;
|
culture="hu-HU" ;;
|
||||||
"it" | "it-"* )
|
"it" | "it-"* )
|
||||||
short="it"
|
|
||||||
lang="Italian"
|
lang="Italian"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="it-IT" ;;
|
culture="it-IT" ;;
|
||||||
"ja" | "ja-"* | "jp" | "jp-"* )
|
"ja" | "ja-"* | "jp" | "jp-"* )
|
||||||
short="ja"
|
|
||||||
lang="Japanese"
|
lang="Japanese"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="ja-JP" ;;
|
culture="ja-JP" ;;
|
||||||
"ko" | "ko-"* | "kr" | "kr-"* )
|
"ko" | "ko-"* | "kr" | "kr-"* )
|
||||||
short="ko"
|
|
||||||
lang="Korean"
|
lang="Korean"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="ko-KR" ;;
|
culture="ko-KR" ;;
|
||||||
"lt" | "lt-"* )
|
"lt" | "lt-"* )
|
||||||
short="lt"
|
|
||||||
lang="Lithuanian"
|
lang="Lithuanian"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="lt-LT" ;;
|
culture="lv-LV" ;;
|
||||||
"lv" | "lv-"* )
|
"lv" | "lv-"* )
|
||||||
short="lv"
|
|
||||||
lang="Latvian"
|
lang="Latvian"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="lv-LV" ;;
|
culture="lt-LT" ;;
|
||||||
"nb" | "nb-"* |"nn" | "nn-"* | "no" | "no-"* )
|
"nb" | "nb-"* |"nn" | "nn-"* | "no" | "no-"* )
|
||||||
short="no"
|
|
||||||
lang="Norwegian"
|
lang="Norwegian"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="nb-NO" ;;
|
culture="nb-NO" ;;
|
||||||
"nl" | "nl-"* )
|
"nl" | "nl-"* )
|
||||||
short="nl"
|
|
||||||
lang="Dutch"
|
lang="Dutch"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="nl-NL" ;;
|
culture="nl-NL" ;;
|
||||||
"pl" | "pl-"* )
|
"pl" | "pl-"* )
|
||||||
short="pl"
|
|
||||||
lang="Polish"
|
lang="Polish"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="pl-PL" ;;
|
culture="pl-PL" ;;
|
||||||
"br" | "pt-br" )
|
"br" | "pt-br" )
|
||||||
short="pt"
|
|
||||||
lang="Brazilian Portuguese"
|
lang="Brazilian Portuguese"
|
||||||
desc="Portuguese"
|
desc="Portuguese"
|
||||||
culture="pt-BR" ;;
|
culture="pt-BR" ;;
|
||||||
"pt" | "pt-"* )
|
"pt" | "pt-"* )
|
||||||
short="pp"
|
|
||||||
lang="Portuguese"
|
lang="Portuguese"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="pt-BR" ;;
|
culture="pt-BR" ;;
|
||||||
"ro" | "ro-"* )
|
"ro" | "ro-"* )
|
||||||
short="ro"
|
|
||||||
lang="Romanian"
|
lang="Romanian"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="ro-RO" ;;
|
culture="ro-RO" ;;
|
||||||
"ru" | "ru-"* )
|
"ru" | "ru-"* )
|
||||||
short="ru"
|
|
||||||
lang="Russian"
|
lang="Russian"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="ru-RU" ;;
|
culture="ru-RU" ;;
|
||||||
"sk" | "sk-"* )
|
"sk" | "sk-"* )
|
||||||
short="sk"
|
|
||||||
lang="Slovak"
|
lang="Slovak"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="sk-SK" ;;
|
culture="sk-SK" ;;
|
||||||
"sl" | "sl-"* | "si" | "si-"* )
|
"sl" | "sl-"* | "si" | "si-"* )
|
||||||
short="sl"
|
|
||||||
lang="Slovenian"
|
lang="Slovenian"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="sl-SI" ;;
|
culture="sl-SI" ;;
|
||||||
"sr" | "sr-"* )
|
"sr" | "sr-"* )
|
||||||
short="sr"
|
|
||||||
lang="Serbian Latin"
|
lang="Serbian Latin"
|
||||||
desc="Serbian"
|
desc="Serbian"
|
||||||
culture="sr-Latn-RS" ;;
|
culture="sr-Latn-RS" ;;
|
||||||
"sv" | "sv-"* | "se" | "se-"* )
|
"sv" | "sv-"* | "se" | "se-"* )
|
||||||
short="sv"
|
|
||||||
lang="Swedish"
|
lang="Swedish"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="sv-SE" ;;
|
culture="sv-SE" ;;
|
||||||
"th" | "th-"* )
|
"th" | "th-"* )
|
||||||
short="th"
|
|
||||||
lang="Thai"
|
lang="Thai"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="th-TH" ;;
|
culture="th-TH" ;;
|
||||||
"tr" | "tr-"* )
|
"tr" | "tr-"* )
|
||||||
short="tr"
|
|
||||||
lang="Turkish"
|
lang="Turkish"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="tr-TR" ;;
|
culture="tr-TR" ;;
|
||||||
"ua" | "ua-"* | "uk" | "uk-"* )
|
"ua" | "ua-"* | "uk" | "uk-"* )
|
||||||
short="uk"
|
|
||||||
lang="Ukrainian"
|
lang="Ukrainian"
|
||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="uk-UA" ;;
|
culture="uk-UA" ;;
|
||||||
"hk" | "zh-hk" | "cn-hk" )
|
"hk" | "zh-hk" | "cn-hk" )
|
||||||
short="hk"
|
lang="Chinese Traditional"
|
||||||
lang="Chinese (Traditional)"
|
|
||||||
desc="Chinese HK"
|
desc="Chinese HK"
|
||||||
culture="zh-TW" ;;
|
culture="zh-TW" ;;
|
||||||
"tw" | "zh-tw" | "cn-tw" )
|
"tw" | "zh-tw" | "cn-tw" )
|
||||||
short="tw"
|
lang="Chinese Traditional"
|
||||||
lang="Chinese (Traditional)"
|
|
||||||
desc="Chinese TW"
|
desc="Chinese TW"
|
||||||
culture="zh-TW" ;;
|
culture="zh-TW" ;;
|
||||||
"zh" | "zh-"* | "cn" | "cn-"* )
|
"zh" | "zh-"* | "cn" | "cn-"* )
|
||||||
short="cn"
|
lang="Chinese Simplified"
|
||||||
lang="Chinese (Simplified)"
|
|
||||||
desc="Chinese"
|
desc="Chinese"
|
||||||
culture="zh-CN" ;;
|
culture="zh-CN" ;;
|
||||||
esac
|
esac
|
||||||
|
@ -328,7 +279,6 @@ getLanguage() {
|
||||||
case "${ret,,}" in
|
case "${ret,,}" in
|
||||||
"desc" ) echo "$desc" ;;
|
"desc" ) echo "$desc" ;;
|
||||||
"name" ) echo "$lang" ;;
|
"name" ) echo "$lang" ;;
|
||||||
"code" ) echo "$short" ;;
|
|
||||||
"culture" ) echo "$culture" ;;
|
"culture" ) echo "$culture" ;;
|
||||||
*) echo "$desc";;
|
*) echo "$desc";;
|
||||||
esac
|
esac
|
||||||
|
@ -395,8 +345,6 @@ printVersion() {
|
||||||
local desc="$2"
|
local desc="$2"
|
||||||
|
|
||||||
case "${id,,}" in
|
case "${id,,}" in
|
||||||
"tiny11"* ) desc="Tiny 11" ;;
|
|
||||||
"core11"* ) desc="Core 11" ;;
|
|
||||||
"win10"* ) desc="Windows 10" ;;
|
"win10"* ) desc="Windows 10" ;;
|
||||||
"win11"* ) desc="Windows 11" ;;
|
"win11"* ) desc="Windows 11" ;;
|
||||||
esac
|
esac
|
||||||
|
@ -451,10 +399,7 @@ fromFile() {
|
||||||
local file="${1,,}"
|
local file="${1,,}"
|
||||||
local arch="${PLATFORM,,}"
|
local arch="${PLATFORM,,}"
|
||||||
|
|
||||||
file="${file//-/_}"
|
case "${file// /_}" in
|
||||||
file="${file// /_}"
|
|
||||||
|
|
||||||
case "$file" in
|
|
||||||
*"_x64_"* | *"_x64."*)
|
*"_x64_"* | *"_x64."*)
|
||||||
arch="x64"
|
arch="x64"
|
||||||
;;
|
;;
|
||||||
|
@ -466,13 +411,7 @@ fromFile() {
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case "$file" in
|
case "${file// /_}" in
|
||||||
"tiny11core"* | "tiny11_core"* | "tiny_11_core"* )
|
|
||||||
id="core11"
|
|
||||||
;;
|
|
||||||
"tiny11"* | "tiny_11"* )
|
|
||||||
id="tiny11"
|
|
||||||
;;
|
|
||||||
"win10"*| "win_10"* | *"windows10"* | *"windows_10"* )
|
"win10"*| "win_10"* | *"windows10"* | *"windows_10"* )
|
||||||
id="win10${arch}"
|
id="win10${arch}"
|
||||||
;;
|
;;
|
||||||
|
@ -497,9 +436,7 @@ fromName() {
|
||||||
|
|
||||||
case "${name,,}" in
|
case "${name,,}" in
|
||||||
*"windows 10"* ) id="win10${arch}" ;;
|
*"windows 10"* ) id="win10${arch}" ;;
|
||||||
*"optimum 10"* ) id="win10${arch}" ;;
|
|
||||||
*"windows 11"* ) id="win11${arch}" ;;
|
*"windows 11"* ) id="win11${arch}" ;;
|
||||||
*"optimum 11"* ) id="win11${arch}" ;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
echo "$id"
|
echo "$id"
|
||||||
|
@ -550,27 +487,22 @@ 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=""
|
||||||
|
|
||||||
[[ "${lang,,}" != "en" ]] && [[ "${lang,,}" != "en-us" ]] && return 0
|
[[ "${lang,,}" != "en" ]] && [[ "${lang,,}" != "en-us" ]] && return 0
|
||||||
|
|
||||||
case "${id,,}" in
|
case "${id,,}" in
|
||||||
"win11arm64" )
|
|
||||||
size=5460387840
|
|
||||||
sum="57d1dfb2c6690a99fe99226540333c6c97d3fd2b557a50dfe3d68c3f675ef2b0"
|
|
||||||
;;
|
|
||||||
"win11arm64-enterprise-ltsc-eval" )
|
"win11arm64-enterprise-ltsc-eval" )
|
||||||
size=5042194432
|
size=4252764160
|
||||||
sum="3dcdba9c9c0aa0430d4332b60c9afcb3cd613d648a49cbba2d4ef7b5978f32e8"
|
sum="ccec358a760c3c581249f091ed42d04f37b2b99c347b7a58257c3cc272d7982c"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case "${ret,,}" in
|
case "${ret,,}" in
|
||||||
"sum" ) echo "$sum" ;;
|
"sum" ) echo "$sum" ;;
|
||||||
"size" ) echo "$size" ;;
|
"size" ) echo "$size" ;;
|
||||||
*) echo "$url";;
|
*) echo "";;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -586,30 +518,157 @@ getLink1() {
|
||||||
local url=""
|
local url=""
|
||||||
local sum=""
|
local sum=""
|
||||||
local size=""
|
local size=""
|
||||||
local host="https://dl.bobpony.com/windows"
|
local host="https://drive.massgrave.dev"
|
||||||
|
|
||||||
[[ "${lang,,}" != "en" ]] && [[ "${lang,,}" != "en-us" ]] && return 0
|
culture=$(getLanguage "$lang" "culture")
|
||||||
|
|
||||||
case "${id,,}" in
|
case "${id,,}" in
|
||||||
"win11arm64" | "win11arm64-enterprise" | "win11arm64-enterprise-eval" )
|
"win11arm64" )
|
||||||
size=5219411968
|
case "${culture,,}" in
|
||||||
sum="dbd54452c3c20b4625f511dae3c3e057270448fb661232d4fa66279f59a63157"
|
"ar" | "ar-"* ) url="ar-sa_windows_11_consumer_editions_version_24h2_arm64_dvd_331e352e.iso" ;;
|
||||||
url="11/en-us_windows_11_24h2_arm64.iso"
|
"bg" | "bg-"* ) url="bg-bg_windows_11_consumer_editions_version_24h2_arm64_dvd_ad0f4159.iso" ;;
|
||||||
|
"cs" | "cs-"* ) url="cs-cz_windows_11_consumer_editions_version_24h2_arm64_dvd_09e9a65d.iso" ;;
|
||||||
|
"da" | "da-"* ) url="da-dk_windows_11_consumer_editions_version_24h2_arm64_dvd_cfc9f7d2.iso" ;;
|
||||||
|
"de" | "de-"* ) url="de-de_windows_11_consumer_editions_version_24h2_arm64_dvd_77817e34.iso" ;;
|
||||||
|
"el" | "el-"* ) url="el-gr_windows_11_consumer_editions_version_24h2_arm64_dvd_7ff49fe0.iso" ;;
|
||||||
|
"gb" | "en-gb" ) url="en-gb_windows_11_consumer_editions_version_24h2_arm64_dvd_2fb276c5.iso" ;;
|
||||||
|
"en" | "en-"* )
|
||||||
|
size=5460387840
|
||||||
|
sum="57d1dfb2c6690a99fe99226540333c6c97d3fd2b557a50dfe3d68c3f675ef2b0"
|
||||||
|
url="en-us_windows_11_consumer_editions_version_24h2_arm64_dvd_4cc70bf6.iso" ;;
|
||||||
|
"mx" | "es-mx" ) url="es-mx_windows_11_consumer_editions_version_24h2_arm64_dvd_29df5eac.iso" ;;
|
||||||
|
"es" | "es-"* ) url="es-es_windows_11_consumer_editions_version_24h2_arm64_dvd_b0586d9e.iso" ;;
|
||||||
|
"et" | "et-"* ) url="et-ee_windows_11_consumer_editions_version_24h2_arm64_dvd_0895b4c2.iso" ;;
|
||||||
|
"fi" | "fi-"* ) url="fi-fi_windows_11_consumer_editions_version_24h2_arm64_dvd_030941fb.iso" ;;
|
||||||
|
"ca" | "fr-ca" ) url="fr-ca_windows_11_consumer_editions_version_24h2_arm64_dvd_08e2b30e.iso" ;;
|
||||||
|
"fr" | "fr-"* ) url="fr-fr_windows_11_consumer_editions_version_24h2_arm64_dvd_f7d51069.iso" ;;
|
||||||
|
"he" | "he-"* ) url="he-il_windows_11_consumer_editions_version_24h2_arm64_dvd_24838d6b.iso" ;;
|
||||||
|
"hr" | "hr-"* ) url="hr-hr_windows_11_consumer_editions_version_24h2_arm64_dvd_260e2f8a.iso" ;;
|
||||||
|
"hu" | "hu-"* ) url="hu-hu_windows_11_consumer_editions_version_24h2_arm64_dvd_981626d6.iso" ;;
|
||||||
|
"it" | "it-"* ) url="it-it_windows_11_consumer_editions_version_24h2_arm64_dvd_30f0547d.iso" ;;
|
||||||
|
"ja" | "ja-"* ) url="ja-jp_windows_11_consumer_editions_version_24h2_arm64_dvd_f5fc9b3e.iso" ;;
|
||||||
|
"ko" | "ko-"* ) url="ko-kr_windows_11_consumer_editions_version_24h2_arm64_dvd_5dddc52e.iso" ;;
|
||||||
|
"lt" | "lt-"* ) url="lt-lt_windows_11_consumer_editions_version_24h2_arm64_dvd_e83cfe4c.iso" ;;
|
||||||
|
"lv" | "lv-"* ) url="lv-lv_windows_11_consumer_editions_version_24h2_arm64_dvd_0028b5e8.iso" ;;
|
||||||
|
"nb" | "nb-"* ) url="nb-no_windows_11_consumer_editions_version_24h2_arm64_dvd_1df6aff1.iso" ;;
|
||||||
|
"nl" | "nl-"* ) url="nl-nl_windows_11_consumer_editions_version_24h2_arm64_dvd_2a794237.iso" ;;
|
||||||
|
"pl" | "pl-"* ) url="pl-pl_windows_11_consumer_editions_version_24h2_arm64_dvd_80af0fd7.iso" ;;
|
||||||
|
"br" | "pt-br" ) url="pt-br_windows_11_consumer_editions_version_24h2_arm64_dvd_0648fb13.iso" ;;
|
||||||
|
"pt" | "pt-"* ) url="pt-pt_windows_11_consumer_editions_version_24h2_arm64_dvd_223f3f3a.iso" ;;
|
||||||
|
"ro" | "ro-"* ) url="ro-ro_windows_11_consumer_editions_version_24h2_arm64_dvd_78f3a92a.iso" ;;
|
||||||
|
"ru" | "ru-"* ) url="ru-ru_windows_11_consumer_editions_version_24h2_arm64_dvd_8e4d44aa.iso" ;;
|
||||||
|
"sk" | "sk-"* ) url="sk-sk_windows_11_consumer_editions_version_24h2_arm64_dvd_c8c147d6.iso" ;;
|
||||||
|
"sl" | "sl-"* ) url="sl-si_windows_11_consumer_editions_version_24h2_arm64_dvd_f4e5671d.iso" ;;
|
||||||
|
"sr" | "sr-"* ) url="sr-latn-rs_windows_11_consumer_editions_version_24h2_arm64_dvd_489179df.iso" ;;
|
||||||
|
"sv" | "sv-"* ) url="sv-se_windows_11_consumer_editions_version_24h2_arm64_dvd_fa42c0cc.iso" ;;
|
||||||
|
"th" | "th-"* ) url="th-th_windows_11_consumer_editions_version_24h2_arm64_dvd_abb88faa.iso" ;;
|
||||||
|
"tr" | "tr-"* ) url="tr-tr_windows_11_consumer_editions_version_24h2_arm64_dvd_ea2494b5.iso" ;;
|
||||||
|
"uk" | "uk-"* ) url="uk-ua_windows_11_consumer_editions_version_24h2_arm64_dvd_70fa6caf.iso" ;;
|
||||||
|
"zh-hk" | "zh-tw" ) url="zh-tw_windows_11_consumer_editions_version_24h2_arm64_dvd_fa6b02d0.iso" ;;
|
||||||
|
"zh" | "zh-"* ) url="zh-cn_windows_11_consumer_editions_version_24h2_arm64_dvd_4b5c8070.iso" ;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
"win11arm64-enterprise" | "win11arm64-enterprise-eval" )
|
||||||
|
case "${culture,,}" in
|
||||||
|
"ar" | "ar-"* ) url="ar-sa_windows_11_business_editions_version_24h2_arm64_dvd_0b673385.iso" ;;
|
||||||
|
"bg" | "bg-"* ) url="bg-bg_windows_11_business_editions_version_24h2_arm64_dvd_788c03e0.iso" ;;
|
||||||
|
"cs" | "cs-"* ) url="cs-cz_windows_11_business_editions_version_24h2_arm64_dvd_1f7bc350.iso" ;;
|
||||||
|
"da" | "da-"* ) url="da-dk_windows_11_business_editions_version_24h2_arm64_dvd_9d466587.iso" ;;
|
||||||
|
"de" | "de-"* ) url="de-de_windows_11_business_editions_version_24h2_arm64_dvd_c2e28d02.iso" ;;
|
||||||
|
"el" | "el-"* ) url="el-gr_windows_11_business_editions_version_24h2_arm64_dvd_549d89e0.iso" ;;
|
||||||
|
"gb" | "en-gb" ) url="en-gb_windows_11_business_editions_version_24h2_arm64_dvd_4b053a98.iso" ;;
|
||||||
|
"en" | "en-"* )
|
||||||
|
size=5388951552
|
||||||
|
sum="15ff94a99e89846c54316275f60ea697c9517e5dea7b3a963157a4c632524f72"
|
||||||
|
url="en-us_windows_11_business_editions_version_24h2_arm64_dvd_ad92e9d8.iso" ;;
|
||||||
|
"mx" | "es-mx" ) url="es-mx_windows_11_business_editions_version_24h2_arm64_dvd_2f7a4f0e.iso" ;;
|
||||||
|
"es" | "es-"* ) url="es-es_windows_11_business_editions_version_24h2_arm64_dvd_81ab0494.iso" ;;
|
||||||
|
"et" | "et-"* ) url="et-ee_windows_11_business_editions_version_24h2_arm64_dvd_49e9e4b9.iso" ;;
|
||||||
|
"fi" | "fi-"* ) url="fi-fi_windows_11_business_editions_version_24h2_arm64_dvd_18c415d6.iso" ;;
|
||||||
|
"ca" | "fr-ca" ) url="fr-ca_windows_11_business_editions_version_24h2_arm64_dvd_9de095b9.iso" ;;
|
||||||
|
"fr" | "fr-"* ) url="fr-fr_windows_11_business_editions_version_24h2_arm64_dvd_dadf21c7.iso" ;;
|
||||||
|
"he" | "he-"* ) url="he-il_windows_11_business_editions_version_24h2_arm64_dvd_a836dc29.iso" ;;
|
||||||
|
"hr" | "hr-"* ) url="hr-hr_windows_11_business_editions_version_24h2_arm64_dvd_8b68a3fd.iso" ;;
|
||||||
|
"hu" | "hu-"* ) url="hu-hu_windows_11_business_editions_version_24h2_arm64_dvd_0e1fd665.iso" ;;
|
||||||
|
"it" | "it-"* ) url="it-it_windows_11_business_editions_version_24h2_arm64_dvd_c4e7511f.iso" ;;
|
||||||
|
"ja" | "ja-"* ) url="ja-jp_windows_11_business_editions_version_24h2_arm64_dvd_28e70c96.iso" ;;
|
||||||
|
"ko" | "ko-"* ) url="ko-kr_windows_11_business_editions_version_24h2_arm64_dvd_739157b9.iso" ;;
|
||||||
|
"lt" | "lt-"* ) url="lt-lt_windows_11_business_editions_version_24h2_arm64_dvd_896253e8.iso" ;;
|
||||||
|
"lv" | "lv-"* ) url="lv-lv_windows_11_business_editions_version_24h2_arm64_dvd_e5fd8399.iso" ;;
|
||||||
|
"nb" | "nb-"* ) url="nb-no_windows_11_business_editions_version_24h2_arm64_dvd_698e7791.iso" ;;
|
||||||
|
"nl" | "nl-"* ) url="nl-nl_windows_11_business_editions_version_24h2_arm64_dvd_7e6e0919.iso" ;;
|
||||||
|
"pl" | "pl-"* ) url="pl-pl_windows_11_business_editions_version_24h2_arm64_dvd_b297967a.iso" ;;
|
||||||
|
"br" | "pt-br" ) url="pt-br_windows_11_business_editions_version_24h2_arm64_dvd_7011721a.iso" ;;
|
||||||
|
"pt" | "pt-"* ) url="pt-pt_windows_11_business_editions_version_24h2_arm64_dvd_221e64a5.iso" ;;
|
||||||
|
"ro" | "ro-"* ) url="ro-ro_windows_11_business_editions_version_24h2_arm64_dvd_82cbceb3.iso" ;;
|
||||||
|
"ru" | "ru-"* ) url="ru-ru_windows_11_business_editions_version_24h2_arm64_dvd_6ab7f1a4.iso" ;;
|
||||||
|
"sk" | "sk-"* ) url="sk-sk_windows_11_business_editions_version_24h2_arm64_dvd_04ce533b.iso" ;;
|
||||||
|
"sl" | "sl-"* ) url="sl-si_windows_11_business_editions_version_24h2_arm64_dvd_dd345ed1.iso" ;;
|
||||||
|
"sr" | "sr-"* ) url="sr-latn-rs_windows_11_business_editions_version_24h2_arm64_dvd_f2b86976.iso" ;;
|
||||||
|
"sv" | "sv-"* ) url="sv-se_windows_11_business_editions_version_24h2_arm64_dvd_88f0e36f.iso" ;;
|
||||||
|
"th" | "th-"* ) url="th-th_windows_11_business_editions_version_24h2_arm64_dvd_9c714026.iso" ;;
|
||||||
|
"tr" | "tr-"* ) url="tr-tr_windows_11_business_editions_version_24h2_arm64_dvd_4da6f82d.iso" ;;
|
||||||
|
"uk" | "uk-"* ) url="uk-ua_windows_11_business_editions_version_24h2_arm64_dvd_65304891.iso" ;;
|
||||||
|
"zh-hk" | "zh-tw" ) url="zh-tw_windows_11_business_editions_version_24h2_arm64_dvd_99a82a4f.iso" ;;
|
||||||
|
"zh" | "zh-"* ) url="zh-cn_windows_11_business_editions_version_24h2_arm64_dvd_9696a5e8.iso" ;;
|
||||||
|
esac
|
||||||
;;
|
;;
|
||||||
"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="en-us_windows_11_iot_enterprise_ltsc_2024_arm64_dvd_ec517836.iso"
|
||||||
;;
|
;;
|
||||||
"win10arm64" | "win10arm64-enterprise" | "win10arm64-enterprise-eval" )
|
"win10arm64" | "win10arm64-enterprise" | "win10arm64-enterprise-eval" )
|
||||||
size=4689637376
|
case "${culture,,}" in
|
||||||
sum="7b43e64f4e3b961a83f9b70efa4b9d863bc5c348fe86d75917ac974116d17227"
|
"ar" | "ar-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Arabic_Pro_Ent_EDU_N_MLF_X23-67213.ISO" ;;
|
||||||
url="10/en-us_windows_10_22h2_arm64.iso"
|
"bg" | "bg-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Bulgarian_Pro_Ent_EDU_N_MLF_X23-67215.ISO" ;;
|
||||||
|
"cs" | "cs-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Czech_Pro_Ent_EDU_N_MLF_X23-67219.ISO" ;;
|
||||||
|
"da" | "da-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Danish_Pro_Ent_EDU_N_MLF_X23-67220.ISO" ;;
|
||||||
|
"de" | "de-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_German_Pro_Ent_EDU_N_MLF_X23-67228.ISO" ;;
|
||||||
|
"el" | "el-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Greek_Pro_Ent_EDU_N_MLF_X23-67229.ISO" ;;
|
||||||
|
"gb" | "en-gb" ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Eng_Intl_Pro_Ent_EDU_N_MLF_X23-67222.ISO" ;;
|
||||||
|
"en" | "en-"* )
|
||||||
|
size=5190453248
|
||||||
|
sum="bd96b342193f81c0a2e6595d8d8b8dc01dbf789d19211699f6299fec7b712197"
|
||||||
|
url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_English_Pro_Ent_EDU_N_MLF_X23-67223.ISO" ;;
|
||||||
|
"mx" | "es-mx" ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Spanish_Latam_Pro_Ent_EDU_N_MLF_X23-67245.ISO" ;;
|
||||||
|
"es" | "es-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Spanish_Pro_Ent_EDU_N_MLF_X23-67246.ISO" ;;
|
||||||
|
"et" | "et-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Estonian_Pro_Ent_EDU_N_MLF_X23-67224.ISO" ;;
|
||||||
|
"fi" | "fi-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Finnish_Pro_Ent_EDU_N_MLF_X23-67225.ISO" ;;
|
||||||
|
"ca" | "fr-ca" ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_FrenchCanadian_Pro_Ent_EDU_N_MLF_X23-67227.ISO" ;;
|
||||||
|
"fr" | "fr-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_French_Pro_Ent_EDU_N_MLF_X23-67226.ISO" ;;
|
||||||
|
"he" | "he-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Hebrew_Pro_Ent_EDU_N_MLF_X23-67230.ISO" ;;
|
||||||
|
"hr" | "hr-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Croatian_Pro_Ent_EDU_N_MLF_X23-67218.ISO" ;;
|
||||||
|
"hu" | "hu-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Hungarian_Pro_Ent_EDU_N_MLF_X23-67231.ISO" ;;
|
||||||
|
"it" | "it-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Italian_Pro_Ent_EDU_N_MLF_X23-67232.ISO" ;;
|
||||||
|
"ja" | "ja-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Japanese_Pro_Ent_EDU_N_MLF_X23-67233.ISO" ;;
|
||||||
|
"ko" | "ko-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Korean_Pro_Ent_EDU_N_MLF_X23-67234.ISO" ;;
|
||||||
|
"lt" | "lt-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Lithuanian_Pro_Ent_EDU_N_MLF_X23-67236.ISO" ;;
|
||||||
|
"lv" | "lv-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Latvian_Pro_Ent_EDU_N_MLF_X23-67235.ISO" ;;
|
||||||
|
"nb" | "nb-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Norwegian_Pro_Ent_EDU_N_MLF_X23-67237.ISO" ;;
|
||||||
|
"nl" | "nl-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Dutch_Pro_Ent_EDU_N_MLF_X23-67221.ISO" ;;
|
||||||
|
"pl" | "pl-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Polish_Pro_Ent_EDU_N_MLF_X23-67238.ISO" ;;
|
||||||
|
"br" | "pt-br" ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Brazilian_Pro_Ent_EDU_N_MLF_X23-67214.ISO" ;;
|
||||||
|
"pt" | "pt-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Portuguese_Pro_Ent_EDU_N_MLF_X23-67239.ISO" ;;
|
||||||
|
"ro" | "ro-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Romanian_Pro_Ent_EDU_N_MLF_X23-67240.ISO" ;;
|
||||||
|
"ru" | "ru-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Russian_Pro_Ent_EDU_N_MLF_X23-67241.ISO" ;;
|
||||||
|
"sk" | "sk-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Slovak_Pro_Ent_EDU_N_MLF_X23-67243.ISO" ;;
|
||||||
|
"sl" | "sl-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Slovenian_Pro_Ent_EDU_N_MLF_X23-67244.ISO" ;;
|
||||||
|
"sr" | "sr-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Serbian_Latin_Pro_Ent_EDU_N_MLF_X23-67242.ISO" ;;
|
||||||
|
"sv" | "sv-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Swedish_Pro_Ent_EDU_N_MLF_X23-67247.ISO" ;;
|
||||||
|
"th" | "th-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Thai_Pro_Ent_EDU_N_MLF_X23-67248.ISO" ;;
|
||||||
|
"tr" | "tr-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Turkish_Pro_Ent_EDU_N_MLF_X23-67249.ISO" ;;
|
||||||
|
"uk" | "uk-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_Ukrainian_Pro_Ent_EDU_N_MLF_X23-67250.ISO" ;;
|
||||||
|
"zh-hk" | "zh-tw" ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_ChnTrad_Pro_Ent_EDU_N_MLF_X23-67217.ISO" ;;
|
||||||
|
"zh" | "zh-"* ) url="SW_DVD9_Win_Pro_10_22H2.15_Arm64_ChnSimp_Pro_Ent_EDU_N_MLF_X23-67216.ISO" ;;
|
||||||
|
esac
|
||||||
;;
|
;;
|
||||||
"win10arm64-ltsc" | "win10arm64-enterprise-ltsc-eval" )
|
"win10arm64-ltsc" | "win10arm64-enterprise-ltsc-eval" )
|
||||||
|
[[ "${lang,,}" != "en" ]] && [[ "${lang,,}" != "en-us" ]] && return 0
|
||||||
size=4430471168
|
size=4430471168
|
||||||
sum="d265df49b30a1477d010c79185a7bc88591a1be4b3eb690c994bed828ea17c00"
|
sum="d265df49b30a1477d010c79185a7bc88591a1be4b3eb690c994bed828ea17c00"
|
||||||
url="10/en-us_windows_10_iot_enterprise_ltsc_2021_arm64_dvd_e8d4fc46.iso"
|
url="en-us_windows_10_iot_enterprise_ltsc_2021_arm64_dvd_e8d4fc46.iso"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -624,51 +683,39 @@ getLink1() {
|
||||||
|
|
||||||
getLink2() {
|
getLink2() {
|
||||||
|
|
||||||
|
# Fallbacks for users who cannot connect to the Microsoft servers
|
||||||
|
|
||||||
local id="$1"
|
local id="$1"
|
||||||
local lang="$2"
|
local lang="$2"
|
||||||
local ret="$3"
|
local ret="$3"
|
||||||
local url=""
|
local url=""
|
||||||
local sum=""
|
local sum=""
|
||||||
local size=""
|
local size=""
|
||||||
local host="https://archive.org/download"
|
local host="https://dl.bobpony.com/windows"
|
||||||
|
|
||||||
[[ "${lang,,}" != "en" ]] && [[ "${lang,,}" != "en-us" ]] && return 0
|
[[ "${lang,,}" != "en" ]] && [[ "${lang,,}" != "en-us" ]] && return 0
|
||||||
|
|
||||||
case "${id,,}" in
|
case "${id,,}" in
|
||||||
"tiny11" )
|
"win11arm64" | "win11arm64-enterprise" | "win11arm64-enterprise-eval" )
|
||||||
size=4480499712
|
size=6326812672
|
||||||
sum="ec6056aa554c17290224af23e1b99961fe99606bb5ea9102d61838939c63325b"
|
sum="464c75909b9c37864e144886445a2faa67ac86f0845a68cca3f017b97f810e8d"
|
||||||
url="tiny11a64/tiny11a64%20r1.iso"
|
url="11/en-us_windows_11_23h2_arm64.iso"
|
||||||
;;
|
|
||||||
"core11" )
|
|
||||||
size=3300327424
|
|
||||||
sum="812dae6b5bf5215db63b61ae10d8f0ffd3aa8529a18d96e9ced53341e2c676ec"
|
|
||||||
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" )
|
"win11arm64-ltsc" | "win11arm64-enterprise-ltsc-eval" )
|
||||||
|
[[ "${lang,,}" != "en" ]] && [[ "${lang,,}" != "en-us" ]] && return 0
|
||||||
size=5121449984
|
size=5121449984
|
||||||
sum="f8f068cdc90c894a55d8c8530db7c193234ba57bb11d33b71383839ac41246b4"
|
sum="f8f068cdc90c894a55d8c8530db7c193234ba57bb11d33b71383839ac41246b4"
|
||||||
url="Windows11LTSC/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=5192060928
|
size=4846794752
|
||||||
sum="101079b911c8c3dd9c9a88499a16b930fbf00cbaf901761d8265bb3a8fcd9ea9"
|
sum="6d2688f95fa1d359d68ed0c38c3f38de7b3713c893410e15be9d1e706a4a58c7"
|
||||||
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"
|
url="10/en-us_windows_10_22h2_arm64.iso"
|
||||||
;;
|
;;
|
||||||
"win10arm64-ltsc" | "win10arm64-enterprise-ltsc-eval" )
|
"win10arm64-ltsc" | "win10arm64-enterprise-ltsc-eval" )
|
||||||
size=4430471168
|
size=4430471168
|
||||||
sum="d265df49b30a1477d010c79185a7bc88591a1be4b3eb690c994bed828ea17c00"
|
sum="d265df49b30a1477d010c79185a7bc88591a1be4b3eb690c994bed828ea17c00"
|
||||||
url="windows-10-enterprise-ltsc-full-collection/en-us_windows_10_iot_enterprise_ltsc_2021_arm64_dvd_e8d4fc46.iso"
|
url="10/en-us_windows_10_iot_enterprise_ltsc_2021_arm64_dvd_e8d4fc46.iso"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -793,12 +840,16 @@ 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 -print -quit)
|
file=$(find "$dest" -maxdepth 1 -type f -iname install.bat | head -n 1)
|
||||||
[ -f "$file" ] && unix2dos -q "$file"
|
[ -f "$file" ] && unix2dos -q "$file"
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
migrateFiles() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
detectLegacy() {
|
detectLegacy() {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
16
src/entry.sh
16
src/entry.sh
|
@ -1,18 +1,16 @@
|
||||||
#!/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 Windows
|
. mido.sh # Download code
|
||||||
. install.sh # Run installation
|
. install.sh # Run installation
|
||||||
. disk.sh # Initialize disks
|
. disk.sh # Initialize disks
|
||||||
. display.sh # Initialize graphics
|
. display.sh # Initialize graphics
|
||||||
|
@ -39,10 +37,8 @@ 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" &
|
||||||
sed -u -e 's/\x1B\[[=0-9;]*[a-z]//gi' \
|
wait $! || :
|
||||||
-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
|
||||||
|
|
265
src/install.sh
265
src/install.sh
|
@ -10,31 +10,21 @@ 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
|
||||||
if [[ "${STORAGE,,}/${previous,,}" != "${iso,,}" ]]; then
|
previous="$STORAGE/$previous"
|
||||||
|
if [[ "${previous,,}" != "${iso,,}" ]]; then
|
||||||
if [ -f "$boot" ] && hasDisk; then
|
if [ -f "$boot" ] && hasDisk; then
|
||||||
if [[ "${iso,,}" == "${STORAGE,,}/windows."* ]]; then
|
info "Detected that the version was changed, but ignoring this because Windows is already installed."
|
||||||
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
|
||||||
rm -f "$STORAGE/$previous"
|
[ -f "$previous" ] && rm -f "$previous"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -86,6 +76,8 @@ startInstall() {
|
||||||
|
|
||||||
BOOT="$STORAGE/$file"
|
BOOT="$STORAGE/$file"
|
||||||
|
|
||||||
|
! migrateFiles "$BOOT" "$VERSION" && error "Migration failed!" && exit 57
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
skipInstall "$BOOT" && return 1
|
skipInstall "$BOOT" && return 1
|
||||||
|
@ -128,9 +120,6 @@ 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.base"
|
rm -f "$STORAGE/windows.base"
|
||||||
rm -f "$STORAGE/windows.boot"
|
rm -f "$STORAGE/windows.boot"
|
||||||
rm -f "$STORAGE/windows.mode"
|
rm -f "$STORAGE/windows.mode"
|
||||||
|
@ -167,27 +156,10 @@ finishInstall() {
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "${ARGS:-}" ]; then
|
|
||||||
ARGUMENTS="$ARGS ${ARGUMENTS:-}"
|
|
||||||
echo "$ARGS" > "$STORAGE/windows.args"
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
@ -199,9 +171,8 @@ 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 -print -quit)
|
efi=$(find "$dir" -maxdepth 1 -type d -iname efi | head -n 1)
|
||||||
|
|
||||||
if [ -z "$efi" ]; then
|
if [ -z "$efi" ]; then
|
||||||
[[ "${PLATFORM,,}" == "x64" ]] && BOOT_MODE="windows_legacy"
|
[[ "${PLATFORM,,}" == "x64" ]] && BOOT_MODE="windows_legacy"
|
||||||
|
@ -222,23 +193,13 @@ abortInstall() {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
findFile() {
|
detectCustom() {
|
||||||
|
|
||||||
local dir file base
|
local file base
|
||||||
local fname="$1"
|
CUSTOM=""
|
||||||
local boot="$STORAGE/windows.boot"
|
|
||||||
|
|
||||||
dir=$(find / -maxdepth 1 -type d -iname "$fname" -print -quit)
|
file=$(find / -maxdepth 1 -type f -iname custom.iso | head -n 1)
|
||||||
[ ! -d "$dir" ] && dir=$(find "$STORAGE" -maxdepth 1 -type d -iname "$fname" -print -quit)
|
[ ! -s "$file" ] && file=$(find "$STORAGE" -maxdepth 1 -type f -iname custom.iso | head -n 1)
|
||||||
|
|
||||||
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")
|
||||||
|
@ -254,25 +215,12 @@ findFile() {
|
||||||
[ -z "$size" ] || [[ "$size" == "0" ]] && return 0
|
[ -z "$size" ] || [[ "$size" == "0" ]] && return 0
|
||||||
|
|
||||||
ISO="$file"
|
ISO="$file"
|
||||||
CUSTOM="$file"
|
CUSTOM="$ISO"
|
||||||
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"
|
||||||
|
@ -292,12 +240,12 @@ extractESD() {
|
||||||
mkdir -p "$dir"
|
mkdir -p "$dir"
|
||||||
|
|
||||||
size=16106127360
|
size=16106127360
|
||||||
size_gb=$(formatBytes "$size")
|
size_gb=$(( (size + 1073741823)/1073741824 ))
|
||||||
space=$(df --output=avail -B 1 "$dir" | tail -n 1)
|
space=$(df --output=avail -B 1 "$dir" | tail -n 1)
|
||||||
space_gb=$(formatBytes "$space")
|
space_gb=$(( (space + 1073741823)/1073741824 ))
|
||||||
|
|
||||||
if (( size > space )); then
|
if (( size > space )); then
|
||||||
error "Not enough free space in $STORAGE, have $space_gb available but need at least $size_gb." && return 1
|
error "Not enough free space in $STORAGE, have $space_gb GB available but need at least $size_gb GB." && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local esdImageCount
|
local esdImageCount
|
||||||
|
@ -362,7 +310,7 @@ extractImage() {
|
||||||
local dir="$2"
|
local dir="$2"
|
||||||
local version="$3"
|
local version="$3"
|
||||||
local desc="local ISO"
|
local desc="local ISO"
|
||||||
local file size size_gb space space_gb
|
local size size_gb space space_gb
|
||||||
|
|
||||||
if [ -z "$CUSTOM" ]; then
|
if [ -z "$CUSTOM" ]; then
|
||||||
desc="downloaded ISO"
|
desc="downloaded ISO"
|
||||||
|
@ -383,16 +331,16 @@ extractImage() {
|
||||||
mkdir -p "$dir"
|
mkdir -p "$dir"
|
||||||
|
|
||||||
size=$(stat -c%s "$iso")
|
size=$(stat -c%s "$iso")
|
||||||
size_gb=$(formatBytes "$size")
|
size_gb=$(( (size + 1073741823)/1073741824 ))
|
||||||
space=$(df --output=avail -B 1 "$dir" | tail -n 1)
|
space=$(df --output=avail -B 1 "$dir" | tail -n 1)
|
||||||
space_gb=$(formatBytes "$space")
|
space_gb=$(( (space + 1073741823)/1073741824 ))
|
||||||
|
|
||||||
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 available but need at least $size_gb." && return 1
|
error "Not enough free space in $STORAGE, have $space_gb GB available but need at least $size_gb GB." && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -rf "$dir"
|
rm -rf "$dir"
|
||||||
|
@ -401,27 +349,8 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,10 +483,6 @@ 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"
|
||||||
|
@ -602,14 +527,14 @@ detectImage() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local src wim info
|
local src wim info
|
||||||
src=$(find "$dir" -maxdepth 1 -type d -iname sources -print -quit)
|
src=$(find "$dir" -maxdepth 1 -type d -iname sources | head -n 1)
|
||||||
|
|
||||||
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 -print -quit)
|
wim=$(find "$src" -maxdepth 1 -type f -iname install.wim | head -n 1)
|
||||||
[ ! -f "$wim" ] && wim=$(find "$src" -maxdepth 1 -type f -iname install.esd -print -quit)
|
[ ! -f "$wim" ] && wim=$(find "$src" -maxdepth 1 -type f -iname install.esd | head -n 1)
|
||||||
|
|
||||||
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
|
||||||
|
@ -642,10 +567,6 @@ 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"
|
||||||
|
|
||||||
|
@ -693,15 +614,11 @@ 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
|
[ -z "$YRES" ] && YRES="720"
|
||||||
sed -i "s/ 20.20.20.1 / ${VM_NET_IP%.*}.1 /g" "$asset"
|
[ -z "$XRES" ] && XRES="1280"
|
||||||
fi
|
|
||||||
|
|
||||||
[ -z "$HEIGHT" ] && HEIGHT="720"
|
sed -i "s/<VerticalResolution>1080<\/VerticalResolution>/<VerticalResolution>$YRES<\/VerticalResolution>/g" "$asset"
|
||||||
[ -z "$WIDTH" ] && WIDTH="1280"
|
sed -i "s/<HorizontalResolution>1920<\/HorizontalResolution>/<HorizontalResolution>$XRES<\/HorizontalResolution>/g" "$asset"
|
||||||
|
|
||||||
sed -i "s/<VerticalResolution>1080<\/VerticalResolution>/<VerticalResolution>$HEIGHT<\/VerticalResolution>/g" "$asset"
|
|
||||||
sed -i "s/<HorizontalResolution>1920<\/HorizontalResolution>/<HorizontalResolution>$WIDTH<\/HorizontalResolution>/g" "$asset"
|
|
||||||
|
|
||||||
culture=$(getLanguage "$language" "culture")
|
culture=$(getLanguage "$language" "culture")
|
||||||
|
|
||||||
|
@ -734,26 +651,15 @@ 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
|
||||||
|
|
||||||
[ -n "$PASSWORD" ] && pass="$PASSWORD" || pass="admin"
|
if [ -n "$PASSWORD" ]; then
|
||||||
|
pass=$(printf '%s' "${PASSWORD}Password" | 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' "${PASSWORD}AdministratorPassword" | 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>$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/<Password>...............<Value \/>/<Password>\n <Value>$pass<\/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"
|
||||||
|
|
||||||
if [ -n "$EDITION" ]; then
|
|
||||||
[[ "${EDITION^^}" == "CORE" ]] && EDITION="STANDARDCORE"
|
|
||||||
sed -i "s/SERVERSTANDARD<\/Value>/SERVER${EDITION^^}<\/Value>/g" "$asset"
|
|
||||||
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
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -765,13 +671,8 @@ addDriver() {
|
||||||
local path="$2"
|
local path="$2"
|
||||||
local target="$3"
|
local target="$3"
|
||||||
local driver="$4"
|
local driver="$4"
|
||||||
local desc=""
|
|
||||||
local folder=""
|
local folder=""
|
||||||
|
|
||||||
if [ -z "$id" ]; then
|
|
||||||
warn "no Windows version specified for \"$driver\" driver!" && return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "${id,,}" in
|
case "${id,,}" in
|
||||||
"win7x86"* ) folder="w7/x86" ;;
|
"win7x86"* ) folder="w7/x86" ;;
|
||||||
"win7x64"* ) folder="w7/amd64" ;;
|
"win7x64"* ) folder="w7/amd64" ;;
|
||||||
|
@ -791,12 +692,7 @@ addDriver() {
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [ -z "$folder" ]; then
|
if [ -z "$folder" ]; then
|
||||||
desc=$(printVersion "$id" "$id")
|
warn "no \"$driver\" driver found for \"$DETECTED\" !" && return 0
|
||||||
if [[ "${id,,}" != *"x86"* ]]; then
|
|
||||||
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
|
||||||
|
@ -829,12 +725,7 @@ addDrivers() {
|
||||||
local msg="Adding drivers to image..."
|
local msg="Adding drivers to image..."
|
||||||
info "$msg" && html "$msg"
|
info "$msg" && html "$msg"
|
||||||
|
|
||||||
if [ -z "$version" ]; then
|
if ! bsdtar -xf /drivers.txz -C "$drivers"; then
|
||||||
version="win11x64"
|
|
||||||
warn "Windows version unknown, falling back to Windows 11 drivers..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
@ -847,7 +738,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
|
||||||
addDriver "$version" "$drivers" "$target" "smbus" || return 1
|
# Disable temporarily : 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
|
||||||
|
@ -855,7 +746,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
|
||||||
addDriver "$version" "$drivers" "$target" "pvpanic" || return 1
|
# Disable temporarily : 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
|
||||||
|
@ -903,14 +794,14 @@ updateImage() {
|
||||||
rm -rf "$tmp"
|
rm -rf "$tmp"
|
||||||
mkdir -p "$tmp"
|
mkdir -p "$tmp"
|
||||||
|
|
||||||
src=$(find "$dir" -maxdepth 1 -type d -iname sources -print -quit)
|
src=$(find "$dir" -maxdepth 1 -type d -iname sources | head -n 1)
|
||||||
|
|
||||||
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 -print -quit)
|
wim=$(find "$src" -maxdepth 1 -type f -iname boot.wim | head -n 1)
|
||||||
[ ! -f "$wim" ] && wim=$(find "$src" -maxdepth 1 -type f -iname boot.esd -print -quit)
|
[ ! -f "$wim" ] && wim=$(find "$src" -maxdepth 1 -type f -iname boot.esd | head -n 1)
|
||||||
|
|
||||||
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
|
||||||
|
@ -973,7 +864,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" -print -quit)
|
path=$(find "$dir" -maxdepth 1 -type f -iname "$find" | head -n 1)
|
||||||
|
|
||||||
if [ -f "$path" ]; then
|
if [ -f "$path" ]; then
|
||||||
if [[ "$MANUAL" != [Yy1]* ]]; then
|
if [[ "$MANUAL" != [Yy1]* ]]; then
|
||||||
|
@ -1027,12 +918,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=$(formatBytes "$size")
|
size_gb=$(( (size + 1073741823)/1073741824 ))
|
||||||
space=$(df --output=avail -B 1 "$TMP" | tail -n 1)
|
space=$(df --output=avail -B 1 "$TMP" | tail -n 1)
|
||||||
space_gb=$(formatBytes "$space")
|
space_gb=$(( (space + 1073741823)/1073741824 ))
|
||||||
|
|
||||||
if (( size > space )); then
|
if (( size > space )); then
|
||||||
error "Not enough free space in $STORAGE, have $space_gb available but need at least $size_gb." && return 1
|
error "Not enough free space in $STORAGE, have $space_gb GB available but need at least $size_gb GB." && return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "${BOOT_MODE,,}" != "windows_legacy" ]]; then
|
if [[ "${BOOT_MODE,,}" != "windows_legacy" ]]; then
|
||||||
|
@ -1074,49 +965,49 @@ bootWindows() {
|
||||||
|
|
||||||
rm -rf "$TMP"
|
rm -rf "$TMP"
|
||||||
|
|
||||||
if [ -f "$STORAGE/windows.args" ]; then
|
|
||||||
ARGS=$(<"$STORAGE/windows.args")
|
|
||||||
ARGS="${ARGS//[![:print:]]/}"
|
|
||||||
ARGUMENTS="$ARGS ${ARGUMENTS:-}"
|
|
||||||
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
|
||||||
if [ -z "${DISK_TYPE:-}" ]; then
|
[ -z "${DISK_TYPE:-}" ] && DISK_TYPE=$(<"$STORAGE/windows.type")
|
||||||
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:]]/}"
|
if [ -s "$STORAGE/windows.old" ] && [ -f "$STORAGE/windows.old" ]; then
|
||||||
|
[[ "${PLATFORM,,}" == "x64" ]] && MACHINE=$(<"$STORAGE/windows.old")
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -s "$STORAGE/windows.old" ] && [ -f "$STORAGE/windows.old" ]; then
|
# Migrations
|
||||||
if [[ "${PLATFORM,,}" == "x64" ]]; then
|
|
||||||
|
[[ "${PLATFORM,,}" != "x64" ]] && return 0
|
||||||
|
|
||||||
|
if [ -f "$STORAGE/windows.old" ]; then
|
||||||
MACHINE=$(<"$STORAGE/windows.old")
|
MACHINE=$(<"$STORAGE/windows.old")
|
||||||
MACHINE="${MACHINE//[![:print:]]/}"
|
[ -z "$MACHINE" ] && MACHINE="q35"
|
||||||
|
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
|
||||||
|
|
||||||
|
|
215
src/mido.sh
215
src/mido.sh
|
@ -4,26 +4,25 @@ set -Eeuo pipefail
|
||||||
handle_curl_error() {
|
handle_curl_error() {
|
||||||
|
|
||||||
local error_code="$1"
|
local error_code="$1"
|
||||||
local server_name="$2"
|
|
||||||
|
|
||||||
case "$error_code" in
|
case "$error_code" in
|
||||||
1) error "Unsupported protocol!" ;;
|
1) error "Unsupported protocol!" ;;
|
||||||
2) error "Failed to initialize curl!" ;;
|
2) error "Failed to initialize curl!" ;;
|
||||||
3) error "The URL format is malformed!" ;;
|
3) error "The URL format is malformed!" ;;
|
||||||
5) error "Failed to resolve address of proxy host!" ;;
|
5) error "Failed to resolve address of proxy host!" ;;
|
||||||
6) error "Failed to resolve $server_name servers! Is there an Internet connection?" ;;
|
6) error "Failed to resolve Microsoft servers! Is there an Internet connection?" ;;
|
||||||
7) error "Failed to contact $server_name servers! Is there an Internet connection or is the server down?" ;;
|
7) error "Failed to contact Microsoft servers! Is there an Internet connection or is the server down?" ;;
|
||||||
8) error "$server_name servers returned a malformed HTTP response!" ;;
|
8) error "Microsoft servers returned a malformed HTTP response!" ;;
|
||||||
16) error "A problem was detected in the HTTP2 framing layer!" ;;
|
16) error "A problem was detected in the HTTP2 framing layer!" ;;
|
||||||
22) error "$server_name servers returned a failing HTTP status code!" ;;
|
22) error "Microsoft servers returned a failing HTTP status code!" ;;
|
||||||
23) error "Failed at writing Windows media to disk! Out of disk space or permission error?" ;;
|
23) error "Failed at writing Windows media to disk! Out of disk space or permission error?" ;;
|
||||||
26) error "Failed to read Windows media from disk!" ;;
|
26) error "Failed to read Windows media from disk!" ;;
|
||||||
27) error "Ran out of memory during download!" ;;
|
27) error "Ran out of memory during download!" ;;
|
||||||
28) error "Connection timed out to $server_name server!" ;;
|
28) error "Connection timed out to Microsoft server!" ;;
|
||||||
35) error "SSL connection error from $server_name server!" ;;
|
35) error "SSL connection error from Microsoft server!" ;;
|
||||||
36) error "Failed to continue earlier download!" ;;
|
36) error "Failed to continue earlier download!" ;;
|
||||||
52) error "Received no data from the $server_name server!" ;;
|
52) error "Received no data from the Microsoft server!" ;;
|
||||||
63) error "$server_name servers returned an unexpectedly large response!" ;;
|
63) error "Microsoft servers returned an unexpectedly large response!" ;;
|
||||||
# POSIX defines exit statuses 1-125 as usable by us
|
# POSIX defines exit statuses 1-125 as usable by us
|
||||||
# https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02
|
# https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02
|
||||||
$((error_code <= 125)))
|
$((error_code <= 125)))
|
||||||
|
@ -64,75 +63,77 @@ download_windows() {
|
||||||
local lang="$2"
|
local lang="$2"
|
||||||
local desc="$3"
|
local desc="$3"
|
||||||
local sku_id=""
|
local sku_id=""
|
||||||
local sku_url=""
|
|
||||||
local iso_url=""
|
|
||||||
local iso_json=""
|
|
||||||
local language=""
|
local language=""
|
||||||
local session_id=""
|
local session_id=""
|
||||||
local user_agent=""
|
local user_agent=""
|
||||||
local download_type=""
|
|
||||||
local windows_version=""
|
local windows_version=""
|
||||||
local iso_download_link=""
|
local iso_download_link=""
|
||||||
local download_page_html=""
|
|
||||||
local product_edition_id=""
|
local product_edition_id=""
|
||||||
local language_skuid_json=""
|
local iso_download_link_html=""
|
||||||
local profile="606624d44113"
|
local iso_download_page_html=""
|
||||||
|
local language_skuid_table_html=""
|
||||||
|
|
||||||
|
case "${id,,}" in
|
||||||
|
"win11x64" ) windows_version="11" ;;
|
||||||
|
"win10x64" ) windows_version="10" ;;
|
||||||
|
"win81x64" ) windows_version="8" ;;
|
||||||
|
* ) error "Invalid VERSION specified, value \"$id\" is not recognized!" && return 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
user_agent=$(get_agent)
|
user_agent=$(get_agent)
|
||||||
language=$(getLanguage "$lang" "name")
|
language=$(getLanguage "$lang" "name")
|
||||||
|
|
||||||
case "${id,,}" in
|
|
||||||
"win11x64" ) windows_version="11" && download_type="1" ;;
|
|
||||||
"win10x64" ) windows_version="10" && download_type="1" ;;
|
|
||||||
"win11arm64" ) windows_version="11arm64" && download_type="2" ;;
|
|
||||||
* ) error "Invalid VERSION specified, value \"$id\" is not recognized!" && return 1 ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
local url="https://www.microsoft.com/en-us/software-download/windows$windows_version"
|
local url="https://www.microsoft.com/en-us/software-download/windows$windows_version"
|
||||||
[[ "${id,,}" == "win10"* ]] && url+="ISO"
|
case "$windows_version" in
|
||||||
|
8 | 10) url+="ISO";;
|
||||||
|
esac
|
||||||
|
|
||||||
# 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
|
||||||
# This is the *only* request we make that Fido doesn't. Fido manually maintains a list of all the Windows release/edition product edition IDs in its script (see: $WindowsVersions array). This is helpful for downloading older releases (e.g. Windows 10 1909, 21H1, etc.) but we always want to get the newest release which is why we get this value dynamically
|
# This is the *only* request we make that Fido doesn't. Fido manually maintains a list of all the Windows release/edition product edition IDs in its script (see: $WindowsVersions array). This is helpful for downloading older releases (e.g. Windows 10 1909, 21H1, etc.) but we always want to get the newest release which is why we get this value dynamically
|
||||||
# Also, keeping a "$WindowsVersions" array like Fido does would be way too much of a maintenance burden
|
# Also, keeping a "$WindowsVersions" array like Fido does would be way too much of a maintenance burden
|
||||||
# Remove "Accept" header that curl sends by default
|
# Remove "Accept" header that curl sends by default
|
||||||
[[ "$DEBUG" == [Yy1]* ]] && echo "Parsing download page: ${url}"
|
[[ "$DEBUG" == [Yy1]* ]] && echo " - Parsing download page: ${url}"
|
||||||
download_page_html=$(curl --silent --max-time 30 --user-agent "$user_agent" --header "Accept:" --max-filesize 1M --fail --proto =https --tlsv1.2 --http1.1 -- "$url") || {
|
iso_download_page_html=$(curl --silent --max-time 30 --user-agent "$user_agent" --header "Accept:" --max-filesize 1M --fail --proto =https --tlsv1.2 --http1.1 -- "$url") || {
|
||||||
handle_curl_error "$?" "Microsoft"
|
handle_curl_error $?
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ "$DEBUG" == [Yy1]* ]] && echo -n "Getting Product edition ID: "
|
[[ "$DEBUG" == [Yy1]* ]] && echo -n "Getting Product edition ID: "
|
||||||
product_edition_id=$(echo "$download_page_html" | grep -Eo '<option value="[0-9]+">Windows' | cut -d '"' -f 2 | head -n 1 | tr -cd '0-9' | head -c 16)
|
# tr: Filter for only numerics to prevent HTTP parameter injection
|
||||||
|
# head -c was recently added to POSIX: https://austingroupbugs.net/view.php?id=407
|
||||||
|
product_edition_id=$(echo "$iso_download_page_html" | grep -Eo '<option value="[0-9]+">Windows' | cut -d '"' -f 2 | head -n 1 | tr -cd '0-9' | head -c 16)
|
||||||
[[ "$DEBUG" == [Yy1]* ]] && echo "$product_edition_id"
|
[[ "$DEBUG" == [Yy1]* ]] && echo "$product_edition_id"
|
||||||
|
|
||||||
if [ -z "$product_edition_id" ]; then
|
|
||||||
error "Product edition ID not found!"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
[[ "$DEBUG" == [Yy1]* ]] && echo "Permit Session ID: $session_id"
|
[[ "$DEBUG" == [Yy1]* ]] && echo "Permit Session ID: $session_id"
|
||||||
# Permit Session ID
|
# Permit Session ID
|
||||||
|
# "org_id" is always the same value
|
||||||
curl --silent --max-time 30 --output /dev/null --user-agent "$user_agent" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "https://vlscppe.microsoft.com/tags?org_id=y6jn8c31&session_id=$session_id" || {
|
curl --silent --max-time 30 --output /dev/null --user-agent "$user_agent" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "https://vlscppe.microsoft.com/tags?org_id=y6jn8c31&session_id=$session_id" || {
|
||||||
# This should only happen if there's been some change to how this API works
|
# This should only happen if there's been some change to how this API works
|
||||||
handle_curl_error "$?" "Microsoft"
|
handle_curl_error $?
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Extract everything after the last slash
|
||||||
|
local url_segment_parameter="${url##*/}"
|
||||||
|
|
||||||
[[ "$DEBUG" == [Yy1]* ]] && echo -n "Getting language SKU ID: "
|
[[ "$DEBUG" == [Yy1]* ]] && echo -n "Getting language SKU ID: "
|
||||||
sku_url="https://www.microsoft.com/software-download-connector/api/getskuinformationbyproductedition?profile=$profile&ProductEditionId=$product_edition_id&SKU=undefined&friendlyFileName=undefined&Locale=en-US&sessionID=$session_id"
|
# Get language -> skuID association table
|
||||||
language_skuid_json=$(curl --silent --max-time 30 --request GET --user-agent "$user_agent" --referer "$url" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "$sku_url") || {
|
# SKU ID: This specifies the language of the ISO. We always use "English (United States)", however, the SKU for this changes with each Windows release
|
||||||
handle_curl_error "$?" "Microsoft"
|
# We must make this request so our next one will be allowed
|
||||||
|
# --data "" is required otherwise no "Content-Length" header will be sent causing HTTP response "411 Length Required"
|
||||||
|
language_skuid_table_html=$(curl --silent --max-time 30 --request POST --user-agent "$user_agent" --data "" --header "Accept:" --max-filesize 10K --fail --proto =https --tlsv1.2 --http1.1 -- "https://www.microsoft.com/en-US/api/controls/contentinclude/html?pageId=a8f8f489-4c7f-463a-9ca6-5cff94d8d041&host=www.microsoft.com&segments=software-download,$url_segment_parameter&query=&action=getskuinformationbyproductedition&sessionId=$session_id&productEditionId=$product_edition_id&sdVersion=2") || {
|
||||||
|
handle_curl_error $?
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
{ sku_id=$(echo "$language_skuid_json" | jq --arg LANG "$language" -r '.Skus[] | select(.Language==$LANG).Id') 2>/dev/null; rc=$?; } || :
|
# tr: Filter for only alphanumerics or "-" to prevent HTTP parameter injection
|
||||||
|
sku_id=$(echo "$language_skuid_table_html" | grep -m 1 ">${language}<" | sed 's/"//g' | cut -d ',' -f 1 | cut -d ':' -f 2 | tr -cd '[:alnum:]-' | head -c 16)
|
||||||
|
|
||||||
if [ -z "$sku_id" ] || [[ "${sku_id,,}" == "null" ]] || (( rc != 0 )); then
|
if [ -z "$sku_id" ]; then
|
||||||
language=$(getLanguage "$lang" "desc")
|
language=$(getLanguage "$lang" "desc")
|
||||||
error "No download in the $language language available for $desc!"
|
error "No download in the $language language available for $desc!"
|
||||||
return 1
|
return 1
|
||||||
|
@ -143,31 +144,28 @@ download_windows() {
|
||||||
|
|
||||||
# Get ISO download link
|
# Get ISO download link
|
||||||
# If any request is going to be blocked by Microsoft it's always this last one (the previous requests always seem to succeed)
|
# If any request is going to be blocked by Microsoft it's always this last one (the previous requests always seem to succeed)
|
||||||
|
# --referer: Required by Microsoft servers to allow request
|
||||||
|
iso_download_link_html=$(curl --silent --max-time 30 --request POST --user-agent "$user_agent" --data "" --referer "$url" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "https://www.microsoft.com/en-US/api/controls/contentinclude/html?pageId=6e2a1789-ef16-4f27-a296-74ef7ef5d96b&host=www.microsoft.com&segments=software-download,$url_segment_parameter&query=&action=GetProductDownloadLinksBySku&sessionId=$session_id&skuId=$sku_id&language=English&sdVersion=2")
|
||||||
|
|
||||||
iso_url="https://www.microsoft.com/software-download-connector/api/GetProductDownloadLinksBySku?profile=$profile&ProductEditionId=undefined&SKU=$sku_id&friendlyFileName=undefined&Locale=en-US&sessionID=$session_id"
|
if ! [ "$iso_download_link_html" ]; then
|
||||||
iso_json=$(curl --silent --max-time 30 --request GET --user-agent "$user_agent" --referer "$url" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "$iso_url")
|
|
||||||
|
|
||||||
if ! [ "$iso_json" ]; then
|
|
||||||
# This should only happen if there's been some change to how this API works
|
# This should only happen if there's been some change to how this API works
|
||||||
error "Microsoft servers gave us an empty response to our request for an automated download."
|
error "Microsoft servers gave us an empty response to our request for an automated download."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if echo "$iso_json" | grep -q "Sentinel marked this request as rejected."; then
|
if echo "$iso_download_link_html" | grep -q "We are unable to complete your request at this time."; then
|
||||||
error "Microsoft blocked the automated download request based on your IP address."
|
error "Microsoft blocked the automated download request based on your IP address."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if echo "$iso_json" | grep -q "We are unable to complete your request at this time."; then
|
# Filter for 64-bit ISO download URL
|
||||||
error "Microsoft blocked the automated download request based on your IP address."
|
# sed: HTML decode "&" character
|
||||||
return 1
|
# tr: Filter for only alphanumerics or punctuation
|
||||||
fi
|
iso_download_link=$(echo "$iso_download_link_html" | grep -o "https://software.download.prss.microsoft.com.*IsoX64" | cut -d '"' -f 1 | sed 's/&/\&/g' | tr -cd '[:alnum:][:punct:]')
|
||||||
|
|
||||||
{ iso_download_link=$(echo "$iso_json" | jq --argjson TYPE "$download_type" -r '.ProductDownloadOptions[] | select(.DownloadType==$TYPE).Uri') 2>/dev/null; rc=$?; } || :
|
if ! [ "$iso_download_link" ]; then
|
||||||
|
# This should only happen if there's been some change to the download endpoint web address
|
||||||
if [ -z "$iso_download_link" ] || [[ "${iso_download_link,,}" == "null" ]] || (( rc != 0 )); then
|
|
||||||
error "Microsoft servers gave us no download link to our request for an automated download!"
|
error "Microsoft servers gave us no download link to our request for an automated download!"
|
||||||
info "Response: $iso_json"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -209,9 +207,6 @@ 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" ;;
|
||||||
|
@ -234,7 +229,7 @@ download_windows_eval() {
|
||||||
|
|
||||||
[[ "$DEBUG" == [Yy1]* ]] && echo "Parsing download page: ${url}"
|
[[ "$DEBUG" == [Yy1]* ]] && echo "Parsing download page: ${url}"
|
||||||
iso_download_page_html=$(curl --silent --max-time 30 --user-agent "$user_agent" --location --max-filesize 1M --fail --proto =https --tlsv1.2 --http1.1 -- "$url") || {
|
iso_download_page_html=$(curl --silent --max-time 30 --user-agent "$user_agent" --location --max-filesize 1M --fail --proto =https --tlsv1.2 --http1.1 -- "$url") || {
|
||||||
handle_curl_error "$?" "Microsoft"
|
handle_curl_error $?
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,10 +241,10 @@ download_windows_eval() {
|
||||||
|
|
||||||
[[ "$DEBUG" == [Yy1]* ]] && echo "Getting download link.."
|
[[ "$DEBUG" == [Yy1]* ]] && echo "Getting download link.."
|
||||||
|
|
||||||
filter="https://go.microsoft.com/fwlink/?linkid=[0-9]\+&clcid=0x[0-9a-z]\+&culture=${culture,,}&country=${country,,}"
|
if [[ "$enterprise_type" == "iot" ]]; then
|
||||||
|
filter="https://go.microsoft.com/fwlink/?linkid=[0-9]\+&clcid=0x[0-9a-z]\+&culture=${culture,,}&country=${country^^}"
|
||||||
if ! echo "$iso_download_page_html" | grep -io "$filter" > /dev/null; then
|
else
|
||||||
filter="https://go.microsoft.com/fwlink/p/?linkid=[0-9]\+&clcid=0x[0-9a-z]\+&culture=${culture,,}&country=${country,,}"
|
filter="https://go.microsoft.com/fwlink/p/?LinkID=[0-9]\+&clcid=0x[0-9a-z]\+&culture=${culture,,}&country=${country^^}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
iso_download_links=$(echo "$iso_download_page_html" | grep -io "$filter") || {
|
iso_download_links=$(echo "$iso_download_page_html" | grep -io "$filter") || {
|
||||||
|
@ -288,11 +283,11 @@ download_windows_eval() {
|
||||||
[[ "$DEBUG" == [Yy1]* ]] && echo "Found download link: $iso_download_link"
|
[[ "$DEBUG" == [Yy1]* ]] && echo "Found download link: $iso_download_link"
|
||||||
|
|
||||||
# Follow redirect so proceeding log message is useful
|
# Follow redirect so proceeding log message is useful
|
||||||
# This is a request we make that Fido doesn't
|
# This is a request we make this Fido doesn't
|
||||||
|
# We don't need to set "--max-filesize" here because this is a HEAD request and the output is to /dev/null anyway
|
||||||
iso_download_link=$(curl --silent --max-time 30 --user-agent "$user_agent" --location --output /dev/null --silent --write-out "%{url_effective}" --head --fail --proto =https --tlsv1.2 --http1.1 -- "$iso_download_link") || {
|
iso_download_link=$(curl --silent --max-time 30 --user-agent "$user_agent" --location --output /dev/null --silent --write-out "%{url_effective}" --head --fail --proto =https --tlsv1.2 --http1.1 -- "$iso_download_link") || {
|
||||||
# This should only happen if the Microsoft servers are down
|
# This should only happen if the Microsoft servers are down
|
||||||
handle_curl_error "$?" "Microsoft"
|
handle_curl_error $?
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +309,7 @@ getWindows() {
|
||||||
info "$msg" && html "$msg"
|
info "$msg" && html "$msg"
|
||||||
|
|
||||||
case "${version,,}" in
|
case "${version,,}" in
|
||||||
"win2008r2" | "win81${PLATFORM,,}"* | "win11${PLATFORM,,}-enterprise-iot"* | "win11${PLATFORM,,}-enterprise-ltsc"* )
|
"win2008r2" | "win81${PLATFORM,,}-enterprise"* | "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
|
||||||
|
@ -322,7 +317,6 @@ getWindows() {
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case "${version,,}" in
|
case "${version,,}" in
|
||||||
"win11${PLATFORM,,}" ) ;;
|
|
||||||
"win11${PLATFORM,,}-enterprise-iot"* ) ;;
|
"win11${PLATFORM,,}-enterprise-iot"* ) ;;
|
||||||
"win11${PLATFORM,,}-enterprise-ltsc"* ) ;;
|
"win11${PLATFORM,,}-enterprise-ltsc"* ) ;;
|
||||||
* )
|
* )
|
||||||
|
@ -333,13 +327,13 @@ getWindows() {
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case "${version,,}" in
|
case "${version,,}" in
|
||||||
"win10${PLATFORM,,}" | "win11${PLATFORM,,}" )
|
"win81${PLATFORM,,}" | "win10${PLATFORM,,}" | "win11${PLATFORM,,}" )
|
||||||
download_windows "$version" "$lang" "$edition" && return 0
|
download_windows "$version" "$lang" "$edition" && return 0
|
||||||
;;
|
;;
|
||||||
"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" | "win2019-hv" | "win2016-eval" | "win2012r2-eval" )
|
"win2025-eval" | "win2022-eval" | "win2019-eval" | "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" )
|
||||||
|
@ -347,10 +341,53 @@ getWindows() {
|
||||||
* ) error "Invalid VERSION specified, value \"$version\" is not recognized!" ;;
|
* ) error "Invalid VERSION specified, value \"$version\" is not recognized!" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
MIDO_URL=$(getMido "$version" "$lang" "")
|
if [[ "${PLATFORM,,}" != "x64" ]]; then
|
||||||
[ -z "$MIDO_URL" ] && return 1
|
MIDO_URL=""
|
||||||
|
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() {
|
||||||
|
@ -472,18 +509,6 @@ 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"
|
||||||
|
@ -492,9 +517,7 @@ verifyFile() {
|
||||||
local check="$4"
|
local check="$4"
|
||||||
|
|
||||||
if [ -n "$size" ] && [[ "$total" != "$size" ]] && [[ "$size" != "0" ]]; then
|
if [ -n "$size" ] && [[ "$total" != "$size" ]] && [[ "$size" != "0" ]]; then
|
||||||
if [[ "$VERIFY" == [Yy1]* ]] || [[ "$DEBUG" == [Yy1]* ]]; then
|
warn "The downloaded file has an unexpected size: $total bytes, while expected value was: $size bytes. Please report this at $SUPPORT/issues"
|
||||||
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=""
|
||||||
|
@ -517,7 +540,7 @@ verifyFile() {
|
||||||
info "Succesfully verified ISO!" && return 0
|
info "Succesfully verified ISO!" && return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
error "The downloaded file has an unknown $algo checksum: $hash , as the expected value was: $check. Please report this at $SUPPORT/issues"
|
error "The downloaded file has an invalid $algo checksum: $hash , while expected value was: $check. Please report this at $SUPPORT/issues"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,17 +552,14 @@ downloadFile() {
|
||||||
local size="$4"
|
local size="$4"
|
||||||
local lang="$5"
|
local lang="$5"
|
||||||
local desc="$6"
|
local desc="$6"
|
||||||
local msg="Downloading $desc"
|
local rc total progress domain dots space folder
|
||||||
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)
|
||||||
total_gb=$(formatBytes "$space")
|
(( size > space )) && error "Not enough free space left to download file!" && return 1
|
||||||
(( 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
|
||||||
|
@ -549,8 +569,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)
|
||||||
|
@ -561,26 +581,25 @@ 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 --user-agent "$agent" --show-progress "$progress"; rc=$?; } || :
|
{ wget "$url" -O "$iso" -q --timeout=30 --no-http-keep-alive --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_gb ?). Please report this at $SUPPORT/issues" && return 1
|
error "Invalid download link: $url (is only $total bytes?). 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! Please report this at $SUPPORT/issues" && return 1
|
(( rc == 8 )) && error "$msg , server issued an error response!" && return 1
|
||||||
|
|
||||||
error "$msg , reason: $rc"
|
error "$msg , reason: $rc"
|
||||||
return 1
|
return 1
|
||||||
|
@ -598,14 +617,12 @@ 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://127.0.0.1:8006/ to view the screen..."
|
info "Windows started succesfully, visit http://localhost:8006/ to view the screen..."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
36
src/samba.sh
36
src/samba.sh
|
@ -14,21 +14,16 @@ 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" || return 1
|
chmod 777 "$dir"
|
||||||
|
|
||||||
{ echo "--------------------------------------------------------"
|
{ echo "--------------------------------------------------------"
|
||||||
echo " $APP for Docker v$(</run/version)..."
|
echo " $APP for Docker v$(</run/version)..."
|
||||||
|
@ -76,9 +71,6 @@ addShare() {
|
||||||
echo " guest account = nobody"
|
echo " guest account = nobody"
|
||||||
echo " map to guest = Bad User"
|
echo " map to guest = Bad User"
|
||||||
echo " server min protocol = NT1"
|
echo " server min protocol = NT1"
|
||||||
echo " follow symlinks = yes"
|
|
||||||
echo " wide links = yes"
|
|
||||||
echo " unix extensions = no"
|
|
||||||
echo ""
|
echo ""
|
||||||
echo " # disable printing services"
|
echo " # disable printing services"
|
||||||
echo " load printers = no"
|
echo " load printers = no"
|
||||||
|
@ -92,35 +84,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"
|
||||||
|
|
||||||
if ! addShare "$share" "Data" "Shared"; then
|
addShare "$share" "Data" "Shared" || error "Failed to create shared folder!"
|
||||||
error "Failed to add shared folder '$share'. Please check its permissions." && return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -d "/data2" ]; then
|
[ -d "/data2" ] && addShare "/data2" "Data2" "Shared"
|
||||||
addShare "/data2" "Data2" "Shared" || error "Failed to add shared folder '/data2'. Please check its permissions."
|
[ -d "/data3" ] && addShare "/data3" "Data3" "Shared"
|
||||||
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:-}"
|
|
||||||
for dir in "${dirs[@]}"; do
|
|
||||||
[ ! -d "$dir" ] && continue
|
|
||||||
dir_name=$(basename "$dir")
|
|
||||||
addShare "$dir" "$dir_name" "Shared $dir_name" || error "Failed to create shared folder for $dir!"
|
|
||||||
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