summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stührk <andy@hammerhartes.de>2019-11-28 23:54:17 +0100
committerAndreas Stührk <andy@hammerhartes.de>2019-11-28 23:54:17 +0100
commita9b5bba5ed69efce719a4f2c7c058fc0cc86a927 (patch)
treeaa6e3a0ded3528ee00a248d4ffeacc90f5cc6afa
Initial commit: seems to be at least somewhat usable
-rw-r--r--build-tarball.nix69
-rw-r--r--configuration.nix46
-rw-r--r--nixos.nix13
-rw-r--r--syschdemd.nix19
-rw-r--r--syschdemd.sh43
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