2020-01-10 03:19:15 +08:00
|
|
|
{ pkgs ? import <nixpkgs> {}
|
|
|
|
, lib ? pkgs.lib
|
|
|
|
, diskImageSize ? "22G"
|
|
|
|
, qemuMem ? "4G"
|
|
|
|
, windowsImage ? null
|
|
|
|
, autoUnattendParams ? {}
|
|
|
|
, packages ? []
|
|
|
|
, impureMode ? false
|
|
|
|
, ...
|
|
|
|
}@attrs:
|
|
|
|
|
|
|
|
let
|
|
|
|
# qemu_test is a smaller closure only building for a single system arch
|
|
|
|
qemu = pkgs.qemu_test;
|
|
|
|
libguestfs = pkgs.libguestfs-with-appliance.override {
|
|
|
|
inherit qemu;
|
|
|
|
};
|
|
|
|
|
|
|
|
runQemuCommand = name: command: (
|
|
|
|
pkgs.runCommandNoCC name { buildInputs = [ pkgs.p7zip qemu libguestfs ]; }
|
|
|
|
(
|
|
|
|
''
|
|
|
|
if ! test -f; then
|
|
|
|
echo "KVM not available, bailing out" >> /dev/stderr
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
'' + command
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
windowsIso = if windowsImage != null then windowsImage else pkgs.fetchurl {
|
|
|
|
url = "https://software-download.microsoft.com/download/sg/17763.107.101029-1455.rs5_release_svc_refresh_CLIENT_LTSC_EVAL_x64FRE_en-us.iso";
|
|
|
|
sha256 = "668fe1af70c2f7416328aee3a0bb066b12dc6bbd2576f40f812b95741e18bc3a";
|
|
|
|
};
|
|
|
|
|
2020-01-31 06:53:17 +08:00
|
|
|
openSshServerPackage = ./openssh/server-package.cab;
|
|
|
|
|
|
|
|
# pkgs.fetchurl {
|
|
|
|
# name = "OpenSSH-Server-Package~31bf3856ad364e35~amd64~~.cab";
|
|
|
|
# url = "http://download.windowsupdate.com/c/msdownload/update/software/updt/2018/04/openssh-server-package~31bf3856ad364e35~amd64~~_b264949145379b61d55448ed2625916457f701ba.cab";
|
|
|
|
# sha256 = "1pzaz2i7x05ki6gq7yxh0j4c1l6r57hawl3ggkji0r83wzrmh7ps";
|
|
|
|
# };
|
|
|
|
# openSshClientPackage = pkgs.fetchurl {
|
|
|
|
# name = "OpenSSH-Client-Package-31bf3856ad364e35-AMD64.cab";
|
|
|
|
# url = "http://download.windowsupdate.com/d/msdownload/update/software/updt/2018/04/openssh-client-package~31bf3856ad364e35~amd64~~_715b60a3869c393e0c03fd5683fe88c6f155ce28.cab";
|
|
|
|
# sha256 = "1rfdh2b47y27smy91g19s82cfwp8x5wg2iri95b8ndi9mplyfqdd";
|
|
|
|
# };
|
|
|
|
|
|
|
|
# Note: We're not using this one but keep around as a reference since microsoft makes it near impossible to find
|
|
|
|
# URLs for these kind of things
|
|
|
|
# fodIso = pkgs.fetchurl {
|
|
|
|
# url = "https://software-download.microsoft.com/download/pr/17763.1.180914-1434.rs5_release_amd64fre_SERVER-FOD-PACKAGES_OEM_amd64fre_MULTI.iso";
|
|
|
|
# sha256 = "009pygycwvfkbm02zycp9zv136qc2lcljjjp0021fjd2kn3mf6k9";
|
|
|
|
# };
|
|
|
|
|
2020-01-10 03:19:15 +08:00
|
|
|
autounattend = import ./autounattend.nix (
|
|
|
|
attrs // {
|
|
|
|
inherit pkgs;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
bundleInstaller = pkgs.callPackage ./bundle {};
|
|
|
|
|
|
|
|
# Packages required to drive installation of other packages
|
|
|
|
bootstrapPkgs = let
|
|
|
|
winPkgs = import ./pkgs.nix { inherit pkgs; };
|
|
|
|
|
2020-02-13 08:51:45 +08:00
|
|
|
# nuget = winPkgs.makePkg {
|
|
|
|
# name = "nuget-dll";
|
|
|
|
# src = ./nuget/Microsoft.PackageManagement.NuGetProvider.dll;
|
|
|
|
# installScript = ''
|
|
|
|
# mkdir -f "C:\Program Files\PackageManagement\ProviderAssemblies\nuget\2.8.5.208"
|
|
|
|
# cp "Microsoft.PackageManagement.NuGetProvider.dll" "C:\Program Files\PackageManagement\ProviderAssemblies\nuget\2.8.5.208"
|
|
|
|
# Import-PackageProvider -Name NuGet -RequiredVersion 2.8.5.201
|
|
|
|
# '';
|
|
|
|
# };
|
2020-01-20 08:43:44 +08:00
|
|
|
|
2020-01-27 18:23:53 +08:00
|
|
|
anaconda = winPkgs.makePkg {
|
|
|
|
name = "Anaconda3";
|
|
|
|
src = pkgs.fetchurl {
|
|
|
|
name = "Anaconda3.exe";
|
|
|
|
url = "https://repo.anaconda.com/archive/Anaconda3-2019.03-Windows-x86_64.exe";
|
|
|
|
sha256 = "1f9icm5rwab6l1f23a70dw0qixzrl62wbglimip82h4zhxlh3jfj";
|
|
|
|
};
|
|
|
|
installScript = ''
|
2020-02-13 08:51:45 +08:00
|
|
|
.\Anaconda3.exe /InstallationType=AllUsers /RegisterPython=0 /S /D="C:\ProgramData\Anaconda3"
|
2020-01-27 18:23:53 +08:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2020-01-10 03:19:15 +08:00
|
|
|
in
|
|
|
|
runQemuCommand "bootstrap-win-pkgs.img" ''
|
|
|
|
mkdir pkgs
|
|
|
|
mkdir pkgs/bootstrap
|
2020-02-13 08:51:45 +08:00
|
|
|
mkdir pkgs/user
|
2020-01-31 06:53:17 +08:00
|
|
|
mkdir pkgs/fod
|
2020-01-10 03:19:15 +08:00
|
|
|
|
|
|
|
cp ${bundleInstaller} pkgs/"$(stripHash "${bundleInstaller}")"
|
2020-01-29 07:16:49 +08:00
|
|
|
|
2020-01-31 06:53:17 +08:00
|
|
|
# Install optional windows features
|
|
|
|
cp ${openSshServerPackage} pkgs/fod/OpenSSH-Server-Package~31bf3856ad364e35~amd64~~.cab
|
|
|
|
|
2020-01-29 07:16:49 +08:00
|
|
|
# SSH setup script goes here because windows XML parser sucks
|
|
|
|
cp ${autounattend.setupScript} pkgs/ssh-setup.ps1
|
|
|
|
|
2020-02-13 08:51:45 +08:00
|
|
|
# cp ${anaconda} pkgs/user/00_"$(stripHash "${anaconda}")"
|
2020-01-10 03:19:15 +08:00
|
|
|
|
|
|
|
${lib.concatStringsSep "\n" (builtins.map (x: ''cp ${x} pkgs/bootstrap/"$(stripHash "${x}")"'') packages)}
|
|
|
|
|
|
|
|
virt-make-fs --partition --type=fat pkgs/ $out
|
|
|
|
'';
|
|
|
|
|
|
|
|
installScript = pkgs.writeScript "windows-install-script" (
|
|
|
|
let
|
|
|
|
qemuParams = [
|
|
|
|
"-enable-kvm"
|
|
|
|
"-cpu"
|
|
|
|
"host"
|
|
|
|
"-smp"
|
|
|
|
"$NIX_BUILD_CORES"
|
|
|
|
"-m"
|
|
|
|
"${qemuMem}"
|
|
|
|
"-bios"
|
|
|
|
"${pkgs.OVMF.fd}/FV/OVMF.fd"
|
|
|
|
"-vga"
|
|
|
|
"virtio"
|
|
|
|
"-device"
|
|
|
|
"piix3-usb-uhci" # USB root hub
|
|
|
|
# USB boot
|
|
|
|
"-drive"
|
|
|
|
"id=win-install,file=usbimage.img,if=none,format=raw,readonly=on"
|
|
|
|
"-device"
|
|
|
|
"usb-storage,drive=win-install"
|
|
|
|
# Output image
|
|
|
|
"-drive"
|
|
|
|
"file=c.img,index=0,media=disk,cache=unsafe"
|
|
|
|
# "CD" drive with bootstrap pkgs
|
|
|
|
"-drive"
|
|
|
|
"id=virtio-win,file=${bootstrapPkgs},if=none,format=raw,readonly=on"
|
|
|
|
"-device"
|
|
|
|
"usb-storage,drive=virtio-win"
|
2020-01-31 06:53:17 +08:00
|
|
|
# "CD" drive with windows features-on-demand
|
|
|
|
# "-cdrom" "${fodIso}"
|
2020-01-10 03:19:15 +08:00
|
|
|
] ++ lib.optional (!impureMode) "-nographic";
|
|
|
|
in
|
|
|
|
''
|
|
|
|
#!${pkgs.runtimeShell}
|
|
|
|
set -exuo pipefail
|
|
|
|
export PATH=${lib.makeBinPath [ pkgs.p7zip qemu libguestfs ]}:$PATH
|
|
|
|
|
|
|
|
# Create a bootable "USB" image
|
|
|
|
# Booting in USB mode circumvents the "press any key to boot from cdrom" prompt
|
|
|
|
#
|
|
|
|
# Also embed the autounattend answer file in this image
|
|
|
|
mkdir -p win
|
|
|
|
mkdir -p win/nix-win
|
|
|
|
7z x -y ${windowsIso} -owin
|
2020-01-29 07:16:49 +08:00
|
|
|
|
|
|
|
cp ${autounattend.autounattendXML} win/autounattend.xml
|
|
|
|
|
2020-01-10 03:19:15 +08:00
|
|
|
virt-make-fs --partition --type=fat win/ usbimage.img
|
|
|
|
rm -rf win
|
|
|
|
|
|
|
|
# Qemu requires files to be rw
|
|
|
|
qemu-img create -f qcow2 c.img ${diskImageSize}
|
|
|
|
env NIX_BUILD_CORES="''${NIX_BUILD_CORES:4}" qemu-system-x86_64 ${lib.concatStringsSep " " qemuParams}
|
|
|
|
''
|
|
|
|
);
|
|
|
|
|
|
|
|
in
|
|
|
|
if impureMode then installScript else pkgs.runCommandNoCC "windows.img" {} ''
|
|
|
|
${installScript}
|
|
|
|
mv c.img $out
|
|
|
|
''
|