From 03fc47a4775f7cc463fe62f8bddf698a255095f5 Mon Sep 17 00:00:00 2001 From: SEIAROTg Date: Fri, 20 Dec 2024 22:47:19 +0000 Subject: [PATCH] fix: fixes integration with latest sd-switch. --- README.md | 2 -- container.nix | 11 ++++--- home-manager-module.nix | 71 +++++++++++++++++++++-------------------- network.nix | 11 ++++--- nixos-module.nix | 13 ++++---- pod.nix | 11 ++++--- tests/flake.nix | 17 ++-------- 7 files changed, 63 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index 3a07108..08abdd3 100644 --- a/README.md +++ b/README.md @@ -109,8 +109,6 @@ See [`container.nix`](./container.nix), [`network.nix`](./network.nix), and [`po # ... imports = [ inputs.quadlet-nix.homeManagerModules.quadlet ]; # This is crucial to ensure the systemd services are (re)started on config change - # There appears to be some issues with sd-switch>=0.5.0 that causes services not to - # auto-start on boot. Consider using a different version. systemd.user.startServices = "sd-switch"; virtualisation.quadlet.containers = { echo-server = { diff --git a/container.nix b/container.nix index f64b2de..49b10e6 100644 --- a/container.nix +++ b/container.nix @@ -682,8 +682,9 @@ in }; _name = mkOption { internal = true; }; - _unitName = mkOption { internal = true; }; + _serviceName = mkOption { internal = true; }; _configText = mkOption { internal = true; }; + _wantedBy = mkOption { internal = true; }; ref = mkOption { readOnly = true; }; }; @@ -693,21 +694,21 @@ in containerConfig = config.containerConfig // { name = containerName; }; + wantedBy = if config.autoStart then [ quadletUtils.defaultTarget ] else [ ]; unitConfig = { Unit = { Description = "Podman container ${name}"; } // config.unitConfig; - Install = { - WantedBy = if config.autoStart then [ quadletUtils.defaultTarget ] else [ ]; - }; + Install.WantedBy = wantedBy; Container = quadletUtils.configToProperties containerConfig containerOpts; Service = serviceConfigDefault // config.serviceConfig; }; in { _name = containerName; - _unitName = "${name}.service"; + _serviceName = name; _configText = quadletUtils.unitConfigToText unitConfig; + _wantedBy = wantedBy; ref = "${name}.container"; }; } diff --git a/home-manager-module.nix b/home-manager-module.nix index db6a673..e6d6fef 100644 --- a/home-manager-module.nix +++ b/home-manager-module.nix @@ -70,19 +70,9 @@ in "containers/systemd/${p.ref}" = { text = p._configText; }; - # Inject hash for the activation process to detect changes. - # Must be in the main file as it's the only thing home-manager switch process looks at. - "systemd/user/${p._unitName}" = { - text = '' - [Unit] - X-QuadletNixConfigHash=${builtins.hashString "sha256" p._configText} - [Service] - Environment=PATH=/run/wrappers/bin - ''; - }; # Import quadlet-generated unit as a dropin override. - "systemd/user/${p._unitName}.d/override.conf" = { - source = "${configPathLink}/out/${p._unitName}"; + "systemd/user/${p._serviceName}.service.d/override.conf" = { + source = "${configPathLink}/out/${p._serviceName}.service"; }; }) allObjects ) // { @@ -90,32 +80,45 @@ in # systemd only looks for command binary in a few static location. # See: https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html#Command%20lines "systemd/user/podman-user-wait-network-online.service.d/override.conf" = { - text = '' - [Service] - ExecStart= - ExecStart=/bin/sh -c 'until systemctl is-active network-online.target; do sleep 0.5; done' - [Install] - WantedBy=default.target - ''; + text = quadletUtils.unitConfigToText { + Service.ExecSearchPath = "/bin"; + Install.WantedBy = [ "default.target" ]; + }; }; }; - # TODO: link from ${pkgs.podman}/share/systemd/user/podman-auto-update.service - # when https://github.com/containers/podman/issues/24637 is fixed. - systemd.user.services.podman-auto-update = mkIf cfg.autoUpdate.enable { - Unit = { - Description = "Podman auto-update service"; - Documentation = "man:podman-auto-update(1)"; - }; - Service = { - Type = "oneshot"; - # podman rootless requires "newuidmap" (the suid version, not the non-suid one from pkgs.shadow) - Environment = "PATH=/run/wrappers/bin"; - ExecStart = "${getExe quadletUtils.podmanPackage} auto-update"; - ExecStartPost = "${getExe quadletUtils.podmanPackage} image prune -f"; - TimeoutStartSec = "900s"; - TimeoutStopSec = "10s"; + + systemd.user.services = mergeAttrsList ( + map (p: { + # Inject hash for the activation process to detect changes. + # Must be in the main file as it's the only thing home-manager switch process looks at. + # WantedBy must be set through `systemd.user.services` which generates .targets.wants symlinks. + # sd-switch only starts new services with those symlinks. + ${p._serviceName} = { + Unit.X-QuadletNixConfigHash = builtins.hashString "sha256" p._configText; + Service.Environment = [ "PATH=/run/wrappers/bin" ]; + Install.WantedBy = p._wantedBy; + }; + }) allObjects + ) // { + # TODO: link from ${pkgs.podman}/share/systemd/user/podman-auto-update.service + # when https://github.com/containers/podman/issues/24637 is fixed. + podman-auto-update = mkIf cfg.autoUpdate.enable { + Unit = { + Description = "Podman auto-update service"; + Documentation = "man:podman-auto-update(1)"; + }; + Service = { + Type = "oneshot"; + # podman rootless requires "newuidmap" (the suid version, not the non-suid one from pkgs.shadow) + Environment = "PATH=/run/wrappers/bin"; + ExecStart = "${getExe quadletUtils.podmanPackage} auto-update"; + ExecStartPost = "${getExe quadletUtils.podmanPackage} image prune -f"; + TimeoutStartSec = "900s"; + TimeoutStopSec = "10s"; + }; }; }; + systemd.user.timers.podman-auto-update = mkIf cfg.autoUpdate.enable { Unit = { Description = "Podman auto-update timer"; diff --git a/network.nix b/network.nix index 5be7cfe..2ec0609 100644 --- a/network.nix +++ b/network.nix @@ -160,8 +160,9 @@ in }; _name = mkOption { internal = true; }; - _unitName = mkOption { internal = true; }; + _serviceName = mkOption { internal = true; }; _configText = mkOption { internal = true; }; + _wantedBy = mkOption { internal = true; }; ref = mkOption { readOnly = true; }; }; @@ -170,13 +171,12 @@ in networkName = if config.networkConfig.name != null then config.networkConfig.name else "systemd-${name}"; networkConfig = config.networkConfig; + wantedBy = if config.autoStart then [ quadletUtils.defaultTarget ] else [ ]; unitConfig = { Unit = { Description = "Podman network ${name}"; } // config.unitConfig; - Install = { - WantedBy = if config.autoStart then [ quadletUtils.defaultTarget ] else [ ]; - }; + Install.WantedBy = wantedBy; Network = quadletUtils.configToProperties networkConfig networkOpts; Service = { ExecStop = "${getExe quadletUtils.podmanPackage} network rm ${networkName}"; @@ -185,8 +185,9 @@ in in { _name = networkName; - _unitName = "${name}-network.service"; + _serviceName = "${name}-network"; _configText = quadletUtils.unitConfigToText unitConfig; + _wantedBy = wantedBy; ref = "${name}.network"; }; } diff --git a/nixos-module.nix b/nixos-module.nix index a30b00d..3972859 100644 --- a/nixos-module.nix +++ b/nixos-module.nix @@ -80,20 +80,19 @@ in systemd.packages = [ (pkgs.linkFarm "quadlet-service-symlinks" ( map (p: { - name = "etc/systemd/system/${p._unitName}"; - path = "/run/systemd/generator/${p._unitName}"; + name = "etc/systemd/system/${p._serviceName}.service"; + path = "/run/systemd/generator/${p._serviceName}.service"; }) allObjects )) ]; # Inject X-RestartIfChanged=${hash} for NixOS to detect changes. systemd.units = mergeAttrsList ( map (p: { - ${p._unitName} = { + "${p._serviceName}.service" = { overrideStrategy = "asDropin"; - text = '' - [Unit] - X-QuadletNixConfigHash=${builtins.hashString "sha256" p._configText} - ''; + text = quadletUtils.unitConfigToText { + Unit.X-QuadletNixConfigHash = builtins.hashString "sha256" p._configText; + }; }; }) allObjects ); diff --git a/pod.nix b/pod.nix index 4646653..a2b6f0d 100644 --- a/pod.nix +++ b/pod.nix @@ -192,8 +192,9 @@ in }; _name = mkOption { internal = true; }; - _unitName = mkOption { internal = true; }; + _serviceName = mkOption { internal = true; }; _configText = mkOption { internal = true; }; + _wantedBy = mkOption { internal = true; }; ref = mkOption { readOnly = true; }; }; @@ -207,21 +208,21 @@ in podConfig = config.podConfig // { name = podName; }; + wantedBy = if config.autoStart then [ quadletUtils.defaultTarget ] else [ ]; unitConfig = { Unit = { Description = "Podman pod ${name}"; } // config.unitConfig; - Install = { - WantedBy = if config.autoStart then [ quadletUtils.defaultTarget ] else [ ]; - }; + Install.WantedBy = wantedBy; Pod = quadletUtils.configToProperties podConfig podOpts; Service = serviceConfigDefault // config.serviceConfig; }; in { _name = podName; - _unitName = "${name}-pod.service"; + _serviceName = "${name}-pod"; _configText = quadletUtils.unitConfigToText unitConfig; + _wantedBy = wantedBy; ref = "${name}.pod"; }; } diff --git a/tests/flake.nix b/tests/flake.nix index c838621..cf40ff1 100644 --- a/tests/flake.nix +++ b/tests/flake.nix @@ -6,7 +6,6 @@ # inputs path to be set in --override-input inputs = { nixpkgs.url = "path:/dev/null"; - nixpkgs-2405.url = "github:NixOS/nixpkgs/nixos-24.05"; quadlet-nix.url = "path:/dev/null"; quadlet-nix.inputs.nixpkgs.follows = "nixpkgs"; @@ -18,7 +17,7 @@ }; outputs = - { test-config, nixpkgs, nixpkgs-2405, home-manager, quadlet-nix, ... }: let + { test-config, nixpkgs, home-manager, quadlet-nix, ... }: let system = test-config.system; makeTestScript = { user, testScript }: { nodes, ... }: '' import json @@ -80,8 +79,6 @@ users.groups.alice = {}; home-manager.users.alice = lib.mkDefault ({ ... }: { - # sd-switch 0.5.0 doesn't start services on boot - nixpkgs.overlays = [ (final: prev: { sd-switch = pkgs.sd-switch; }) ]; imports = [ quadlet-nix.homeManagerModules.quadlet testConfig @@ -120,17 +117,7 @@ checks = let pkgs = import nixpkgs { inherit system; }; genRootfulTest = genTest pkgs runRootfulTest; - sdSwitchBugAffected = let - version = pkgs.sd-switch.version; - in builtins.compareVersions version "0.5.0" >= 0; - sdSwitchBugOverlay = final: prev: { - sd-switch = (import nixpkgs-2405 { inherit system; }).sd-switch; - }; - rootlessPkgs = if !sdSwitchBugAffected then pkgs else import nixpkgs { - inherit system; - overlays = [ sdSwitchBugOverlay ]; - }; - genRootlessTest = genTest rootlessPkgs runRootlessTest; + genRootlessTest = genTest pkgs runRootlessTest; tests = builtins.listToAttrs [ (genRootfulTest ./basic.nix) (genRootlessTest ./basic.nix)