summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorK900 <me@0upti.me>2022-10-30 17:58:52 +0300
committerGitHub <noreply@github.com>2022-10-30 15:58:52 +0100
commit8e3a9c1aadace6a1a54cf33fa8f39cf7c906c29b (patch)
tree6790ca65b5d2d6e42e9b5e5055a93e60cb173816 /modules
parent7bfb8f5aa91fee30a189eae32cda8ddc465076df (diff)
feat: native systemd support (#134)
Diffstat (limited to 'modules')
-rw-r--r--modules/installer.nix4
-rw-r--r--modules/interop.nix3
-rw-r--r--modules/wsl-distro.nix270
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' ':')
+ ''}
+ '';
+ };
+ })
+ ];
}