diff --git a/pkgs/build-support/vm/windows/default.nix b/pkgs/build-support/vm/windows/default.nix new file mode 100644 index 000000000000..03b66e9f5043 --- /dev/null +++ b/pkgs/build-support/vm/windows/default.nix @@ -0,0 +1,348 @@ +with import {}; + +with import { + inherit system; + minimal = false; +}; + +let + winISO = /path/to/iso/XXX; + + bootstrapAfterLogin = runCommand "bootstrap.sh" {} '' + cat > "$out" < ~/.ssh/authorized_keys < "$out" + ''); + gen = { url, md5 }: { + source = fetchurl { + url = "${cygwinMirror}/${url}"; + inherit md5; + }; + target = url; + }; + in map gen expr; + + cygiso = import { + inherit (pkgs) stdenv perl cdrkit pathsFromGraph; + contents = [ + { source = bootstrapAfterLogin; + target = "bootstrap.sh"; + } + { source = fetchurl { + url = "http://cygwin.com/setup-x86_64.exe"; + sha256 = "1bjmq9h1p6mmiqp6f1kvmg94jbsdi1pxfa07a5l497zzv9dsfivm"; + }; + target = "setup.exe"; + } + { source = cygPkgList; + target = "setup.ini"; + } + ] ++ makeCygwinClosure { + packages = cygPkgList; + packageList = [ "openssh" ]; + }; + }; + + maybeKvm64 = lib.optional (stdenv.system == "x86_64-linux") "-cpu kvm64"; + + cygwinQemuArgs = lib.concatStringsSep " " (maybeKvm64 ++ [ + "-monitor unix:$MONITOR_SOCKET,server,nowait" + "-nographic" + "-boot order=c,once=d" + "-drive file=${floppyImg},readonly,index=0,if=floppy" + "-drive file=winvm.img,index=0,media=disk" + "-drive file=${winISO},index=1,media=cdrom" + "-drive file=${cygiso}/iso/cd.iso,index=2,media=cdrom" + "-net nic,vlan=0,macaddr=52:54:00:12:01:01" + "-net vde,vlan=0,sock=$QEMU_VDE_SOCKET" + "-rtc base=2010-01-01,clock=vm" + ]); + + modulesClosure = lib.overrideDerivation vmTools.modulesClosure (o: { + rootModules = o.rootModules ++ lib.singleton "virtio_net"; + }); + + snakeOilSSH = stdenv.mkDerivation { + name = "snakeoil-ssh-cygwin"; + buildCommand = '' + ensureDir "$out" + ${openssh}/bin/ssh-keygen -t ecdsa -f "$out/key" -N "" + ''; + }; + + controllerQemuArgs = cmd: let + preInitScript = writeScript "preinit.sh" '' + #!${vmTools.initrdUtils}/bin/ash -e + export PATH=${vmTools.initrdUtils}/bin + mount -t proc none /proc + mount -t sysfs none /sys + for arg in $(cat /proc/cmdline); do + if [ "x''${arg#command=}" != "x$arg" ]; then + command="''${arg#command=}" + fi + done + + for i in $(cat ${modulesClosure}/insmod-list); do + insmod $i + done + + mkdir -p /tmp /dev + mknod /dev/null c 1 3 + mknod /dev/zero c 1 5 + mknod /dev/random c 1 8 + mknod /dev/urandom c 1 9 + mknod /dev/tty c 5 0 + + ifconfig lo up + ifconfig eth0 up 192.168.0.2 + + mkdir -p /nix/store /etc /var/run /var/log + + cat > /etc/passwd < /etc/samba/smb.conf < '$out/state.gz'" + CMD + cp winvm.img "$out/disk.img" + ''; + }; + +in bootstrap diff --git a/pkgs/build-support/vm/windows/mkclosure.py b/pkgs/build-support/vm/windows/mkclosure.py new file mode 100644 index 000000000000..48d569a6bd3e --- /dev/null +++ b/pkgs/build-support/vm/windows/mkclosure.py @@ -0,0 +1,78 @@ +# Ugliest Python code I've ever written. -- aszlig +import sys + +def get_plist(path): + in_pack = False + in_str = False + current_key = None + buf = "" + packages = {} + package_name = None + package_attrs = {} + with open(path, 'r') as setup: + for line in setup: + if in_str and line.rstrip().endswith('"'): + package_attrs[current_key] = buf + line.rstrip()[:-1] + in_str = False + continue + elif in_str: + buf += line + continue + + if line.startswith('@'): + in_pack = True + package_name = line[1:].strip() + package_attrs = {} + elif in_pack and ':' in line: + key, value = line.split(':', 1) + if value.lstrip().startswith('"'): + if value.lstrip()[1:].rstrip().endswith('"'): + value = value.strip().strip('"') + else: + in_str = True + current_key = key.strip().lower() + buf = value.lstrip()[1:] + continue + package_attrs[key.strip().lower()] = value.strip() + elif in_pack: + in_pack = False + packages[package_name] = package_attrs + return packages + +def main(): + packages = get_plist(sys.argv[1]) + to_include = set() + + def traverse(package): + to_include.add(package) + attrs = packages.get(package, {}) + deps = attrs.get('requires', '').split() + for new_dep in set(deps) - to_include: + traverse(new_dep) + + map(traverse, sys.argv[2:]) + + sys.stdout.write('[\n') + for package, attrs in packages.iteritems(): + if package not in to_include: + cats = [c.lower() for c in attrs.get('category', '').split()] + if 'base' not in cats: + continue + + install_line = attrs.get('install') + if install_line is None: + continue + + url, size, md5 = install_line.split(' ', 2) + + pack = [ + ' {', + ' url = "{0}";'.format(url), + ' md5 = "{0}";'.format(md5), + ' }', + ]; + sys.stdout.write('\n'.join(pack) + '\n') + sys.stdout.write(']\n') + +if __name__ == '__main__': + main()