Skip to content

Commit

Permalink
nixos: use user service for activation
Browse files Browse the repository at this point in the history
  • Loading branch information
pasqui23 committed Dec 11, 2021
1 parent 6fe3b53 commit 25ab14f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 37 deletions.
23 changes: 21 additions & 2 deletions modules/programs/ssh.nix
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,23 @@ in
for more information.
'';
};

configPath = mkOption {
type = types.path;
internal = true;
description = ''
Path to the ssh configuration.
'';
};

internallyManaged = mkOption {
type = types.bool;
default = true;
internal = true;
description = ''
Whether to link .ssh/config to programs.ssh.configPath
'';
};
};

config = mkIf cfg.enable {
Expand All @@ -480,15 +497,17 @@ in
}
];

home.file.".ssh/config".text =
home.file.".ssh/config".source = mkIf cfg.internallyManaged cfg.configPath;

programs.ssh.configPath =
let
sortedMatchBlocks = hm.dag.topoSort cfg.matchBlocks;
sortedMatchBlocksStr = builtins.toJSON sortedMatchBlocks;
matchBlocks =
if sortedMatchBlocks ? result
then sortedMatchBlocks.result
else abort "Dependency cycle in SSH match blocks: ${sortedMatchBlocksStr}";
in ''
in pkgs.writeText "ssh_config" ''
${concatStringsSep "\n" (
(mapAttrsToList (n: v: "${n} ${v}") cfg.extraOptionOverrides)
++ (optional (cfg.includes != [ ]) ''
Expand Down
68 changes: 33 additions & 35 deletions nixos/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ let
# Make activation script use same version of Nix as system as a whole.
# This avoids problems with Nix not being in PATH.
home.extraActivationPath = [ config.nix.package ];

# .ssh/config needs to exists before login to let ssh login as that user
programs.ssh.internallyManaged = false;
};
})
] ++ cfg.sharedModules;
Expand Down Expand Up @@ -130,15 +133,11 @@ in {

systemd.services = mapAttrs' (_: usercfg:
let username = usercfg.home.username;
in nameValuePair ("home-manager-${utils.escapeSystemdPath username}") {
description = "Home Manager environment for ${username}";
in nameValuePair "ssh_config-${utils.escapeSystemdPath username}" (lib.mkIf usercfg.programs.ssh.enable {
description = "Linking ${username}' ssh conifg";
wantedBy = [ "multi-user.target" ];
wants = [ "nix-daemon.socket" ];
after = [ "nix-daemon.socket" ];
before = [ "systemd-user-sessions.service" ];

environment = serviceEnvironment;

unitConfig = { RequiresMountsFor = usercfg.home.homeDirectory; };

stopIfChanged = false;
Expand All @@ -148,37 +147,36 @@ in {
Type = "oneshot";
RemainAfterExit = "yes";
TimeoutStartSec = 90;

ExecStart = ["${pkgs.coreutils}/bin/ln -s ${usercfg.programs.ssh.configPath} ${usercfg.home.homeDirectory}/.ssh/config"];
};
})) cfg.users;

systemd.user.services = mapAttrs' (_: usercfg:
let username = usercfg.home.username;
in nameValuePair ("home-manager-${utils.escapeSystemdPath username}") {
description = "Home Manager environment for ${username}";
wantedBy = [ "default.target" ];

# user units cannot depend on system units
# TODO: Insert in the script logic for waiting on the nix socket via dbus
# like https://github.com/mogorman/systemd-lock-handler
# wants = [ "nix-daemon.socket" ];
# after = [ "nix-daemon.socket" ];

environment = serviceEnvironment;

unitConfig.ConditionUser = username; # each user will execute only its own activation

stopIfChanged = false;

serviceConfig = {
Type = "oneshot";
RemainAfterExit = "yes";
TimeoutStartSec = 90;
SyslogIdentifier = "hm-activate-${username}";

ExecStart = let
systemctl =
"XDG_RUNTIME_DIR=\${XDG_RUNTIME_DIR:-/run/user/$UID} systemctl";

sed = "${pkgs.gnused}/bin/sed";

exportedSystemdVariables = concatStringsSep "|" [
"DBUS_SESSION_BUS_ADDRESS"
"DISPLAY"
"WAYLAND_DISPLAY"
"XAUTHORITY"
"XDG_RUNTIME_DIR"
];

setupEnv = pkgs.writeScript "hm-setup-env" ''
#! ${pkgs.runtimeShell} -el
# The activation script is run by a login shell to make sure
# that the user is given a sane environment.
# If the user is logged in, import variables from their current
# session environment.
eval "$(
${systemctl} --user show-environment 2> /dev/null \
| ${sed} -En '/^(${exportedSystemdVariables})=/s/^/export /p'
)"
exec "$1/activate"
'';
in "${setupEnv} ${usercfg.home.activationPackage}";
ExecStart = usercfg.home.activationPackage;
};
}) cfg.users;
};
Expand Down

0 comments on commit 25ab14f

Please sign in to comment.