Skip to content

Commit

Permalink
fix: fixes integration with latest sd-switch.
Browse files Browse the repository at this point in the history
  • Loading branch information
SEIAROTg committed Dec 20, 2024
1 parent 75a3064 commit 03fc47a
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 73 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
11 changes: 6 additions & 5 deletions container.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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; };
};

Expand All @@ -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";
};
}
71 changes: 37 additions & 34 deletions home-manager-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -70,52 +70,55 @@ 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
) // {
# the stock service uses `sh` instead of `/bin/sh`.
# 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";
Expand Down
11 changes: 6 additions & 5 deletions network.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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; };
};

Expand All @@ -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}";
Expand All @@ -185,8 +185,9 @@ in
in
{
_name = networkName;
_unitName = "${name}-network.service";
_serviceName = "${name}-network";
_configText = quadletUtils.unitConfigToText unitConfig;
_wantedBy = wantedBy;
ref = "${name}.network";
};
}
13 changes: 6 additions & 7 deletions nixos-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
Expand Down
11 changes: 6 additions & 5 deletions pod.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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; };
};

Expand All @@ -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";
};
}
17 changes: 2 additions & 15 deletions tests/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 03fc47a

Please sign in to comment.