diff options
| author | K900 <me@0upti.me> | 2022-10-30 17:58:52 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-30 15:58:52 +0100 |
| commit | 8e3a9c1aadace6a1a54cf33fa8f39cf7c906c29b (patch) | |
| tree | 6790ca65b5d2d6e42e9b5e5055a93e60cb173816 /modules | |
| parent | 7bfb8f5aa91fee30a189eae32cda8ddc465076df (diff) | |
feat: native systemd support (#134)
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/installer.nix | 4 | ||||
| -rw-r--r-- | modules/interop.nix | 3 | ||||
| -rw-r--r-- | modules/wsl-distro.nix | 270 |
3 files changed, 154 insertions, 123 deletions
diff --git a/modules/installer.nix b/modules/installer.nix index 45d191a..3fd404f 100644 --- a/modules/installer.nix +++ b/modules/installer.nix @@ -48,9 +48,7 @@ with builtins; with lib; { compressionExtension = ".gz"; extraArgs = "--hard-dereference"; - storeContents = with pkgs; pkgs2storeContents [ - installer - ]; + storeContents = pkgs2storeContents [ installer ]; contents = [ { source = config.environment.etc."wsl.conf".source; target = "/etc/wsl.conf"; } diff --git a/modules/interop.nix b/modules/interop.nix index b7babfb..d055d4b 100644 --- a/modules/interop.nix +++ b/modules/interop.nix @@ -74,9 +74,6 @@ with builtins; with lib; }; }; - # Include Windows %PATH% in Linux $PATH. - environment.extraInit = mkIf cfg.includePath ''PATH="$PATH:$WSLPATH"''; - warnings = let registrations = config.boot.binfmt.registrations; diff --git a/modules/wsl-distro.nix b/modules/wsl-distro.nix index 9b187d1..ded84a3 100644 --- a/modules/wsl-distro.nix +++ b/modules/wsl-distro.nix @@ -2,144 +2,180 @@ with builtins; with lib; { - options.wsl = with types; - let - coercedToStr = coercedTo (oneOf [ bool path int ]) (toString) str; - in - { - enable = mkEnableOption "support for running NixOS as a WSL distribution"; - automountPath = mkOption { - type = str; - default = "/mnt"; - description = "The path where windows drives are mounted (e.g. /mnt/c)"; - }; - automountOptions = mkOption { - type = str; - default = "metadata,uid=1000,gid=100"; - description = "Options to use when mounting windows drives"; - }; - defaultUser = mkOption { - type = str; - default = "nixos"; - description = "The name of the default user"; - }; - startMenuLaunchers = mkEnableOption "shortcuts for GUI applications in the windows start menu"; - wslConf = mkOption { - type = attrsOf (attrsOf (oneOf [ string int bool ])); - description = "Entries that are added to /etc/wsl.conf"; - }; + options.wsl = with types; { + enable = mkEnableOption "support for running NixOS as a WSL distribution"; + nativeSystemd = mkOption { + type = bool; + default = false; + description = "Use native WSL systemd support"; + }; + automountPath = mkOption { + type = str; + default = "/mnt"; + description = "The path where windows drives are mounted (e.g. /mnt/c)"; + }; + automountOptions = mkOption { + type = str; + default = "metadata,uid=1000,gid=100"; + description = "Options to use when mounting windows drives"; + }; + defaultUser = mkOption { + type = str; + default = "nixos"; + description = "The name of the default user"; + }; + startMenuLaunchers = mkEnableOption "shortcuts for GUI applications in the windows start menu"; + wslConf = mkOption { + type = attrsOf (attrsOf (oneOf [ string int bool ])); + description = "Entries that are added to /etc/wsl.conf"; }; + }; config = let cfg = config.wsl; syschdemd = pkgs.callPackage ../scripts/syschdemd.nix { inherit (cfg) automountPath defaultUser; }; + shim = pkgs.callPackage ../scripts/native-systemd-shim/shim.nix { }; + + bashWrapper = pkgs.runCommand "nixos-wsl-bash-wrapper" { nativeBuildInputs = [ pkgs.makeWrapper ]; } '' + makeWrapper ${pkgs.bashInteractive}/bin/sh $out/bin/sh --prefix PATH ':' ${lib.makeBinPath [pkgs.systemd pkgs.gnugrep]} + ''; + + bash = if cfg.nativeSystemd then bashWrapper else pkgs.bashInteractive; in - mkIf cfg.enable { - - wsl.wslConf = { - automount = { - enabled = true; - mountFsTab = true; - root = "${cfg.automountPath}/"; - options = cfg.automountOptions; + mkMerge [ + (mkIf cfg.enable { + wsl.wslConf = { + automount = { + enabled = true; + mountFsTab = true; + root = "${cfg.automountPath}/"; + options = cfg.automountOptions; + }; + network = { + generateResolvConf = mkDefault true; + generateHosts = mkDefault true; + }; }; - network = { - generateResolvConf = mkDefault true; - generateHosts = mkDefault true; - }; - }; - - # We don't need a boot loader - boot.loader.grub.enable = false; - system.build.installBootLoader = "${pkgs.coreutils}/bin/true"; - boot.initrd.enable = false; - system.build.initialRamdisk = pkgs.runCommand "fake-initrd" { } '' - mkdir $out - touch $out/${config.system.boot.loader.initrdFile} - ''; - system.build.initialRamdiskSecretAppender = pkgs.writeShellScriptBin "append-initrd-secrets" ""; - hardware.opengl.enable = true; # Enable GPU acceleration + # We don't need a boot loader + boot.loader.grub.enable = false; + system.build.installBootLoader = "${pkgs.coreutils}/bin/true"; + boot.initrd.enable = false; + system.build.initialRamdisk = pkgs.runCommand "fake-initrd" { } '' + mkdir $out + touch $out/${config.system.boot.loader.initrdFile} + ''; + system.build.initialRamdiskSecretAppender = pkgs.writeShellScriptBin "append-initrd-secrets" ""; + + hardware.opengl.enable = true; # Enable GPU acceleration - environment = { + environment = { - etc = { - "wsl.conf".text = generators.toINI { } cfg.wslConf; + etc = { + "wsl.conf".text = generators.toINI { } cfg.wslConf; - # DNS settings are managed by WSL - hosts.enable = !config.wsl.wslConf.network.generateHosts; - "resolv.conf".enable = !config.wsl.wslConf.network.generateResolvConf; - }; + # DNS settings are managed by WSL + hosts.enable = !config.wsl.wslConf.network.generateHosts; + "resolv.conf".enable = !config.wsl.wslConf.network.generateResolvConf; + }; - systemPackages = [ - (pkgs.runCommand "wslpath" { } '' - mkdir -p $out/bin - ln -s /init $out/bin/wslpath - '') - ]; - }; + systemPackages = [ + (pkgs.runCommand "wslpath" { } '' + mkdir -p $out/bin + ln -s /init $out/bin/wslpath + '') + ]; + }; - networking.dhcpcd.enable = false; + networking.dhcpcd.enable = false; - users.users.${cfg.defaultUser} = { - isNormalUser = true; - uid = 1000; - extraGroups = [ "wheel" ]; # Allow the default user to use sudo - }; + users.users.${cfg.defaultUser} = { + isNormalUser = true; + uid = 1000; + extraGroups = [ "wheel" ]; # Allow the default user to use sudo + }; - users.users.root = { - shell = "${syschdemd}/bin/syschdemd"; # Otherwise WSL fails to login as root with "initgroups failed 5" - extraGroups = [ "root" ]; - }; + users.users.root.extraGroups = [ "root" ]; + + security.sudo.wheelNeedsPassword = mkDefault false; # The default user will not have a password by default + + system.activationScripts = { + copy-launchers = mkIf cfg.startMenuLaunchers ( + stringAfter [ ] '' + for x in applications icons; do + echo "Copying /usr/share/$x" + mkdir -p /usr/share/$x + ${pkgs.rsync}/bin/rsync -ar --delete $systemConfig/sw/share/$x/. /usr/share/$x + done + '' + ); + populateBin = stringAfter [ ] '' + echo "setting up /bin..." + ln -sf /init /bin/wslpath + ln -sf ${bash}/bin/sh /bin/sh + ln -sf ${pkgs.util-linux}/bin/mount /bin/mount + ''; + }; + + systemd = { + # Disable systemd units that don't make sense on WSL + services = { + "serial-getty@ttyS0".enable = false; + "serial-getty@hvc0".enable = false; + "getty@tty1".enable = false; + "autovt@".enable = false; + firewall.enable = false; + systemd-resolved.enable = false; + systemd-udevd.enable = false; + }; + + tmpfiles.rules = [ + # Don't remove the X11 socket + "d /tmp/.X11-unix 1777 root root" + ]; + + # Don't allow emergency mode, because we don't have a console. + enableEmergencyMode = false; + }; - security.sudo = { - extraConfig = '' + warnings = (optional (config.systemd.services.systemd-resolved.enable && config.wsl.wslConf.network.generateResolvConf) "systemd-resolved is enabled, but resolv.conf is managed by WSL"); + }) + (mkIf (!cfg.nativeSystemd) { + users.users.root.shell = "${syschdemd}/bin/syschdemd"; + security.sudo.extraConfig = '' Defaults env_keep+=INSIDE_NAMESPACE ''; - wheelNeedsPassword = mkDefault false; # The default user will not have a password by default - }; - - system.activationScripts = { - copy-launchers = mkIf cfg.startMenuLaunchers ( - stringAfter [ ] '' - for x in applications icons; do - echo "Copying /usr/share/$x" - mkdir -p /usr/share/$x - ${pkgs.rsync}/bin/rsync -ar --delete $systemConfig/sw/share/$x/. /usr/share/$x - done - '' - ); - populateBin = stringAfter [ ] '' - echo "setting up /bin..." - ln -sf /init /bin/wslpath - ln -sf ${pkgs.bashInteractive}/bin/bash /bin/sh - ln -sf ${pkgs.util-linux}/bin/mount /bin/mount - ''; - }; - - systemd = { - # Disable systemd units that don't make sense on WSL - services = { - "serial-getty@ttyS0".enable = false; - "serial-getty@hvc0".enable = false; - "getty@tty1".enable = false; - "autovt@".enable = false; - firewall.enable = false; - systemd-resolved.enable = false; - systemd-udevd.enable = false; + wsl.wslConf.users.default = "root"; + + # Include Windows %PATH% in Linux $PATH. + environment.extraInit = mkIf cfg.interop.includePath ''PATH="$PATH:$WSLPATH"''; + }) + (mkIf cfg.nativeSystemd { + wsl.wslConf = { + user.default = cfg.defaultUser; + boot.systemd = true; }; - tmpfiles.rules = [ - # Don't remove the X11 socket - "d /tmp/.X11-unix 1777 root root" - ]; - - # Don't allow emergency mode, because we don't have a console. - enableEmergencyMode = false; - }; + system.activationScripts = { + shimSystemd = stringAfter [ ] '' + echo "setting up /sbin/init shim..." + mkdir -p /sbin + ln -sf ${shim}/bin/nixos-wsl-native-systemd-shim /sbin/init + ''; + }; - warnings = (optional (config.systemd.services.systemd-resolved.enable && config.wsl.wslConf.network.generateResolvConf) "systemd-resolved is enabled, but resolv.conf is managed by WSL"); - }; + environment = { + # preserve $PATH from parent + variables.PATH = [ "$PATH" ]; + extraInit = '' + export WSLPATH=$(echo "$PATH" | tr ':' '\n' | grep -E "^${cfg.automountPath}" | tr '\n' ':') + ${if cfg.interop.includePath then "" else '' + export PATH=$(echo "$PATH" | tr ':' '\n' | grep -vE "^${cfg.automountPath}" | tr '\n' ':') + ''} + ''; + }; + }) + ]; } |
