diff options
| author | Andreas Stührk <andy@hammerhartes.de> | 2019-11-28 23:54:17 +0100 |
|---|---|---|
| committer | Andreas Stührk <andy@hammerhartes.de> | 2019-11-28 23:54:17 +0100 |
| commit | a9b5bba5ed69efce719a4f2c7c058fc0cc86a927 (patch) | |
| tree | aa6e3a0ded3528ee00a248d4ffeacc90f5cc6afa | |
Initial commit: seems to be at least somewhat usable
| -rw-r--r-- | build-tarball.nix | 69 | ||||
| -rw-r--r-- | configuration.nix | 46 | ||||
| -rw-r--r-- | nixos.nix | 13 | ||||
| -rw-r--r-- | syschdemd.nix | 19 | ||||
| -rw-r--r-- | syschdemd.sh | 43 |
5 files changed, 190 insertions, 0 deletions
diff --git a/build-tarball.nix b/build-tarball.nix new file mode 100644 index 0000000..08d028c --- /dev/null +++ b/build-tarball.nix @@ -0,0 +1,69 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + pkgs2storeContents = l : map (x: { object = x; symlink = "none"; }) l; + + nixpkgs = lib.cleanSource pkgs.path; + + channelSources = pkgs.runCommand "nixos-${config.system.nixos.version}" + { preferLocalBuild = true; } + '' + mkdir -p $out + cp -prd ${nixpkgs.outPath} $out/nixos + chmod -R u+w $out/nixos + if [ ! -e $out/nixos/nixpkgs ]; then + ln -s . $out/nixos/nixpkgs + fi + echo -n ${config.system.nixos.revision} > $out/nixos/.git-revision + echo -n ${config.system.nixos.versionSuffix} > $out/nixos/.version-suffix + echo ${config.system.nixos.versionSuffix} | sed -e s/pre// > $out/nixos/svn-revision + ''; + + preparer = pkgs.writeShellScriptBin "wsl-prepare" '' + set -e + + mkdir -m 0755 ./bin ./etc + mkdir -m 1777 ./tmp + + # WSL requires a /bin/sh - only temporary, NixOS's activate will overwrite + ln -s ${pkgs.stdenv.shell} ./bin/sh + + # WSL also requires a /bin/mount, otherwise the host fs isn't accessible + ln -s ${pkgs.utillinux}/bin/mount ./bin/mount + + # Set system profile + system=${config.system.build.toplevel} + ./$system/sw/bin/nix-store --store `pwd` --load-db < ./nix-path-registration + rm ./nix-path-registration + ./$system/sw/bin/nix-env --store `pwd` -p ./nix/var/nix/profiles/system --set $system + + # Set channel + mkdir -p ./nix/var/nix/profiles/per-user/root + ./$system/sw/bin/nix-env --store `pwd` -p ./nix/var/nix/profiles/per-user/root/channels --set ${channelSources} + mkdir -m 0700 -p ./root/.nix-defexpr + ln -s /nix/var/nix/profiles/per-user/root/channels ./root/.nix-defexpr/channels + + # It's now a NixOS! + touch ./etc/NIXOS + ''; +in +{ system.build.tarball = pkgs.callPackage <nixpkgs/nixos/lib/make-system-tarball.nix> { + # No contents, structure will be added by prepare script + contents = []; + + storeContents = pkgs2storeContents [ + config.system.build.toplevel + pkgs.stdenv + channelSources + preparer + ]; + + extraCommands = "${preparer}/bin/wsl-prepare"; + + # Use gzip + compressCommand = "gzip"; + compressionExtension = ".gz"; + }; +} diff --git a/configuration.nix b/configuration.nix new file mode 100644 index 0000000..3e11857 --- /dev/null +++ b/configuration.nix @@ -0,0 +1,46 @@ +{ lib, pkgs, config, ... }: + +with lib; + +let + syschdemd = import ./syschdemd.nix { inherit lib pkgs config; }; +in +{ + imports = [ + <nixpkgs/nixos/modules/profiles/minimal.nix> + ]; + + # WSL is closer to a container than anything else + boot.isContainer = true; + + environment.etc.hosts.enable = false; + environment.etc."resolv.conf".enable = false; + + networking.dhcpcd.enable = false; + + users.users.andy = { + isNormalUser = true; + shell = "${syschdemd}/bin/syschdemd"; + extraGroups = [ "wheel" ]; + }; + + # Described as "it should not be overwritten" in NixOS documentation, + # but it's on /run per default and WSL mounts /run as a tmpfs, hence + # hiding the wrappers. + security.wrapperDir = "/wrappers"; + + security.sudo.wheelNeedsPassword = false; + + # Disable systemd units that don't make sense on WSL + systemd.services."serial-getty@ttyS0".enable = false; + systemd.services."serial-getty@hvc0".enable = false; + systemd.services."getty@tty1".enable = false; + systemd.services."autovt@".enable = false; + + systemd.services.firewall.enable = false; + systemd.services.systemd-resolved.enable = false; + systemd.services.systemd-udevd.enable = false; + + # Don't allow emergency mode, because we don't have a console. + systemd.enableEmergencyMode = false; +} diff --git a/nixos.nix b/nixos.nix new file mode 100644 index 0000000..3a32460 --- /dev/null +++ b/nixos.nix @@ -0,0 +1,13 @@ +# Build with +# nix-build -A system -A config.system.build.tarball ./nixos.nix + +import <nixpkgs/nixos> { + configuration = { + imports = [ + ./configuration.nix + ./build-tarball.nix + ]; + }; + + system = "x86_64-linux"; +} diff --git a/syschdemd.nix b/syschdemd.nix new file mode 100644 index 0000000..6e786a5 --- /dev/null +++ b/syschdemd.nix @@ -0,0 +1,19 @@ +{ lib, pkgs, config, ... }: + +let + nixpkgs = import <nixpkgs> {}; + + inherit (nixpkgs) daemonize; +in +pkgs.substituteAll { + name = "syschdemd"; + src = ./syschdemd.sh; + dir = "bin"; + isExecutable = true; + + buildInputs = [ daemonize ]; + + inherit daemonize; + inherit (config.security) wrapperDir; + fsPackagesPath = lib.makeBinPath config.system.fsPackages; +} diff --git a/syschdemd.sh b/syschdemd.sh new file mode 100644 index 0000000..1964daa --- /dev/null +++ b/syschdemd.sh @@ -0,0 +1,43 @@ +#! @shell@ + +set -e + +sw="/nix/var/nix/profiles/system/sw/bin" +systemPath=`${sw}/readlink -f /nix/var/nix/profiles/system` + +# Needs root to work +if [[ $EUID -ne 0 ]]; then + exec @wrapperDir@/sudo "$0" -u "$UID" "$@" +fi + +targetUid=$UID + +while [ "$#" -gt 0 ]; do + i="$1"; shift 1 + case "$i" in + -u) + targetUid=$1; shift 1 + ;; + *) + echo "$0: unknown option \`$i'" + exit 1 + ;; + esac +done + +if [ ! -e "/run/current-system" ]; then + ln -sfn "$(${sw}/readlink -f "$systemPath")" /run/current-system +fi + +if [ ! -e "/run/systemd.pid" ]; then + PATH=/run/current-system/systemd/lib/systemd:@fsPackagesPath@ \ + LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive \ + @daemonize@/bin/daemonize /run/current-system/sw/bin/unshare -fp --mount-proc systemd + /run/current-system/sw/bin/pgrep -xf systemd > /run/systemd.pid +fi + +if [ $UID -ne $targetUid ]; then + exec @wrapperDir@/su -s @shell@ $(/run/current-system/sw/bin/id -un $targetUid) +else + exec @shell@ +fi |
