mirror of
https://github.com/nix-community/home-manager.git
synced 2026-01-11 17:39:37 +08:00
Compare commits
24 Commits
a65c04965c
...
38e187fd2f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38e187fd2f | ||
|
|
9bfca5b3a7 | ||
|
|
bfaba198af | ||
|
|
b1421bdfe5 | ||
|
|
4cd7ae4cd4 | ||
|
|
e43f7c3321 | ||
|
|
6841643203 | ||
|
|
a755d94ab0 | ||
|
|
33fe25dbe5 | ||
|
|
337d3602c0 | ||
|
|
5d814af6af | ||
|
|
787784fb6f | ||
|
|
2379f704b0 | ||
|
|
a26335db1b | ||
|
|
d016674f6a | ||
|
|
c2d3a75ebe | ||
|
|
93af99ec02 | ||
|
|
c8b68aafed | ||
|
|
bca7415de4 | ||
|
|
d070d83048 | ||
|
|
048104c098 | ||
|
|
af894fbbc7 | ||
|
|
53084c95ce | ||
|
|
2f93d7333e |
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: Home Manager\n"
|
"Project-Id-Version: Home Manager\n"
|
||||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||||
"POT-Creation-Date: 2025-07-22 10:59+0200\n"
|
"POT-Creation-Date: 2025-07-22 10:59+0200\n"
|
||||||
"PO-Revision-Date: 2025-12-04 04:17+0000\n"
|
"PO-Revision-Date: 2025-12-04 09:16+0000\n"
|
||||||
"Last-Translator: \"Urocissa Caerulea.Tw\" <urocissa.tw@proton.me>\n"
|
"Last-Translator: \"Urocissa Caerulea.Tw\" <urocissa.tw@proton.me>\n"
|
||||||
"Language-Team: Chinese (Traditional Han script) <https://hosted.weblate.org/"
|
"Language-Team: Chinese (Traditional Han script) <https://hosted.weblate.org/"
|
||||||
"projects/home-manager/cli/zh_Hant/>\n"
|
"projects/home-manager/cli/zh_Hant/>\n"
|
||||||
@@ -215,7 +215,7 @@ msgstr "沒有即將過期的世代"
|
|||||||
|
|
||||||
#: home-manager/home-manager:877
|
#: home-manager/home-manager:877
|
||||||
msgid "No home-manager packages seem to be installed."
|
msgid "No home-manager packages seem to be installed."
|
||||||
msgstr "似乎沒有安裝 home-manager 軟體包。"
|
msgstr "似乎沒有安裝 home-manager 套件。"
|
||||||
|
|
||||||
#: home-manager/home-manager:962
|
#: home-manager/home-manager:962
|
||||||
msgid "Unknown argument %s"
|
msgid "Unknown argument %s"
|
||||||
@@ -223,11 +223,11 @@ msgstr "未知引數 %s"
|
|||||||
|
|
||||||
#: home-manager/home-manager:987
|
#: home-manager/home-manager:987
|
||||||
msgid "This will remove Home Manager from your system."
|
msgid "This will remove Home Manager from your system."
|
||||||
msgstr "這將會從系統中移除 Home Manager。"
|
msgstr "這將會從您的系統中移除 Home Manager。"
|
||||||
|
|
||||||
#: home-manager/home-manager:990
|
#: home-manager/home-manager:990
|
||||||
msgid "This is a dry run, nothing will actually be uninstalled."
|
msgid "This is a dry run, nothing will actually be uninstalled."
|
||||||
msgstr "這是試執行結果,沒有實際解除安裝任何軟體包。"
|
msgstr "這是模擬執行,實際上並不會解除安裝任何內容。"
|
||||||
|
|
||||||
#: home-manager/home-manager:994
|
#: home-manager/home-manager:994
|
||||||
msgid "Really uninstall Home Manager?"
|
msgid "Really uninstall Home Manager?"
|
||||||
@@ -235,27 +235,27 @@ msgstr "確定要解除安裝 Home Manager 嗎?"
|
|||||||
|
|
||||||
#: home-manager/home-manager:1000
|
#: home-manager/home-manager:1000
|
||||||
msgid "Switching to empty Home Manager configuration..."
|
msgid "Switching to empty Home Manager configuration..."
|
||||||
msgstr "正在切換至空的 Home Manager 配置 ..."
|
msgstr "正在切換至空的 Home Manager 設定..."
|
||||||
|
|
||||||
#: home-manager/home-manager:1015
|
#: home-manager/home-manager:1015
|
||||||
msgid "Yay!"
|
msgid "Yay!"
|
||||||
msgstr "好耶!"
|
msgstr "太好了!"
|
||||||
|
|
||||||
#: home-manager/home-manager:1020
|
#: home-manager/home-manager:1020
|
||||||
msgid "Home Manager is uninstalled but your home.nix is left untouched."
|
msgid "Home Manager is uninstalled but your home.nix is left untouched."
|
||||||
msgstr "Home Manager 已解除安裝,但未改動您的 home.nix 配置檔案。"
|
msgstr "Home Manager 已解除安裝,但您的 home.nix 保持不變。"
|
||||||
|
|
||||||
#: home-manager/home-manager:1285
|
#: home-manager/home-manager:1285
|
||||||
msgid "expire-generations expects one argument, got %d."
|
msgid "expire-generations expects one argument, got %d."
|
||||||
msgstr "expire-generations 須要一個引數,但獲取到了 %d 個。"
|
msgstr "expire-generations 預期一個引數,但得到了 %d 個。"
|
||||||
|
|
||||||
#: home-manager/home-manager:1310
|
#: home-manager/home-manager:1310
|
||||||
msgid "Unknown command: %s"
|
msgid "Unknown command: %s"
|
||||||
msgstr "未知命令:%s"
|
msgstr "未知指令:%s"
|
||||||
|
|
||||||
#: home-manager/install.nix:21
|
#: home-manager/install.nix:21
|
||||||
msgid "This derivation is not buildable, please run it using nix-shell."
|
msgid "This derivation is not buildable, please run it using nix-shell."
|
||||||
msgstr "此配置檔案/變體不可構建,請在 nix-shell 中執行它。"
|
msgstr "此 derivation 無法建置,請使用 nix-shell 執行。"
|
||||||
|
|
||||||
#, sh-format
|
#, sh-format
|
||||||
#~ msgid "Please set the $EDITOR environment variable"
|
#~ msgid "Please set the $EDITOR environment variable"
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ in
|
|||||||
xdg.stateHome = mkOptionDefault defaultStateHome;
|
xdg.stateHome = mkOptionDefault defaultStateHome;
|
||||||
|
|
||||||
home.sessionVariables = variables;
|
home.sessionVariables = variables;
|
||||||
systemd.user.sessionVariables = mkIf pkgs.stdenv.hostPlatform.isLinux variables;
|
systemd.user.sessionVariables = variables;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ let
|
|||||||
tomlFormat = pkgs.formats.toml { };
|
tomlFormat = pkgs.formats.toml { };
|
||||||
|
|
||||||
inherit (lib) mkIf mkOption types;
|
inherit (lib) mkIf mkOption types;
|
||||||
inherit (pkgs.stdenv) isLinux isDarwin;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
meta.maintainers = with lib.maintainers; [
|
meta.maintainers = with lib.maintainers; [
|
||||||
@@ -221,98 +220,82 @@ in
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
(mkIf daemonCfg.enable (
|
(mkIf daemonCfg.enable {
|
||||||
lib.mkMerge [
|
assertions = [
|
||||||
{
|
{
|
||||||
assertions = [
|
assertion = lib.versionAtLeast cfg.package.version "18.2.0";
|
||||||
{
|
message = ''
|
||||||
assertion = lib.versionAtLeast cfg.package.version "18.2.0";
|
The Atuin daemon requires at least version 18.2.0 or later.
|
||||||
message = ''
|
'';
|
||||||
The Atuin daemon requires at least version 18.2.0 or later.
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
{
|
|
||||||
assertion = isLinux || isDarwin;
|
|
||||||
message = "The Atuin daemon can only be configured on either Linux or macOS.";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
programs.atuin.settings = {
|
|
||||||
daemon = {
|
|
||||||
enabled = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
(mkIf isLinux {
|
{
|
||||||
programs.atuin.settings = {
|
assertion = config.systemd.user.enable || config.launchd.enable;
|
||||||
daemon = {
|
message = "The Atuin daemon can only be configured on systems with systemd or launchd.";
|
||||||
systemd_socket = true;
|
}
|
||||||
};
|
];
|
||||||
};
|
|
||||||
|
|
||||||
systemd.user.services.atuin-daemon = {
|
programs.atuin.settings.daemon = {
|
||||||
Unit = {
|
enabled = true;
|
||||||
Description = "Atuin daemon";
|
systemd_socket = config.systemd.user.enable;
|
||||||
Requires = [ "atuin-daemon.socket" ];
|
socket_path = lib.mkIf (!config.systemd.user.enable) (
|
||||||
};
|
lib.mkDefault "${config.xdg.dataHome}/atuin/daemon.sock"
|
||||||
Install = {
|
);
|
||||||
Also = [ "atuin-daemon.socket" ];
|
};
|
||||||
WantedBy = [ "default.target" ];
|
|
||||||
};
|
|
||||||
Service = {
|
|
||||||
ExecStart = "${lib.getExe cfg.package} daemon";
|
|
||||||
Environment = lib.optionals (daemonCfg.logLevel != null) [ "ATUIN_LOG=${daemonCfg.logLevel}" ];
|
|
||||||
Restart = "on-failure";
|
|
||||||
RestartSteps = 3;
|
|
||||||
RestartMaxDelaySec = 6;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.user.sockets.atuin-daemon =
|
systemd.user.services.atuin-daemon = {
|
||||||
let
|
Unit = {
|
||||||
socket_dir = if lib.versionAtLeast cfg.package.version "18.4.0" then "%t" else "%D/atuin";
|
Description = "Atuin daemon";
|
||||||
in
|
Requires = [ "atuin-daemon.socket" ];
|
||||||
{
|
};
|
||||||
Unit = {
|
Install = {
|
||||||
Description = "Atuin daemon socket";
|
Also = [ "atuin-daemon.socket" ];
|
||||||
};
|
WantedBy = [ "default.target" ];
|
||||||
Install = {
|
};
|
||||||
WantedBy = [ "sockets.target" ];
|
Service = {
|
||||||
};
|
ExecStart = "${lib.getExe cfg.package} daemon";
|
||||||
Socket = {
|
Environment = lib.optionals (daemonCfg.logLevel != null) [ "ATUIN_LOG=${daemonCfg.logLevel}" ];
|
||||||
ListenStream = "${socket_dir}/atuin.sock";
|
Restart = "on-failure";
|
||||||
SocketMode = "0600";
|
RestartSteps = 3;
|
||||||
RemoveOnStop = true;
|
RestartMaxDelaySec = 6;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
|
||||||
(mkIf isDarwin {
|
|
||||||
programs.atuin.settings = {
|
|
||||||
daemon = {
|
|
||||||
socket_path = lib.mkDefault "${config.xdg.dataHome}/atuin/daemon.sock";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
launchd.agents.atuin-daemon = {
|
systemd.user.sockets.atuin-daemon =
|
||||||
enable = true;
|
let
|
||||||
config = {
|
socket_dir = if lib.versionAtLeast cfg.package.version "18.4.0" then "%t" else "%D/atuin";
|
||||||
ProgramArguments = [
|
in
|
||||||
"${lib.getExe cfg.package}"
|
{
|
||||||
"daemon"
|
Unit = {
|
||||||
];
|
Description = "Atuin daemon socket";
|
||||||
EnvironmentVariables = lib.optionalAttrs (daemonCfg.logLevel != null) {
|
|
||||||
ATUIN_LOG = daemonCfg.logLevel;
|
|
||||||
};
|
|
||||||
KeepAlive = {
|
|
||||||
Crashed = true;
|
|
||||||
SuccessfulExit = false;
|
|
||||||
};
|
|
||||||
ProcessType = "Background";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
})
|
Install = {
|
||||||
]
|
WantedBy = [ "sockets.target" ];
|
||||||
))
|
};
|
||||||
|
Socket = {
|
||||||
|
ListenStream = "${socket_dir}/atuin.sock";
|
||||||
|
SocketMode = "0600";
|
||||||
|
RemoveOnStop = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
launchd.agents.atuin-daemon = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
ProgramArguments = [
|
||||||
|
"${lib.getExe cfg.package}"
|
||||||
|
"daemon"
|
||||||
|
];
|
||||||
|
EnvironmentVariables = lib.optionalAttrs (daemonCfg.logLevel != null) {
|
||||||
|
ATUIN_LOG = daemonCfg.logLevel;
|
||||||
|
};
|
||||||
|
KeepAlive = {
|
||||||
|
Crashed = true;
|
||||||
|
SuccessfulExit = false;
|
||||||
|
};
|
||||||
|
ProcessType = "Background";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ let
|
|||||||
cfg = config.programs.bashmount;
|
cfg = config.programs.bashmount;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
meta.maintainers = [ lib.maintainers.AndersonTorres ];
|
meta.maintainers = [ ];
|
||||||
|
|
||||||
options.programs.bashmount = {
|
options.programs.bashmount = {
|
||||||
enable = lib.mkEnableOption "bashmount";
|
enable = lib.mkEnableOption "bashmount";
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ let
|
|||||||
iniFormat = pkgs.formats.ini { };
|
iniFormat = pkgs.formats.ini { };
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
meta.maintainers = with lib.maintainers; [ AndersonTorres ];
|
meta.maintainers = with lib.maintainers; [ ];
|
||||||
|
|
||||||
options.programs.havoc = {
|
options.programs.havoc = {
|
||||||
enable = lib.mkEnableOption "Havoc terminal";
|
enable = lib.mkEnableOption "Havoc terminal";
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ in
|
|||||||
|
|
||||||
generatedConfigs =
|
generatedConfigs =
|
||||||
let
|
let
|
||||||
grouped = builtins.groupBy (x: x.type) pluginsNormalized;
|
grouped = lib.groupBy (x: x.type) pluginsNormalized;
|
||||||
configsOnly = lib.foldl (acc: p: if p.config != null then acc ++ [ p.config ] else acc) [ ];
|
configsOnly = lib.foldl (acc: p: if p.config != null then acc ++ [ p.config ] else acc) [ ];
|
||||||
in
|
in
|
||||||
lib.mapAttrs (_name: vals: lib.concatStringsSep "\n" (configsOnly vals)) grouped;
|
lib.mapAttrs (_name: vals: lib.concatStringsSep "\n" (configsOnly vals)) grouped;
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ in
|
|||||||
lib.optional (cfg.clean.enable && config.nix.gc.automatic)
|
lib.optional (cfg.clean.enable && config.nix.gc.automatic)
|
||||||
"programs.nh.clean.enable and nix.gc.automatic (Home-Manager) are both enabled. Please use one or the other to avoid conflict.";
|
"programs.nh.clean.enable and nix.gc.automatic (Home-Manager) are both enabled. Please use one or the other to avoid conflict.";
|
||||||
|
|
||||||
assertions = lib.optionals pkgs.stdenv.isDarwin [
|
assertions = [
|
||||||
(lib.hm.darwin.assertInterval "programs.nh.clean.dates" cfg.clean.dates pkgs)
|
(lib.hm.darwin.assertInterval "programs.nh.clean.dates" cfg.clean.dates pkgs)
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -131,30 +131,25 @@ in
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.user = lib.mkIf (cfg.clean.enable && pkgs.stdenv.isLinux) {
|
systemd.user = lib.mkIf cfg.clean.enable {
|
||||||
services.nh-clean = {
|
services.nh-clean = {
|
||||||
Unit.Description = "Nh clean (user)";
|
Unit.Description = "Nh clean (user)";
|
||||||
|
|
||||||
Service = {
|
Service = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
ExecStart = "${lib.getExe cfg.package} clean user ${cfg.clean.extraArgs}";
|
ExecStart = "${lib.getExe cfg.package} clean user ${cfg.clean.extraArgs}";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
timers.nh-clean = {
|
timers.nh-clean = {
|
||||||
Unit.Description = "Run nh clean";
|
Unit.Description = "Run nh clean";
|
||||||
|
|
||||||
Timer = {
|
Timer = {
|
||||||
OnCalendar = cfg.clean.dates;
|
OnCalendar = cfg.clean.dates;
|
||||||
Persistent = true;
|
Persistent = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
Install.WantedBy = [ "timers.target" ];
|
Install.WantedBy = [ "timers.target" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
launchd.agents.nh-clean = lib.mkIf (cfg.clean.enable && pkgs.stdenv.isDarwin) {
|
launchd.agents.nh-clean = lib.mkIf cfg.clean.enable {
|
||||||
enable = true;
|
enable = true;
|
||||||
config = {
|
config = {
|
||||||
ProgramArguments = [
|
ProgramArguments = [
|
||||||
@@ -163,9 +158,7 @@ in
|
|||||||
"user"
|
"user"
|
||||||
]
|
]
|
||||||
++ lib.optional (cfg.clean.extraArgs != "") cfg.clean.extraArgs;
|
++ lib.optional (cfg.clean.extraArgs != "") cfg.clean.extraArgs;
|
||||||
|
|
||||||
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval cfg.clean.dates;
|
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval cfg.clean.dates;
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,78 +32,72 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf serviceConfig.enable (
|
config = lib.mkIf serviceConfig.enable {
|
||||||
lib.mkMerge [
|
systemd.user = {
|
||||||
(lib.mkIf pkgs.stdenv.isLinux {
|
services.borgmatic = {
|
||||||
systemd.user = {
|
Unit = {
|
||||||
services.borgmatic = {
|
Description = "borgmatic backup";
|
||||||
Unit = {
|
# Prevent borgmatic from running unless the machine is
|
||||||
Description = "borgmatic backup";
|
# plugged into power:
|
||||||
# Prevent borgmatic from running unless the machine is
|
ConditionACPower = true;
|
||||||
# plugged into power:
|
|
||||||
ConditionACPower = true;
|
|
||||||
};
|
|
||||||
Service = {
|
|
||||||
Type = "oneshot";
|
|
||||||
|
|
||||||
# Lower CPU and I/O priority:
|
|
||||||
Nice = 19;
|
|
||||||
IOSchedulingClass = "best-effort";
|
|
||||||
IOSchedulingPriority = 7;
|
|
||||||
IOWeight = 100;
|
|
||||||
|
|
||||||
Restart = "no";
|
|
||||||
LogRateLimitIntervalSec = 0;
|
|
||||||
|
|
||||||
# Delay start to prevent backups running during boot:
|
|
||||||
ExecStartPre = "${pkgs.coreutils}/bin/sleep 3m";
|
|
||||||
|
|
||||||
ExecStart = ''
|
|
||||||
${pkgs.systemd}/bin/systemd-inhibit \
|
|
||||||
--who="borgmatic" \
|
|
||||||
--what="sleep:shutdown" \
|
|
||||||
--why="Prevent interrupting scheduled backup" \
|
|
||||||
${programConfig.package}/bin/borgmatic \
|
|
||||||
--stats \
|
|
||||||
--verbosity -1 \
|
|
||||||
--list \
|
|
||||||
--syslog-verbosity 1
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
timers.borgmatic = {
|
|
||||||
Unit.Description = "Run borgmatic backup";
|
|
||||||
Timer = {
|
|
||||||
OnCalendar = serviceConfig.frequency;
|
|
||||||
Persistent = true;
|
|
||||||
RandomizedDelaySec = "10m";
|
|
||||||
};
|
|
||||||
Install.WantedBy = [ "timers.target" ];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
})
|
Service = {
|
||||||
|
Type = "oneshot";
|
||||||
|
|
||||||
(lib.mkIf pkgs.stdenv.isDarwin {
|
# Lower CPU and I/O priority:
|
||||||
assertions = [
|
Nice = 19;
|
||||||
(lib.hm.darwin.assertInterval "services.borgmatic.frequency" serviceConfig.frequency pkgs)
|
IOSchedulingClass = "best-effort";
|
||||||
|
IOSchedulingPriority = 7;
|
||||||
|
IOWeight = 100;
|
||||||
|
|
||||||
|
Restart = "no";
|
||||||
|
LogRateLimitIntervalSec = 0;
|
||||||
|
|
||||||
|
# Delay start to prevent backups running during boot:
|
||||||
|
ExecStartPre = "${pkgs.coreutils}/bin/sleep 3m";
|
||||||
|
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.systemd}/bin/systemd-inhibit \
|
||||||
|
--who="borgmatic" \
|
||||||
|
--what="sleep:shutdown" \
|
||||||
|
--why="Prevent interrupting scheduled backup" \
|
||||||
|
${programConfig.package}/bin/borgmatic \
|
||||||
|
--stats \
|
||||||
|
--verbosity -1 \
|
||||||
|
--list \
|
||||||
|
--syslog-verbosity 1
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
timers.borgmatic = {
|
||||||
|
Unit.Description = "Run borgmatic backup";
|
||||||
|
Timer = {
|
||||||
|
OnCalendar = serviceConfig.frequency;
|
||||||
|
Persistent = true;
|
||||||
|
RandomizedDelaySec = "10m";
|
||||||
|
};
|
||||||
|
Install.WantedBy = [ "timers.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
assertions = [
|
||||||
|
(lib.hm.darwin.assertInterval "services.borgmatic.frequency" serviceConfig.frequency pkgs)
|
||||||
|
];
|
||||||
|
|
||||||
|
launchd.agents.borgmatic = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
ProgramArguments = [
|
||||||
|
(lib.getExe programConfig.package)
|
||||||
|
"--stats"
|
||||||
|
"--list"
|
||||||
];
|
];
|
||||||
|
ProcessType = "Background";
|
||||||
launchd.agents.borgmatic = {
|
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval serviceConfig.frequency;
|
||||||
enable = true;
|
StandardOutPath = "${config.home.homeDirectory}/Library/Logs/borgmatic/launchd-stdout.log";
|
||||||
config = {
|
StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/borgmatic/launchd-stderr.log";
|
||||||
ProgramArguments = [
|
};
|
||||||
(lib.getExe programConfig.package)
|
};
|
||||||
"--stats"
|
};
|
||||||
"--list"
|
|
||||||
];
|
|
||||||
ProcessType = "Background";
|
|
||||||
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval serviceConfig.frequency;
|
|
||||||
StandardOutPath = "${config.home.homeDirectory}/Library/Logs/borgmatic/launchd-stdout.log";
|
|
||||||
StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/borgmatic/launchd-stderr.log";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ in
|
|||||||
|
|
||||||
xdg.configFile."clipse/custom_theme.json".source = jsonFormat.generate "theme" cfg.theme;
|
xdg.configFile."clipse/custom_theme.json".source = jsonFormat.generate "theme" cfg.theme;
|
||||||
|
|
||||||
systemd.user.services.clipse = lib.mkIf (pkgs.stdenv.isLinux && (cfg.package != null)) {
|
systemd.user.services.clipse = lib.mkIf (cfg.package != null) {
|
||||||
Unit = {
|
Unit = {
|
||||||
Description = "Clipse listener";
|
Description = "Clipse listener";
|
||||||
PartOf = [ "graphical-session.target" ];
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable ({
|
config = lib.mkIf cfg.enable {
|
||||||
assertions = [
|
assertions = [
|
||||||
{
|
{
|
||||||
assertion = (lib.count (p: p.isActive) (lib.attrValues cfg.profiles)) <= 1;
|
assertion = (lib.count (p: p.isActive) (lib.attrValues cfg.profiles)) <= 1;
|
||||||
@@ -189,78 +189,74 @@ in
|
|||||||
if activeProfile.name != "default" then "colima-${activeProfile.name}" else "colima"
|
if activeProfile.name != "default" then "colima-${activeProfile.name}" else "colima"
|
||||||
);
|
);
|
||||||
|
|
||||||
launchd.agents = lib.mkIf pkgs.stdenv.isDarwin (
|
launchd.agents = lib.mapAttrs' (
|
||||||
lib.mapAttrs' (
|
name: profile:
|
||||||
name: profile:
|
lib.nameValuePair "colima-${name}" {
|
||||||
lib.nameValuePair "colima-${name}" {
|
enable = true;
|
||||||
enable = true;
|
config = {
|
||||||
config = {
|
ProgramArguments = [
|
||||||
ProgramArguments = [
|
"${lib.getExe cfg.package}"
|
||||||
"${lib.getExe cfg.package}"
|
"start"
|
||||||
"start"
|
name
|
||||||
name
|
"-f"
|
||||||
"-f"
|
"--activate=${if profile.isActive then "true" else "false"}"
|
||||||
"--activate=${if profile.isActive then "true" else "false"}"
|
"--save-config=false"
|
||||||
"--save-config=false"
|
];
|
||||||
];
|
KeepAlive = true;
|
||||||
KeepAlive = true;
|
RunAtLoad = true;
|
||||||
RunAtLoad = true;
|
EnvironmentVariables.PATH = lib.makeBinPath [
|
||||||
EnvironmentVariables.PATH = lib.makeBinPath [
|
cfg.package
|
||||||
cfg.package
|
cfg.perlPackage
|
||||||
cfg.perlPackage
|
cfg.dockerPackage
|
||||||
cfg.dockerPackage
|
cfg.sshPackage
|
||||||
cfg.sshPackage
|
cfg.coreutilsPackage
|
||||||
cfg.coreutilsPackage
|
cfg.curlPackage
|
||||||
cfg.curlPackage
|
cfg.bashPackage
|
||||||
cfg.bashPackage
|
pkgs.darwin.DarwinTools
|
||||||
pkgs.darwin.DarwinTools
|
];
|
||||||
];
|
StandardOutPath = profile.logFile;
|
||||||
StandardOutPath = profile.logFile;
|
StandardErrorPath = profile.logFile;
|
||||||
StandardErrorPath = profile.logFile;
|
};
|
||||||
};
|
}
|
||||||
}
|
) (lib.filterAttrs (_: p: p.isService) cfg.profiles);
|
||||||
) (lib.filterAttrs (_: p: p.isService) cfg.profiles)
|
|
||||||
);
|
|
||||||
|
|
||||||
systemd.user.services = lib.mkIf pkgs.stdenv.isLinux (
|
systemd.user.services = lib.mapAttrs' (
|
||||||
lib.mapAttrs' (
|
name: profile:
|
||||||
name: profile:
|
lib.nameValuePair "colima-${name}" {
|
||||||
lib.nameValuePair "colima-${name}" {
|
Unit = {
|
||||||
Unit = {
|
Description = "Colima container runtime (${name} profile)";
|
||||||
Description = "Colima container runtime (${name} profile)";
|
After = [ "network-online.target" ];
|
||||||
After = [ "network-online.target" ];
|
Wants = [ "network-online.target" ];
|
||||||
Wants = [ "network-online.target" ];
|
};
|
||||||
};
|
Service = {
|
||||||
Service = {
|
ExecStart = ''
|
||||||
ExecStart = ''
|
${lib.getExe cfg.package} start ${name} \
|
||||||
${lib.getExe cfg.package} start ${name} \
|
-f \
|
||||||
-f \
|
--activate=${if profile.isActive then "true" else "false"} \
|
||||||
--activate=${if profile.isActive then "true" else "false"} \
|
--save-config=false
|
||||||
--save-config=false
|
'';
|
||||||
'';
|
Restart = "always";
|
||||||
Restart = "always";
|
RestartSec = 2;
|
||||||
RestartSec = 2;
|
Environment = [
|
||||||
Environment = [
|
"PATH=${
|
||||||
"PATH=${
|
lib.makeBinPath [
|
||||||
lib.makeBinPath [
|
cfg.package
|
||||||
cfg.package
|
cfg.perlPackage
|
||||||
cfg.perlPackage
|
cfg.dockerPackage
|
||||||
cfg.dockerPackage
|
cfg.sshPackage
|
||||||
cfg.sshPackage
|
cfg.coreutilsPackage
|
||||||
cfg.coreutilsPackage
|
cfg.curlPackage
|
||||||
cfg.curlPackage
|
cfg.bashPackage
|
||||||
cfg.bashPackage
|
]
|
||||||
]
|
}"
|
||||||
}"
|
];
|
||||||
];
|
StandardOutput = "append:${profile.logFile}";
|
||||||
StandardOutput = "append:${profile.logFile}";
|
StandardError = "append:${profile.logFile}";
|
||||||
StandardError = "append:${profile.logFile}";
|
};
|
||||||
};
|
Install = {
|
||||||
Install = {
|
WantedBy = [ "default.target" ];
|
||||||
WantedBy = [ "default.target" ];
|
};
|
||||||
};
|
}
|
||||||
}
|
) (lib.filterAttrs (_: p: p.isService) cfg.profiles);
|
||||||
) (lib.filterAttrs (_: p: p.isService) cfg.profiles)
|
};
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,127 +119,117 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable (
|
config = mkIf cfg.enable {
|
||||||
lib.mkMerge [
|
home.sessionVariables =
|
||||||
{
|
let
|
||||||
home.sessionVariables =
|
editorBin = lib.getBin (
|
||||||
let
|
pkgs.writeShellScript "editor" ''exec ${lib.getBin cfg.package}/bin/emacsclient "''${@:---create-frame}"''
|
||||||
editorBin = lib.getBin (
|
);
|
||||||
pkgs.writeShellScript "editor" ''exec ${lib.getBin cfg.package}/bin/emacsclient "''${@:---create-frame}"''
|
in
|
||||||
);
|
mkIf cfg.defaultEditor {
|
||||||
in
|
EDITOR = editorBin;
|
||||||
mkIf cfg.defaultEditor {
|
VISUAL = editorBin;
|
||||||
EDITOR = editorBin;
|
};
|
||||||
VISUAL = editorBin;
|
|
||||||
};
|
home.packages = optional (cfg.client.enable && pkgs.stdenv.isLinux) (lib.hiPrio clientDesktopItem);
|
||||||
|
|
||||||
|
systemd.user.services.emacs = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Emacs text editor";
|
||||||
|
Documentation = "info:emacs man:emacs(1) https://gnu.org/software/emacs/";
|
||||||
|
|
||||||
|
After = optional (cfg.startWithUserSession == "graphical") "graphical-session.target";
|
||||||
|
PartOf = optional (cfg.startWithUserSession == "graphical") "graphical-session.target";
|
||||||
|
|
||||||
|
# Avoid killing the Emacs session, which may be full of
|
||||||
|
# unsaved buffers.
|
||||||
|
X-RestartIfChanged = false;
|
||||||
}
|
}
|
||||||
|
// optionalAttrs needsSocketWorkaround {
|
||||||
|
# Emacs deletes its socket when shutting down, which systemd doesn't
|
||||||
|
# handle, resulting in a server without a socket.
|
||||||
|
# See https://github.com/nix-community/home-manager/issues/2018
|
||||||
|
RefuseManualStart = true;
|
||||||
|
};
|
||||||
|
|
||||||
(mkIf pkgs.stdenv.isLinux {
|
Service = {
|
||||||
systemd.user.services.emacs = {
|
Type = "notify";
|
||||||
Unit = {
|
|
||||||
Description = "Emacs text editor";
|
|
||||||
Documentation = "info:emacs man:emacs(1) https://gnu.org/software/emacs/";
|
|
||||||
|
|
||||||
After = optional (cfg.startWithUserSession == "graphical") "graphical-session.target";
|
# We wrap ExecStart in a login shell so Emacs starts with the user's
|
||||||
PartOf = optional (cfg.startWithUserSession == "graphical") "graphical-session.target";
|
# environment, most importantly $PATH and $NIX_PROFILES. It may be
|
||||||
|
# worth investigating a more targeted approach for user services to
|
||||||
|
# import the user environment.
|
||||||
|
ExecStart = ''${pkgs.runtimeShell} -l -c "${emacsBinPath}/emacs --fg-daemon${
|
||||||
|
# In case the user sets 'server-directory' or 'server-name' in
|
||||||
|
# their Emacs config, we want to specify the socket path explicitly
|
||||||
|
# so launching 'emacs.service' manually doesn't break emacsclient
|
||||||
|
# when using socket activation.
|
||||||
|
lib.optionalString cfg.socketActivation.enable "=${lib.escapeShellArg socketPath}"
|
||||||
|
} ${lib.escapeShellArgs cfg.extraOptions}"'';
|
||||||
|
|
||||||
# Avoid killing the Emacs session, which may be full of
|
# Emacs will exit with status 15 after having received SIGTERM, which
|
||||||
# unsaved buffers.
|
# is the default "KillSignal" value systemd uses to stop services.
|
||||||
X-RestartIfChanged = false;
|
SuccessExitStatus = 15;
|
||||||
}
|
|
||||||
// optionalAttrs needsSocketWorkaround {
|
|
||||||
# Emacs deletes its socket when shutting down, which systemd doesn't
|
|
||||||
# handle, resulting in a server without a socket.
|
|
||||||
# See https://github.com/nix-community/home-manager/issues/2018
|
|
||||||
RefuseManualStart = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
Service = {
|
Restart = "on-failure";
|
||||||
Type = "notify";
|
}
|
||||||
|
// optionalAttrs needsSocketWorkaround {
|
||||||
|
# Use read-only directory permissions to prevent emacs from
|
||||||
|
# deleting systemd's socket file before exiting.
|
||||||
|
ExecStartPost = "${pkgs.coreutils}/bin/chmod --changes -w ${socketDir}";
|
||||||
|
ExecStopPost = "${pkgs.coreutils}/bin/chmod --changes +w ${socketDir}";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// optionalAttrs (cfg.startWithUserSession != false) {
|
||||||
|
Install = {
|
||||||
|
WantedBy = [
|
||||||
|
(if cfg.startWithUserSession == true then "default.target" else "graphical-session.target")
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# We wrap ExecStart in a login shell so Emacs starts with the user's
|
systemd.user.sockets.emacs = mkIf cfg.socketActivation.enable {
|
||||||
# environment, most importantly $PATH and $NIX_PROFILES. It may be
|
Unit = {
|
||||||
# worth investigating a more targeted approach for user services to
|
Description = "Emacs text editor";
|
||||||
# import the user environment.
|
Documentation = "info:emacs man:emacs(1) https://gnu.org/software/emacs/";
|
||||||
ExecStart = ''${pkgs.runtimeShell} -l -c "${emacsBinPath}/emacs --fg-daemon${
|
};
|
||||||
# In case the user sets 'server-directory' or 'server-name' in
|
|
||||||
# their Emacs config, we want to specify the socket path explicitly
|
|
||||||
# so launching 'emacs.service' manually doesn't break emacsclient
|
|
||||||
# when using socket activation.
|
|
||||||
lib.optionalString cfg.socketActivation.enable "=${lib.escapeShellArg socketPath}"
|
|
||||||
} ${lib.escapeShellArgs cfg.extraOptions}"'';
|
|
||||||
|
|
||||||
# Emacs will exit with status 15 after having received SIGTERM, which
|
Socket = {
|
||||||
# is the default "KillSignal" value systemd uses to stop services.
|
ListenStream = socketPath;
|
||||||
SuccessExitStatus = 15;
|
FileDescriptorName = "server";
|
||||||
|
SocketMode = "0600";
|
||||||
|
DirectoryMode = "0700";
|
||||||
|
# This prevents the service from immediately starting again
|
||||||
|
# after being stopped, due to the function
|
||||||
|
# `server-force-stop' present in `kill-emacs-hook', which
|
||||||
|
# calls `server-running-p', which opens the socket file.
|
||||||
|
FlushPending = true;
|
||||||
|
};
|
||||||
|
|
||||||
Restart = "on-failure";
|
Install = {
|
||||||
}
|
WantedBy = [ "sockets.target" ];
|
||||||
// optionalAttrs needsSocketWorkaround {
|
# Adding this Requires= dependency ensures that systemd
|
||||||
# Use read-only directory permissions to prevent emacs from
|
# manages the socket file, in the case where the service is
|
||||||
# deleting systemd's socket file before exiting.
|
# started when the socket is stopped.
|
||||||
ExecStartPost = "${pkgs.coreutils}/bin/chmod --changes -w ${socketDir}";
|
# The socket unit is implicitly ordered before the service.
|
||||||
ExecStopPost = "${pkgs.coreutils}/bin/chmod --changes +w ${socketDir}";
|
RequiredBy = [ "emacs.service" ];
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
// optionalAttrs (cfg.startWithUserSession != false) {
|
|
||||||
Install = {
|
launchd.agents.emacs = {
|
||||||
WantedBy = [
|
enable = true;
|
||||||
(if cfg.startWithUserSession == true then "default.target" else "graphical-session.target")
|
config = {
|
||||||
];
|
ProgramArguments = [
|
||||||
};
|
"${cfg.package}/bin/emacs"
|
||||||
|
"--fg-daemon"
|
||||||
|
]
|
||||||
|
++ cfg.extraOptions;
|
||||||
|
RunAtLoad = true;
|
||||||
|
KeepAlive = {
|
||||||
|
Crashed = true;
|
||||||
|
SuccessfulExit = false;
|
||||||
};
|
};
|
||||||
|
};
|
||||||
home.packages = optional cfg.client.enable (lib.hiPrio clientDesktopItem);
|
};
|
||||||
})
|
};
|
||||||
|
|
||||||
(mkIf (cfg.socketActivation.enable && pkgs.stdenv.isLinux) {
|
|
||||||
systemd.user.sockets.emacs = {
|
|
||||||
Unit = {
|
|
||||||
Description = "Emacs text editor";
|
|
||||||
Documentation = "info:emacs man:emacs(1) https://gnu.org/software/emacs/";
|
|
||||||
};
|
|
||||||
|
|
||||||
Socket = {
|
|
||||||
ListenStream = socketPath;
|
|
||||||
FileDescriptorName = "server";
|
|
||||||
SocketMode = "0600";
|
|
||||||
DirectoryMode = "0700";
|
|
||||||
# This prevents the service from immediately starting again
|
|
||||||
# after being stopped, due to the function
|
|
||||||
# `server-force-stop' present in `kill-emacs-hook', which
|
|
||||||
# calls `server-running-p', which opens the socket file.
|
|
||||||
FlushPending = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
Install = {
|
|
||||||
WantedBy = [ "sockets.target" ];
|
|
||||||
# Adding this Requires= dependency ensures that systemd
|
|
||||||
# manages the socket file, in the case where the service is
|
|
||||||
# started when the socket is stopped.
|
|
||||||
# The socket unit is implicitly ordered before the service.
|
|
||||||
RequiredBy = [ "emacs.service" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
|
|
||||||
(mkIf pkgs.stdenv.isDarwin {
|
|
||||||
launchd.agents.emacs = {
|
|
||||||
enable = true;
|
|
||||||
config = {
|
|
||||||
ProgramArguments = [
|
|
||||||
"${cfg.package}/bin/emacs"
|
|
||||||
"--fg-daemon"
|
|
||||||
]
|
|
||||||
++ cfg.extraOptions;
|
|
||||||
RunAtLoad = true;
|
|
||||||
KeepAlive = {
|
|
||||||
Crashed = true;
|
|
||||||
SuccessfulExit = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,49 +15,12 @@ let
|
|||||||
|
|
||||||
cfg = config.services.git-sync;
|
cfg = config.services.git-sync;
|
||||||
|
|
||||||
mkUnit = name: repo: {
|
services =
|
||||||
Unit.Description = "Git Sync ${name}";
|
mkService:
|
||||||
|
lib.mapAttrs' (name: repo: {
|
||||||
Install.WantedBy = [ "default.target" ];
|
name = "git-sync-${name}";
|
||||||
|
value = mkService name repo;
|
||||||
Service = {
|
}) cfg.repositories;
|
||||||
Environment = [
|
|
||||||
"PATH=${
|
|
||||||
lib.makeBinPath (
|
|
||||||
with pkgs;
|
|
||||||
[
|
|
||||||
openssh
|
|
||||||
git
|
|
||||||
]
|
|
||||||
++ repo.extraPackages
|
|
||||||
)
|
|
||||||
}"
|
|
||||||
"GIT_SYNC_DIRECTORY=${lib.strings.escapeShellArg repo.path}"
|
|
||||||
"GIT_SYNC_COMMAND=${cfg.package}/bin/git-sync"
|
|
||||||
"GIT_SYNC_REPOSITORY=${lib.strings.escapeShellArg repo.uri}"
|
|
||||||
"GIT_SYNC_INTERVAL=${toString repo.interval}"
|
|
||||||
];
|
|
||||||
ExecStart = "${cfg.package}/bin/git-sync-on-inotify";
|
|
||||||
Restart = "on-abort";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
mkAgent = name: repo: {
|
|
||||||
enable = true;
|
|
||||||
config = {
|
|
||||||
StartInterval = repo.interval;
|
|
||||||
ProcessType = "Background";
|
|
||||||
WorkingDirectory = "${repo.path}";
|
|
||||||
WatchPaths = [ "${repo.path}" ];
|
|
||||||
ProgramArguments = [ "${cfg.package}/bin/git-sync" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
mkService = if pkgs.stdenv.isLinux then mkUnit else mkAgent;
|
|
||||||
services = lib.mapAttrs' (name: repo: {
|
|
||||||
name = "git-sync-${name}";
|
|
||||||
value = mkService name repo;
|
|
||||||
}) cfg.repositories;
|
|
||||||
|
|
||||||
repositoryType = types.submodule (
|
repositoryType = types.submodule (
|
||||||
{ name, ... }:
|
{ name, ... }:
|
||||||
@@ -141,11 +104,48 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable (
|
config = mkIf cfg.enable {
|
||||||
lib.mkMerge [
|
launchd.agents = services (
|
||||||
(mkIf pkgs.stdenv.isLinux { systemd.user.services = services; })
|
name: repo: {
|
||||||
(mkIf pkgs.stdenv.isDarwin { launchd.agents = services; })
|
enable = true;
|
||||||
]
|
config = {
|
||||||
);
|
StartInterval = repo.interval;
|
||||||
|
ProcessType = "Background";
|
||||||
|
WorkingDirectory = "${repo.path}";
|
||||||
|
WatchPaths = [ "${repo.path}" ];
|
||||||
|
ProgramArguments = [ "${cfg.package}/bin/git-sync" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
systemd.user.services = services (
|
||||||
|
name: repo: {
|
||||||
|
Unit.Description = "Git Sync ${name}";
|
||||||
|
|
||||||
|
Install.WantedBy = [ "default.target" ];
|
||||||
|
|
||||||
|
Service = {
|
||||||
|
Environment = [
|
||||||
|
"PATH=${
|
||||||
|
lib.makeBinPath (
|
||||||
|
with pkgs;
|
||||||
|
[
|
||||||
|
openssh
|
||||||
|
git
|
||||||
|
]
|
||||||
|
++ repo.extraPackages
|
||||||
|
)
|
||||||
|
}"
|
||||||
|
"GIT_SYNC_DIRECTORY=${lib.strings.escapeShellArg repo.path}"
|
||||||
|
"GIT_SYNC_COMMAND=${cfg.package}/bin/git-sync"
|
||||||
|
"GIT_SYNC_REPOSITORY=${lib.strings.escapeShellArg repo.uri}"
|
||||||
|
"GIT_SYNC_INTERVAL=${toString repo.interval}"
|
||||||
|
];
|
||||||
|
ExecStart = "${cfg.package}/bin/git-sync-on-inotify";
|
||||||
|
Restart = "on-abort";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -344,125 +344,115 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable (
|
config = mkIf cfg.enable {
|
||||||
lib.mkMerge [
|
# Grab the default binary name and fallback to expected value if `meta.mainProgram` not set
|
||||||
{
|
services.gpg-agent.pinentry.program = lib.mkOptionDefault (
|
||||||
# Grab the default binary name and fallback to expected value if `meta.mainProgram` not set
|
cfg.pinentry.package.meta.mainProgram or "pinentry"
|
||||||
services.gpg-agent.pinentry.program = lib.mkOptionDefault (
|
);
|
||||||
cfg.pinentry.package.meta.mainProgram or "pinentry"
|
|
||||||
);
|
|
||||||
|
|
||||||
home.file."${homedir}/gpg-agent.conf".text = lib.concatStringsSep "\n" (
|
home.file."${homedir}/gpg-agent.conf".text = lib.concatStringsSep "\n" (
|
||||||
optional cfg.enableSshSupport "enable-ssh-support"
|
optional cfg.enableSshSupport "enable-ssh-support"
|
||||||
++ optional cfg.grabKeyboardAndMouse "grab"
|
++ optional cfg.grabKeyboardAndMouse "grab"
|
||||||
++ optional (!cfg.enableScDaemon) "disable-scdaemon"
|
++ optional (!cfg.enableScDaemon) "disable-scdaemon"
|
||||||
++ optional cfg.noAllowExternalCache "no-allow-external-cache"
|
++ optional cfg.noAllowExternalCache "no-allow-external-cache"
|
||||||
++ optional (cfg.defaultCacheTtl != null) "default-cache-ttl ${toString cfg.defaultCacheTtl}"
|
++ optional (cfg.defaultCacheTtl != null) "default-cache-ttl ${toString cfg.defaultCacheTtl}"
|
||||||
++ optional (
|
++ optional (
|
||||||
cfg.defaultCacheTtlSsh != null
|
cfg.defaultCacheTtlSsh != null
|
||||||
) "default-cache-ttl-ssh ${toString cfg.defaultCacheTtlSsh}"
|
) "default-cache-ttl-ssh ${toString cfg.defaultCacheTtlSsh}"
|
||||||
++ optional (cfg.maxCacheTtl != null) "max-cache-ttl ${toString cfg.maxCacheTtl}"
|
++ optional (cfg.maxCacheTtl != null) "max-cache-ttl ${toString cfg.maxCacheTtl}"
|
||||||
++ optional (cfg.maxCacheTtlSsh != null) "max-cache-ttl-ssh ${toString cfg.maxCacheTtlSsh}"
|
++ optional (cfg.maxCacheTtlSsh != null) "max-cache-ttl-ssh ${toString cfg.maxCacheTtlSsh}"
|
||||||
++ optional (
|
++ optional (
|
||||||
cfg.pinentry.package != null
|
cfg.pinentry.package != null
|
||||||
) "pinentry-program ${lib.getExe' cfg.pinentry.package cfg.pinentry.program}"
|
) "pinentry-program ${lib.getExe' cfg.pinentry.package cfg.pinentry.program}"
|
||||||
++ [ cfg.extraConfig ]
|
++ [ cfg.extraConfig ]
|
||||||
);
|
);
|
||||||
|
|
||||||
home.sessionVariablesExtra = optionalString cfg.enableSshSupport ''
|
home.sessionVariablesExtra = optionalString cfg.enableSshSupport ''
|
||||||
unset SSH_AGENT_PID
|
unset SSH_AGENT_PID
|
||||||
if [ -z "$SSH_CONNECTION" -o -z "$SSH_AUTH_SOCK" ] && [ "''${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
|
if [ -z "$SSH_CONNECTION" -o -z "$SSH_AUTH_SOCK" ] && [ "''${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
|
||||||
export SSH_AUTH_SOCK="$(${gpgPkg}/bin/gpgconf --list-dirs agent-ssh-socket)"
|
export SSH_AUTH_SOCK="$(${gpgPkg}/bin/gpgconf --list-dirs agent-ssh-socket)"
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
programs = {
|
programs = {
|
||||||
bash.initExtra = mkIf cfg.enableBashIntegration gpgBashInitStr;
|
bash.initExtra = mkIf cfg.enableBashIntegration gpgBashInitStr;
|
||||||
zsh.initContent = mkIf cfg.enableZshIntegration gpgZshInitStr;
|
zsh.initContent = mkIf cfg.enableZshIntegration gpgZshInitStr;
|
||||||
fish.interactiveShellInit = mkIf cfg.enableFishIntegration gpgFishInitStr;
|
fish.interactiveShellInit = mkIf cfg.enableFishIntegration gpgFishInitStr;
|
||||||
nushell.extraConfig = mkIf cfg.enableNushellIntegration gpgNushellInitStr;
|
nushell.extraConfig = mkIf cfg.enableNushellIntegration gpgNushellInitStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Trailing newlines are important
|
||||||
|
home.file."${homedir}/sshcontrol" = mkIf (cfg.sshKeys != null) {
|
||||||
|
text = lib.concatMapStrings (s: ''
|
||||||
|
${s}
|
||||||
|
'') cfg.sshKeys;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user = {
|
||||||
|
services.gpg-agent = {
|
||||||
|
Unit = {
|
||||||
|
Description = "GnuPG cryptographic agent and passphrase cache";
|
||||||
|
Documentation = "man:gpg-agent(1)";
|
||||||
|
Requires = "gpg-agent.socket";
|
||||||
|
After = "gpg-agent.socket";
|
||||||
|
# This is a socket-activated service:
|
||||||
|
RefuseManualStart = true;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
(mkIf (cfg.sshKeys != null) {
|
Service = {
|
||||||
# Trailing newlines are important
|
ExecStart = "${gpgPkg}/bin/gpg-agent --supervised" + optionalString cfg.verbose " --verbose";
|
||||||
home.file."${homedir}/sshcontrol".text = lib.concatMapStrings (s: ''
|
ExecReload = "${gpgPkg}/bin/gpgconf --reload gpg-agent";
|
||||||
${s}
|
Environment = [ "GNUPGHOME=${homedir}" ];
|
||||||
'') cfg.sshKeys;
|
};
|
||||||
})
|
};
|
||||||
|
|
||||||
(lib.mkMerge [
|
sockets = {
|
||||||
(mkIf pkgs.stdenv.isLinux {
|
gpg-agent = mkSocket {
|
||||||
systemd.user = {
|
desc = "GnuPG cryptographic agent and passphrase cache";
|
||||||
services.gpg-agent = {
|
docs = "man:gpg-agent(1)";
|
||||||
Unit = {
|
stream = "S.gpg-agent";
|
||||||
Description = "GnuPG cryptographic agent and passphrase cache";
|
fdName = "std";
|
||||||
Documentation = "man:gpg-agent(1)";
|
};
|
||||||
Requires = "gpg-agent.socket";
|
|
||||||
After = "gpg-agent.socket";
|
|
||||||
# This is a socket-activated service:
|
|
||||||
RefuseManualStart = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
Service = {
|
gpg-agent-ssh = mkIf cfg.enableSshSupport (mkSocket {
|
||||||
ExecStart = "${gpgPkg}/bin/gpg-agent --supervised" + optionalString cfg.verbose " --verbose";
|
desc = "GnuPG cryptographic agent (ssh-agent emulation)";
|
||||||
ExecReload = "${gpgPkg}/bin/gpgconf --reload gpg-agent";
|
docs = "man:gpg-agent(1) man:ssh-add(1) man:ssh-agent(1) man:ssh(1)";
|
||||||
Environment = [ "GNUPGHOME=${homedir}" ];
|
stream = "S.gpg-agent.ssh";
|
||||||
};
|
fdName = "ssh";
|
||||||
};
|
});
|
||||||
|
|
||||||
sockets = {
|
gpg-agent-extra = mkIf cfg.enableExtraSocket (mkSocket {
|
||||||
gpg-agent = mkSocket {
|
desc = "GnuPG cryptographic agent and passphrase cache (restricted)";
|
||||||
desc = "GnuPG cryptographic agent and passphrase cache";
|
docs = "man:gpg-agent(1) man:ssh(1)";
|
||||||
docs = "man:gpg-agent(1)";
|
stream = "S.gpg-agent.extra";
|
||||||
stream = "S.gpg-agent";
|
fdName = "extra";
|
||||||
fdName = "std";
|
});
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
gpg-agent-ssh = mkIf cfg.enableSshSupport (mkSocket {
|
launchd.agents.gpg-agent = {
|
||||||
desc = "GnuPG cryptographic agent (ssh-agent emulation)";
|
enable = true;
|
||||||
docs = "man:gpg-agent(1) man:ssh-add(1) man:ssh-agent(1) man:ssh(1)";
|
config = {
|
||||||
stream = "S.gpg-agent.ssh";
|
ProgramArguments = [
|
||||||
fdName = "ssh";
|
"${gpgPkg}/bin/gpg-agent"
|
||||||
});
|
"--supervised"
|
||||||
|
]
|
||||||
gpg-agent-extra = mkIf cfg.enableExtraSocket (mkSocket {
|
++ optional cfg.verbose "--verbose";
|
||||||
desc = "GnuPG cryptographic agent and passphrase cache (restricted)";
|
EnvironmentVariables = {
|
||||||
docs = "man:gpg-agent(1) man:ssh(1)";
|
GNUPGHOME = homedir;
|
||||||
stream = "S.gpg-agent.extra";
|
};
|
||||||
fdName = "extra";
|
KeepAlive = {
|
||||||
});
|
Crashed = true;
|
||||||
};
|
SuccessfulExit = false;
|
||||||
};
|
};
|
||||||
})
|
ProcessType = "Background";
|
||||||
|
RunAtLoad = cfg.enableSshSupport;
|
||||||
(mkIf pkgs.stdenv.isDarwin {
|
Sockets = {
|
||||||
launchd.agents.gpg-agent = {
|
Agent = mkAgentSock "S.gpg-agent";
|
||||||
enable = true;
|
Ssh = mkIf cfg.enableSshSupport (mkAgentSock "S.gpg-agent.ssh");
|
||||||
config = {
|
Extra = mkIf cfg.enableExtraSocket (mkAgentSock "S.gpg-agent.extra");
|
||||||
ProgramArguments = [
|
};
|
||||||
"${gpgPkg}/bin/gpg-agent"
|
};
|
||||||
"--supervised"
|
};
|
||||||
]
|
};
|
||||||
++ optional cfg.verbose "--verbose";
|
|
||||||
EnvironmentVariables = {
|
|
||||||
GNUPGHOME = homedir;
|
|
||||||
};
|
|
||||||
KeepAlive = {
|
|
||||||
Crashed = true;
|
|
||||||
SuccessfulExit = false;
|
|
||||||
};
|
|
||||||
ProcessType = "Background";
|
|
||||||
RunAtLoad = cfg.enableSshSupport;
|
|
||||||
Sockets = {
|
|
||||||
Agent = mkAgentSock "S.gpg-agent";
|
|
||||||
Ssh = mkIf cfg.enableSshSupport (mkAgentSock "S.gpg-agent.ssh");
|
|
||||||
Extra = mkIf cfg.enableExtraSocket (mkAgentSock "S.gpg-agent.extra");
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
])
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,46 +81,38 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
config = lib.mkIf cfg.enable {
|
||||||
lib.mkMerge [
|
|
||||||
(lib.mkIf pkgs.stdenv.isLinux {
|
|
||||||
systemd.user = {
|
|
||||||
timers.home-manager-auto-expire = {
|
|
||||||
Unit.Description = "Home Manager expire generations timer";
|
|
||||||
|
|
||||||
Install.WantedBy = [ "timers.target" ];
|
systemd.user = {
|
||||||
|
timers.home-manager-auto-expire = {
|
||||||
Timer = {
|
Unit.Description = "Home Manager expire generations timer";
|
||||||
OnCalendar = cfg.frequency;
|
Install.WantedBy = [ "timers.target" ];
|
||||||
Unit = "home-manager-auto-expire.service";
|
Timer = {
|
||||||
Persistent = true;
|
OnCalendar = cfg.frequency;
|
||||||
};
|
Unit = "home-manager-auto-expire.service";
|
||||||
};
|
Persistent = true;
|
||||||
|
|
||||||
services.home-manager-auto-expire = {
|
|
||||||
Unit.Description = "Home Manager expire generations";
|
|
||||||
|
|
||||||
Service.ExecStart = toString script;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
})
|
};
|
||||||
|
services.home-manager-auto-expire = {
|
||||||
|
Unit.Description = "Home Manager expire generations";
|
||||||
|
Service.ExecStart = toString script;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
(lib.mkIf pkgs.stdenv.isDarwin {
|
assertions = [
|
||||||
assertions = [
|
(lib.hm.darwin.assertInterval "services.home-manager.autoExpire.frequency" cfg.frequency pkgs)
|
||||||
(lib.hm.darwin.assertInterval "services.home-manager.autoExpire.frequency" cfg.frequency pkgs)
|
];
|
||||||
];
|
|
||||||
|
|
||||||
launchd.agents.home-manager-auto-expire = {
|
launchd.agents.home-manager-auto-expire = {
|
||||||
enable = true;
|
enable = true;
|
||||||
config = {
|
config = {
|
||||||
ProgramArguments = [ (toString script) ];
|
ProgramArguments = [ (toString script) ];
|
||||||
ProcessType = "Background";
|
ProcessType = "Background";
|
||||||
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval cfg.frequency;
|
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval cfg.frequency;
|
||||||
StandardOutPath = "${config.home.homeDirectory}/Library/Logs/home-manager-auto-expire/launchd-stdout.log";
|
StandardOutPath = "${config.home.homeDirectory}/Library/Logs/home-manager-auto-expire/launchd-stdout.log";
|
||||||
StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/home-manager-auto-expire/launchd-stderr.log";
|
StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/home-manager-auto-expire/launchd-stderr.log";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
|
||||||
]
|
};
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ in
|
|||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
systemd.user = lib.mkIf pkgs.stdenv.hostPlatform.isLinux {
|
systemd.user = {
|
||||||
services.mpd = {
|
services.mpd = {
|
||||||
Unit = lib.mkMerge [
|
Unit = lib.mkMerge [
|
||||||
{
|
{
|
||||||
@@ -236,7 +236,7 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
launchd.agents.mpd = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin {
|
launchd.agents.mpd = {
|
||||||
enable = true;
|
enable = true;
|
||||||
config = {
|
config = {
|
||||||
ProgramArguments = [
|
ProgramArguments = [
|
||||||
|
|||||||
@@ -83,56 +83,51 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.automatic (
|
config = lib.mkIf cfg.automatic {
|
||||||
lib.mkMerge [
|
systemd.user.services.nix-gc = {
|
||||||
(lib.mkIf pkgs.stdenv.isLinux {
|
Unit = {
|
||||||
systemd.user.services.nix-gc = {
|
Description = "Nix Garbage Collector";
|
||||||
Unit = {
|
};
|
||||||
Description = "Nix Garbage Collector";
|
Service = {
|
||||||
};
|
Type = "oneshot";
|
||||||
Service = {
|
ExecStart = pkgs.writeShellScript "nix-gc" "exec ${nixPackage}/bin/nix-collect-garbage ${
|
||||||
Type = "oneshot";
|
lib.optionalString (cfg.options != null) cfg.options
|
||||||
ExecStart = pkgs.writeShellScript "nix-gc" "exec ${nixPackage}/bin/nix-collect-garbage ${
|
}";
|
||||||
lib.optionalString (cfg.options != null) cfg.options
|
};
|
||||||
}";
|
};
|
||||||
};
|
|
||||||
};
|
|
||||||
systemd.user.timers.nix-gc = {
|
|
||||||
Unit = {
|
|
||||||
Description = "Nix Garbage Collector";
|
|
||||||
};
|
|
||||||
Timer = {
|
|
||||||
OnCalendar = cfg.dates;
|
|
||||||
RandomizedDelaySec = cfg.randomizedDelaySec;
|
|
||||||
Persistent = cfg.persistent;
|
|
||||||
Unit = "nix-gc.service";
|
|
||||||
};
|
|
||||||
Install = {
|
|
||||||
WantedBy = [ "timers.target" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
|
|
||||||
(lib.mkIf pkgs.stdenv.isDarwin {
|
systemd.user.timers.nix-gc = {
|
||||||
assertions = [
|
Unit = {
|
||||||
{
|
Description = "Nix Garbage Collector";
|
||||||
assertion = (lib.length cfg.dates) == 1;
|
};
|
||||||
message = "On Darwin, `nix.gc.dates` must contain a single element.";
|
Timer = {
|
||||||
}
|
OnCalendar = cfg.dates;
|
||||||
(lib.hm.darwin.assertInterval "nix.gc.dates.*" (lib.elemAt cfg.dates 0) pkgs)
|
RandomizedDelaySec = cfg.randomizedDelaySec;
|
||||||
];
|
Persistent = cfg.persistent;
|
||||||
|
Unit = "nix-gc.service";
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "timers.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
launchd.agents.nix-gc = {
|
assertions = [
|
||||||
enable = true;
|
{
|
||||||
config = {
|
assertion = pkgs.stdenv.isDarwin -> (lib.length cfg.dates == 1);
|
||||||
ProgramArguments = [
|
message = "On Darwin, `nix.gc.dates` must contain a single element.";
|
||||||
"${nixPackage}/bin/nix-collect-garbage"
|
}
|
||||||
]
|
(lib.hm.darwin.assertInterval "nix.gc.dates.*" (lib.elemAt cfg.dates 0) pkgs)
|
||||||
++ lib.optional (cfg.options != null) cfg.options;
|
];
|
||||||
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval (lib.elemAt cfg.dates 0);
|
|
||||||
};
|
launchd.agents.nix-gc = {
|
||||||
};
|
enable = true;
|
||||||
})
|
config = {
|
||||||
]
|
ProgramArguments = [
|
||||||
);
|
"${nixPackage}/bin/nix-collect-garbage"
|
||||||
|
]
|
||||||
|
++ lib.optional (cfg.options != null) cfg.options;
|
||||||
|
StartCalendarInterval = lib.hm.darwin.mkCalendarInterval (lib.elemAt cfg.dates 0);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
systemd.user.services.ollama = mkIf pkgs.stdenv.isLinux {
|
systemd.user.services.ollama = {
|
||||||
Unit = {
|
Unit = {
|
||||||
Description = "Server for local large language models";
|
Description = "Server for local large language models";
|
||||||
After = [ "network.target" ];
|
After = [ "network.target" ];
|
||||||
@@ -105,7 +105,7 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
launchd.agents.ollama = mkIf pkgs.stdenv.isDarwin {
|
launchd.agents.ollama = {
|
||||||
enable = true;
|
enable = true;
|
||||||
config = {
|
config = {
|
||||||
ProgramArguments = [
|
ProgramArguments = [
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ let
|
|||||||
pueuedBin = "${cfg.package}/bin/pueued";
|
pueuedBin = "${cfg.package}/bin/pueued";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
meta.maintainers = [ lib.maintainers.AndersonTorres ];
|
meta.maintainers = [ ];
|
||||||
|
|
||||||
options.services.pueue = {
|
options.services.pueue = {
|
||||||
enable = lib.mkEnableOption "Pueue, CLI process scheduler and manager";
|
enable = lib.mkEnableOption "Pueue, CLI process scheduler and manager";
|
||||||
@@ -35,51 +35,49 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
config = lib.mkIf cfg.enable {
|
||||||
lib.mkMerge [
|
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||||
{
|
|
||||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
|
||||||
}
|
|
||||||
(lib.mkIf pkgs.stdenv.isLinux {
|
|
||||||
xdg.configFile."pueue/pueue.yml".source = configFile;
|
|
||||||
systemd.user = lib.mkIf (cfg.package != null) {
|
|
||||||
services.pueued = {
|
|
||||||
Unit = {
|
|
||||||
Description = "Pueue Daemon - CLI process scheduler and manager";
|
|
||||||
};
|
|
||||||
|
|
||||||
Service = {
|
xdg.configFile."pueue/pueue.yml" = lib.mkIf pkgs.stdenv.isLinux { source = configFile; };
|
||||||
Restart = "on-failure";
|
|
||||||
ExecStart = "${pueuedBin} -v -c ${configFile}";
|
|
||||||
};
|
|
||||||
|
|
||||||
Install.WantedBy = [ "default.target" ];
|
systemd.user = lib.mkIf (cfg.package != null) {
|
||||||
};
|
services.pueued = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Pueue Daemon - CLI process scheduler and manager";
|
||||||
};
|
};
|
||||||
})
|
|
||||||
(lib.mkIf pkgs.stdenv.isDarwin {
|
|
||||||
# This is the default configuration file location for pueue on
|
|
||||||
# darwin (https://github.com/Nukesor/pueue/wiki/Configuration)
|
|
||||||
home.file."Library/Application Support/pueue/pueue.yml".source = configFile;
|
|
||||||
launchd.agents.pueued = lib.mkIf (cfg.package != null) {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
config = {
|
Service = {
|
||||||
ProgramArguments = [
|
Restart = "on-failure";
|
||||||
pueuedBin
|
ExecStart = "${pueuedBin} -v -c ${configFile}";
|
||||||
"-v"
|
|
||||||
"-c"
|
|
||||||
"${configFile}"
|
|
||||||
];
|
|
||||||
KeepAlive = {
|
|
||||||
Crashed = true;
|
|
||||||
SuccessfulExit = false;
|
|
||||||
};
|
|
||||||
ProcessType = "Background";
|
|
||||||
RunAtLoad = true;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
})
|
|
||||||
]
|
Install.WantedBy = [ "default.target" ];
|
||||||
);
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# This is the default configuration file location for pueue on
|
||||||
|
# darwin (https://github.com/Nukesor/pueue/wiki/Configuration)
|
||||||
|
home.file."Library/Application Support/pueue/pueue.yml" = lib.mkIf pkgs.stdenv.isDarwin {
|
||||||
|
source = configFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
launchd.agents.pueued = lib.mkIf (cfg.package != null) {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
config = {
|
||||||
|
ProgramArguments = [
|
||||||
|
pueuedBin
|
||||||
|
"-v"
|
||||||
|
"-c"
|
||||||
|
"${configFile}"
|
||||||
|
];
|
||||||
|
KeepAlive = {
|
||||||
|
Crashed = true;
|
||||||
|
SuccessfulExit = false;
|
||||||
|
};
|
||||||
|
ProcessType = "Background";
|
||||||
|
RunAtLoad = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,15 +62,13 @@ let
|
|||||||
))
|
))
|
||||||
];
|
];
|
||||||
|
|
||||||
inherit (pkgs.stdenv.hostPlatform) isLinux;
|
|
||||||
|
|
||||||
# Until we have launchd support (#7924), mark the options
|
# Until we have launchd support (#7924), mark the options
|
||||||
# not used in the helper script as "linux exclusive"
|
# not used in the helper script as "linux exclusive"
|
||||||
linuxExclusive =
|
linuxExclusive =
|
||||||
option:
|
option:
|
||||||
option
|
option
|
||||||
// {
|
// {
|
||||||
readOnly = pkgs.stdenv.hostPlatform.isDarwin;
|
readOnly = !pkgs.stdenv.hostPlatform.isLinux;
|
||||||
|
|
||||||
description = option.description + ''
|
description = option.description + ''
|
||||||
|
|
||||||
@@ -393,219 +391,209 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
config = lib.mkIf cfg.enable {
|
||||||
lib.mkMerge [
|
assertions = lib.mapAttrsToList (n: v: {
|
||||||
{
|
assertion = lib.xor (v.repository == null) (v.repositoryFile == null);
|
||||||
assertions = lib.mapAttrsToList (n: v: {
|
message = "services.restic.backups.${n}: exactly one of repository or repositoryFile should be set";
|
||||||
assertion = lib.xor (v.repository == null) (v.repositoryFile == null);
|
}) cfg.backups;
|
||||||
message = "services.restic.backups.${n}: exactly one of repository or repositoryFile should be set";
|
|
||||||
}) cfg.backups;
|
|
||||||
}
|
|
||||||
|
|
||||||
(lib.mkIf isLinux {
|
systemd.user.services = lib.mapAttrs' (
|
||||||
systemd.user.services = lib.mapAttrs' (
|
name: backup:
|
||||||
name: backup:
|
let
|
||||||
let
|
doBackup = backup.dynamicFilesFrom != null || backup.paths != [ ];
|
||||||
doBackup = backup.dynamicFilesFrom != null || backup.paths != [ ];
|
doPrune = backup.pruneOpts != [ ];
|
||||||
doPrune = backup.pruneOpts != [ ];
|
doCheck = backup.runCheck;
|
||||||
doCheck = backup.runCheck;
|
serviceName = "restic-backups-${name}";
|
||||||
serviceName = "restic-backups-${name}";
|
|
||||||
|
|
||||||
extraOptions = lib.concatMap (arg: [
|
extraOptions = lib.concatMap (arg: [
|
||||||
"-o"
|
"-o"
|
||||||
arg
|
arg
|
||||||
]) backup.extraOptions;
|
]) backup.extraOptions;
|
||||||
|
|
||||||
excludeFile = pkgs.writeText "exclude-patterns" (lib.concatLines backup.exclude);
|
excludeFile = pkgs.writeText "exclude-patterns" (lib.concatLines backup.exclude);
|
||||||
excludeFileFlag = "--exclude-file=${excludeFile}";
|
excludeFileFlag = "--exclude-file=${excludeFile}";
|
||||||
|
|
||||||
filesFromTmpFile = "/run/user/$UID/${serviceName}/includes";
|
filesFromTmpFile = "/run/user/$UID/${serviceName}/includes";
|
||||||
filesFromFlag = "--files-from=${filesFromTmpFile}";
|
filesFromFlag = "--files-from=${filesFromTmpFile}";
|
||||||
|
|
||||||
inhibitCmd = lib.optionals backup.inhibitsSleep [
|
inhibitCmd = lib.optionals backup.inhibitsSleep [
|
||||||
"${pkgs.systemd}/bin/systemd-inhibit"
|
"${pkgs.systemd}/bin/systemd-inhibit"
|
||||||
"--mode='block'"
|
"--mode='block'"
|
||||||
"--who='restic'"
|
"--who='restic'"
|
||||||
"--what='idle'"
|
"--what='idle'"
|
||||||
"--why=${lib.escapeShellArg "Scheduled backup ${name}"}"
|
"--why=${lib.escapeShellArg "Scheduled backup ${name}"}"
|
||||||
];
|
];
|
||||||
|
|
||||||
mkResticCmd' =
|
mkResticCmd' =
|
||||||
pre: args:
|
pre: args:
|
||||||
lib.concatStringsSep " " (
|
lib.concatStringsSep " " (
|
||||||
pre ++ lib.singleton (lib.getExe backup.package) ++ extraOptions ++ lib.flatten args
|
pre ++ lib.singleton (lib.getExe backup.package) ++ extraOptions ++ lib.flatten args
|
||||||
);
|
);
|
||||||
mkResticCmd = mkResticCmd' [ ];
|
mkResticCmd = mkResticCmd' [ ];
|
||||||
|
|
||||||
backupCmd =
|
backupCmd =
|
||||||
"${lib.getExe pkgs.bash} -c "
|
"${lib.getExe pkgs.bash} -c "
|
||||||
+ lib.escapeShellArg (
|
+ lib.escapeShellArg (
|
||||||
mkResticCmd' inhibitCmd [
|
mkResticCmd' inhibitCmd [
|
||||||
"backup"
|
"backup"
|
||||||
backup.extraBackupArgs
|
backup.extraBackupArgs
|
||||||
excludeFileFlag
|
excludeFileFlag
|
||||||
filesFromFlag
|
filesFromFlag
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
forgetCmd = mkResticCmd [
|
forgetCmd = mkResticCmd [
|
||||||
"forget"
|
"forget"
|
||||||
"--prune"
|
"--prune"
|
||||||
backup.pruneOpts
|
backup.pruneOpts
|
||||||
];
|
];
|
||||||
checkCmd = mkResticCmd [
|
checkCmd = mkResticCmd [
|
||||||
"check"
|
"check"
|
||||||
backup.checkOpts
|
backup.checkOpts
|
||||||
];
|
];
|
||||||
unlockCmd = mkResticCmd "unlock";
|
unlockCmd = mkResticCmd "unlock";
|
||||||
in
|
in
|
||||||
lib.nameValuePair serviceName {
|
lib.nameValuePair serviceName {
|
||||||
Unit = {
|
Unit = {
|
||||||
Description = "Restic backup service";
|
Description = "Restic backup service";
|
||||||
Wants = [ "network-online.target" ];
|
Wants = [ "network-online.target" ];
|
||||||
After = [ "network-online.target" ];
|
After = [ "network-online.target" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
Service = {
|
Service = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
|
|
||||||
X-RestartIfChanged = true;
|
X-RestartIfChanged = true;
|
||||||
RuntimeDirectory = serviceName;
|
RuntimeDirectory = serviceName;
|
||||||
CacheDirectory = serviceName;
|
CacheDirectory = serviceName;
|
||||||
CacheDirectoryMode = "0700";
|
CacheDirectoryMode = "0700";
|
||||||
PrivateTmp = true;
|
PrivateTmp = true;
|
||||||
|
|
||||||
Environment = mkEnvironment backup ++ [ "RESTIC_CACHE_DIR=%C/${serviceName}" ];
|
Environment = mkEnvironment backup ++ [ "RESTIC_CACHE_DIR=%C/${serviceName}" ];
|
||||||
|
|
||||||
ExecStart =
|
ExecStart =
|
||||||
lib.optional doBackup backupCmd
|
lib.optional doBackup backupCmd
|
||||||
++ lib.optionals doPrune [
|
++ lib.optionals doPrune [
|
||||||
unlockCmd
|
unlockCmd
|
||||||
forgetCmd
|
forgetCmd
|
||||||
]
|
]
|
||||||
++ lib.optional doCheck checkCmd;
|
++ lib.optional doCheck checkCmd;
|
||||||
|
|
||||||
ExecStartPre = lib.getExe (
|
ExecStartPre = lib.getExe (
|
||||||
pkgs.writeShellApplication {
|
pkgs.writeShellApplication {
|
||||||
name = "${serviceName}-exec-start-pre";
|
name = "${serviceName}-exec-start-pre";
|
||||||
inherit runtimeInputs;
|
inherit runtimeInputs;
|
||||||
text = ''
|
text = ''
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
${lib.optionalString (backup.backupPrepareCommand != null) ''
|
${lib.optionalString (backup.backupPrepareCommand != null) ''
|
||||||
${pkgs.writeShellScript "backupPrepareCommand" backup.backupPrepareCommand}
|
${pkgs.writeShellScript "backupPrepareCommand" backup.backupPrepareCommand}
|
||||||
''}
|
''}
|
||||||
|
|
||||||
${lib.optionalString (backup.initialize) ''
|
${lib.optionalString (backup.initialize) ''
|
||||||
${
|
${
|
||||||
mkResticCmd [
|
mkResticCmd [
|
||||||
"cat"
|
"cat"
|
||||||
"config"
|
"config"
|
||||||
]
|
]
|
||||||
} 2>/dev/null || ${mkResticCmd "init"}
|
} 2>/dev/null || ${mkResticCmd "init"}
|
||||||
''}
|
''}
|
||||||
|
|
||||||
${lib.optionalString (backup.paths != null && backup.paths != [ ]) ''
|
${lib.optionalString (backup.paths != null && backup.paths != [ ]) ''
|
||||||
cat ${pkgs.writeText "staticPaths" (lib.concatLines backup.paths)} >> ${filesFromTmpFile}
|
cat ${pkgs.writeText "staticPaths" (lib.concatLines backup.paths)} >> ${filesFromTmpFile}
|
||||||
''}
|
''}
|
||||||
|
|
||||||
${lib.optionalString (backup.dynamicFilesFrom != null) ''
|
${lib.optionalString (backup.dynamicFilesFrom != null) ''
|
||||||
${pkgs.writeShellScript "dynamicFilesFromScript" backup.dynamicFilesFrom} >> ${filesFromTmpFile}
|
${pkgs.writeShellScript "dynamicFilesFromScript" backup.dynamicFilesFrom} >> ${filesFromTmpFile}
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
ExecStopPost = lib.getExe (
|
|
||||||
pkgs.writeShellApplication {
|
|
||||||
name = "${serviceName}-exec-stop-post";
|
|
||||||
inherit runtimeInputs;
|
|
||||||
text = ''
|
|
||||||
set -x
|
|
||||||
|
|
||||||
${lib.optionalString (backup.backupCleanupCommand != null) ''
|
|
||||||
${pkgs.writeShellScript "backupCleanupCommand" backup.backupCleanupCommand}
|
|
||||||
''}
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// lib.optionalAttrs (backup.environmentFile != null) {
|
);
|
||||||
EnvironmentFile = backup.environmentFile;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
) cfg.backups;
|
|
||||||
})
|
|
||||||
|
|
||||||
(lib.mkIf isLinux {
|
ExecStopPost = lib.getExe (
|
||||||
systemd.user.timers = lib.mapAttrs' (
|
pkgs.writeShellApplication {
|
||||||
name: backup:
|
name = "${serviceName}-exec-stop-post";
|
||||||
lib.nameValuePair "restic-backups-${name}" {
|
inherit runtimeInputs;
|
||||||
Unit.Description = "Restic backup service";
|
text = ''
|
||||||
Install.WantedBy = [ "timers.target" ];
|
set -x
|
||||||
|
|
||||||
Timer = backup.timerConfig;
|
${lib.optionalString (backup.backupCleanupCommand != null) ''
|
||||||
}
|
${pkgs.writeShellScript "backupCleanupCommand" backup.backupCleanupCommand}
|
||||||
) (lib.filterAttrs (_: v: v.timerConfig != null) cfg.backups);
|
''}
|
||||||
})
|
'';
|
||||||
|
}
|
||||||
{
|
);
|
||||||
home.packages = lib.mapAttrsToList (
|
}
|
||||||
name: backup:
|
// lib.optionalAttrs (backup.environmentFile != null) {
|
||||||
let
|
EnvironmentFile = backup.environmentFile;
|
||||||
serviceName = "restic-backups-${name}";
|
};
|
||||||
environment = mkEnvironment backup;
|
|
||||||
notPathVar = x: !(lib.hasPrefix "PATH" x);
|
|
||||||
extraOptions = lib.concatMap (arg: [
|
|
||||||
"-o"
|
|
||||||
arg
|
|
||||||
]) backup.extraOptions;
|
|
||||||
restic = lib.concatStringsSep " " (
|
|
||||||
lib.flatten [
|
|
||||||
(lib.getExe backup.package)
|
|
||||||
extraOptions
|
|
||||||
]
|
|
||||||
);
|
|
||||||
in
|
|
||||||
pkgs.writeShellApplication {
|
|
||||||
name = "restic-${name}";
|
|
||||||
excludeShellChecks = [
|
|
||||||
# https://github.com/koalaman/shellcheck/issues/1986
|
|
||||||
"SC2034"
|
|
||||||
# Allow sourcing environmentFile
|
|
||||||
"SC1091"
|
|
||||||
];
|
|
||||||
bashOptions = [
|
|
||||||
"errexit"
|
|
||||||
"nounset"
|
|
||||||
"allexport"
|
|
||||||
];
|
|
||||||
text = ''
|
|
||||||
${lib.optionalString (backup.environmentFile != null) ''
|
|
||||||
source ${backup.environmentFile}
|
|
||||||
''}
|
|
||||||
|
|
||||||
# Set same environment variables as the systemd service
|
|
||||||
${lib.pipe environment [
|
|
||||||
(lib.filter notPathVar)
|
|
||||||
lib.concatLines
|
|
||||||
]}
|
|
||||||
|
|
||||||
RESTIC_CACHE_DIR=${config.xdg.cacheHome}/${serviceName}
|
|
||||||
|
|
||||||
PATH=${
|
|
||||||
lib.pipe environment [
|
|
||||||
(lib.filter (lib.hasPrefix "PATH="))
|
|
||||||
lib.head
|
|
||||||
(lib.removePrefix "PATH=")
|
|
||||||
]
|
|
||||||
}:$PATH
|
|
||||||
|
|
||||||
exec ${restic} "$@"
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
) (lib.filterAttrs (_: v: v.createWrapper) cfg.backups);
|
|
||||||
}
|
}
|
||||||
]
|
) cfg.backups;
|
||||||
);
|
|
||||||
|
systemd.user.timers = lib.mapAttrs' (
|
||||||
|
name: backup:
|
||||||
|
lib.nameValuePair "restic-backups-${name}" {
|
||||||
|
Unit.Description = "Restic backup service";
|
||||||
|
Install.WantedBy = [ "timers.target" ];
|
||||||
|
|
||||||
|
Timer = backup.timerConfig;
|
||||||
|
}
|
||||||
|
) (lib.filterAttrs (_: v: v.timerConfig != null) cfg.backups);
|
||||||
|
|
||||||
|
home.packages = lib.mapAttrsToList (
|
||||||
|
name: backup:
|
||||||
|
let
|
||||||
|
serviceName = "restic-backups-${name}";
|
||||||
|
environment = mkEnvironment backup;
|
||||||
|
notPathVar = x: !(lib.hasPrefix "PATH" x);
|
||||||
|
extraOptions = lib.concatMap (arg: [
|
||||||
|
"-o"
|
||||||
|
arg
|
||||||
|
]) backup.extraOptions;
|
||||||
|
restic = lib.concatStringsSep " " (
|
||||||
|
lib.flatten [
|
||||||
|
(lib.getExe backup.package)
|
||||||
|
extraOptions
|
||||||
|
]
|
||||||
|
);
|
||||||
|
in
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
name = "restic-${name}";
|
||||||
|
excludeShellChecks = [
|
||||||
|
# https://github.com/koalaman/shellcheck/issues/1986
|
||||||
|
"SC2034"
|
||||||
|
# Allow sourcing environmentFile
|
||||||
|
"SC1091"
|
||||||
|
];
|
||||||
|
bashOptions = [
|
||||||
|
"errexit"
|
||||||
|
"nounset"
|
||||||
|
"allexport"
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
${lib.optionalString (backup.environmentFile != null) ''
|
||||||
|
source ${backup.environmentFile}
|
||||||
|
''}
|
||||||
|
|
||||||
|
# Set same environment variables as the systemd service
|
||||||
|
${lib.pipe environment [
|
||||||
|
(lib.filter notPathVar)
|
||||||
|
lib.concatLines
|
||||||
|
]}
|
||||||
|
|
||||||
|
RESTIC_CACHE_DIR=${config.xdg.cacheHome}/${serviceName}
|
||||||
|
|
||||||
|
PATH=${
|
||||||
|
lib.pipe environment [
|
||||||
|
(lib.filter (lib.hasPrefix "PATH="))
|
||||||
|
lib.head
|
||||||
|
(lib.removePrefix "PATH=")
|
||||||
|
]
|
||||||
|
}:$PATH
|
||||||
|
|
||||||
|
exec ${restic} "$@"
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
) (lib.filterAttrs (_: v: v.createWrapper) cfg.backups);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,91 +46,85 @@ in
|
|||||||
enableNushellIntegration = lib.hm.shell.mkNushellIntegrationOption { inherit config; };
|
enableNushellIntegration = lib.hm.shell.mkNushellIntegrationOption { inherit config; };
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
config = lib.mkIf cfg.enable {
|
||||||
lib.mkMerge [
|
|
||||||
{
|
programs =
|
||||||
programs =
|
let
|
||||||
|
socketPath =
|
||||||
|
if pkgs.stdenv.isDarwin then
|
||||||
|
"$(${lib.getExe pkgs.getconf} DARWIN_USER_TEMP_DIR)/${cfg.socket}"
|
||||||
|
else
|
||||||
|
"$XDG_RUNTIME_DIR/${cfg.socket}";
|
||||||
|
|
||||||
|
# Preserve $SSH_AUTH_SOCK only if it stems from a forwarded agent which
|
||||||
|
# is the case if both $SSH_AUTH_SOCK and $SSH_CONNECTION are set.
|
||||||
|
bashIntegration = ''
|
||||||
|
if [ -z "$SSH_AUTH_SOCK" -o -z "$SSH_CONNECTION" ]; then
|
||||||
|
export SSH_AUTH_SOCK=${socketPath}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
fishIntegration = ''
|
||||||
|
if test -z "$SSH_AUTH_SOCK"; or test -z "$SSH_CONNECTION"
|
||||||
|
set -x SSH_AUTH_SOCK ${socketPath}
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
nushellIntegration =
|
||||||
let
|
let
|
||||||
|
unsetOrEmpty = var: ''("${var}" not-in $env) or ($env.${var} | is-empty)'';
|
||||||
socketPath =
|
socketPath =
|
||||||
if pkgs.stdenv.isDarwin then
|
if pkgs.stdenv.isDarwin then
|
||||||
"$(${lib.getExe pkgs.getconf} DARWIN_USER_TEMP_DIR)/${cfg.socket}"
|
''$"(${lib.getExe pkgs.getconf} DARWIN_USER_TEMP_DIR)/${cfg.socket}"''
|
||||||
else
|
else
|
||||||
"$XDG_RUNTIME_DIR/${cfg.socket}";
|
''$"($env.XDG_RUNTIME_DIR)/${cfg.socket}"'';
|
||||||
|
|
||||||
# Preserve $SSH_AUTH_SOCK only if it stems from a forwarded agent,
|
|
||||||
# which is the case if both $SSH_AUTH_SOCK and $SSH_CONNECTION are
|
|
||||||
# set.
|
|
||||||
bashIntegration = ''
|
|
||||||
if [ -z "$SSH_AUTH_SOCK" -o -z "$SSH_CONNECTION" ]; then
|
|
||||||
export SSH_AUTH_SOCK=${socketPath}
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
fishIntegration = ''
|
|
||||||
if test -z "$SSH_AUTH_SOCK"; or test -z "$SSH_CONNECTION"
|
|
||||||
set -x SSH_AUTH_SOCK ${socketPath}
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
nushellIntegration =
|
|
||||||
let
|
|
||||||
unsetOrEmpty = var: ''("${var}" not-in $env) or ($env.${var} | is-empty)'';
|
|
||||||
socketPath =
|
|
||||||
if pkgs.stdenv.isDarwin then
|
|
||||||
''$"(${lib.getExe pkgs.getconf} DARWIN_USER_TEMP_DIR)/${cfg.socket}"''
|
|
||||||
else
|
|
||||||
''$"($env.XDG_RUNTIME_DIR)/${cfg.socket}"'';
|
|
||||||
in
|
|
||||||
''
|
|
||||||
if ${unsetOrEmpty "SSH_AUTH_SOCK"} or ${unsetOrEmpty "SSH_CONNECTION"} {
|
|
||||||
$env.SSH_AUTH_SOCK = ${socketPath}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
in
|
in
|
||||||
{
|
''
|
||||||
# $SSH_AUTH_SOCK has to be set early since other tools rely on it
|
if ${unsetOrEmpty "SSH_AUTH_SOCK"} or ${unsetOrEmpty "SSH_CONNECTION"} {
|
||||||
bash.profileExtra = lib.mkIf cfg.enableBashIntegration (lib.mkOrder 900 bashIntegration);
|
$env.SSH_AUTH_SOCK = ${socketPath}
|
||||||
fish.shellInit = lib.mkIf cfg.enableFishIntegration (lib.mkOrder 900 fishIntegration);
|
}
|
||||||
nushell.extraConfig = lib.mkIf cfg.enableNushellIntegration (lib.mkOrder 900 nushellIntegration);
|
'';
|
||||||
zsh.envExtra = lib.mkIf cfg.enableZshIntegration (lib.mkOrder 900 bashIntegration);
|
in
|
||||||
};
|
{
|
||||||
}
|
# $SSH_AUTH_SOCK has to be set early since other tools rely on it
|
||||||
|
bash.profileExtra = lib.mkIf cfg.enableBashIntegration (lib.mkOrder 900 bashIntegration);
|
||||||
|
fish.shellInit = lib.mkIf cfg.enableFishIntegration (lib.mkOrder 900 fishIntegration);
|
||||||
|
nushell.extraConfig = lib.mkIf cfg.enableNushellIntegration (lib.mkOrder 900 nushellIntegration);
|
||||||
|
zsh.envExtra = lib.mkIf cfg.enableZshIntegration (lib.mkOrder 900 bashIntegration);
|
||||||
|
};
|
||||||
|
|
||||||
(lib.mkIf pkgs.stdenv.isLinux {
|
systemd.user.services.ssh-agent = {
|
||||||
systemd.user.services.ssh-agent = {
|
Install.WantedBy = [ "default.target" ];
|
||||||
Install.WantedBy = [ "default.target" ];
|
Unit = {
|
||||||
Unit = {
|
Description = "SSH authentication agent";
|
||||||
Description = "SSH authentication agent";
|
Documentation = "man:ssh-agent(1)";
|
||||||
Documentation = "man:ssh-agent(1)";
|
};
|
||||||
};
|
Service.ExecStart = "${lib.getExe' cfg.package "ssh-agent"} -D -a %t/${cfg.socket}${
|
||||||
Service.ExecStart = "${lib.getExe' cfg.package "ssh-agent"} -D -a %t/${cfg.socket}${
|
lib.optionalString (
|
||||||
|
cfg.defaultMaximumIdentityLifetime != null
|
||||||
|
) " -t ${toString cfg.defaultMaximumIdentityLifetime}"
|
||||||
|
}";
|
||||||
|
};
|
||||||
|
|
||||||
|
launchd.agents.ssh-agent = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
ProgramArguments = [
|
||||||
|
(lib.getExe pkgs.bash)
|
||||||
|
"-c"
|
||||||
|
''${lib.getExe' cfg.package "ssh-agent"} -D -a "$(${lib.getExe pkgs.getconf} DARWIN_USER_TEMP_DIR)/${cfg.socket}"${
|
||||||
lib.optionalString (
|
lib.optionalString (
|
||||||
cfg.defaultMaximumIdentityLifetime != null
|
cfg.defaultMaximumIdentityLifetime != null
|
||||||
) " -t ${toString cfg.defaultMaximumIdentityLifetime}"
|
) " -t ${toString cfg.defaultMaximumIdentityLifetime}"
|
||||||
}";
|
}''
|
||||||
|
];
|
||||||
|
KeepAlive = {
|
||||||
|
Crashed = true;
|
||||||
|
SuccessfulExit = false;
|
||||||
};
|
};
|
||||||
})
|
ProcessType = "Background";
|
||||||
|
RunAtLoad = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
(lib.mkIf pkgs.stdenv.isDarwin {
|
|
||||||
launchd.agents.ssh-agent = {
|
|
||||||
enable = true;
|
|
||||||
config = {
|
|
||||||
ProgramArguments = [
|
|
||||||
(lib.getExe pkgs.bash)
|
|
||||||
"-c"
|
|
||||||
''${lib.getExe' cfg.package "ssh-agent"} -D -a "$(${lib.getExe pkgs.getconf} DARWIN_USER_TEMP_DIR)/${cfg.socket}"${
|
|
||||||
lib.optionalString (
|
|
||||||
cfg.defaultMaximumIdentityLifetime != null
|
|
||||||
) " -t ${toString cfg.defaultMaximumIdentityLifetime}"
|
|
||||||
}''
|
|
||||||
];
|
|
||||||
KeepAlive = {
|
|
||||||
Crashed = true;
|
|
||||||
SuccessfulExit = false;
|
|
||||||
};
|
|
||||||
ProcessType = "Background";
|
|
||||||
RunAtLoad = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ let
|
|||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
meta.maintainers = [ lib.maintainers.AndersonTorres ];
|
meta.maintainers = [ ];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
xsession.windowManager.fluxbox = {
|
xsession.windowManager.fluxbox = {
|
||||||
|
|||||||
@@ -19,79 +19,71 @@ in
|
|||||||
package = lib.mkPackageOption pkgs "yubikey-agent" { };
|
package = lib.mkPackageOption pkgs "yubikey-agent" { };
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable (
|
config = mkIf cfg.enable {
|
||||||
lib.mkMerge [
|
home.packages = [ cfg.package ];
|
||||||
{ home.packages = [ cfg.package ]; }
|
|
||||||
|
|
||||||
(mkIf pkgs.stdenv.isLinux {
|
home.sessionVariables.SSH_AUTH_SOCK =
|
||||||
systemd.user.services.yubikey-agent = {
|
if pkgs.stdenv.isDarwin then
|
||||||
Unit = {
|
"/tmp/yubikey-agent.sock"
|
||||||
Description = "Seamless ssh-agent for YubiKeys";
|
else
|
||||||
Documentation = "https://github.com/FiloSottile/yubikey-agent";
|
"\${XDG_RUNTIME_DIR:-/run/user/$UID}/yubikey-agent/yubikey-agent.sock";
|
||||||
Requires = "yubikey-agent.socket";
|
|
||||||
After = "yubikey-agent.socket";
|
|
||||||
RefuseManualStart = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
Service = {
|
systemd.user.services.yubikey-agent = {
|
||||||
ExecStart = "${cfg.package}/bin/yubikey-agent -l %t/yubikey-agent/yubikey-agent.sock";
|
Unit = {
|
||||||
Type = "simple";
|
Description = "Seamless ssh-agent for YubiKeys";
|
||||||
# /run/user/$UID for the socket
|
Documentation = "https://github.com/FiloSottile/yubikey-agent";
|
||||||
ReadWritePaths = [ "%t" ];
|
Requires = "yubikey-agent.socket";
|
||||||
|
After = "yubikey-agent.socket";
|
||||||
|
RefuseManualStart = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
Service = {
|
||||||
|
ExecStart = "${cfg.package}/bin/yubikey-agent -l %t/yubikey-agent/yubikey-agent.sock";
|
||||||
|
Type = "simple";
|
||||||
|
# /run/user/$UID for the socket
|
||||||
|
ReadWritePaths = [ "%t" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.sockets.yubikey-agent = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Unix domain socket for Yubikey SSH agent";
|
||||||
|
Documentation = "https://github.com/FiloSottile/yubikey-agent";
|
||||||
|
};
|
||||||
|
|
||||||
|
Socket = {
|
||||||
|
ListenStream = "%t/yubikey-agent/yubikey-agent.sock";
|
||||||
|
RuntimeDirectory = "yubikey-agent";
|
||||||
|
SocketMode = "0600";
|
||||||
|
DirectoryMode = "0700";
|
||||||
|
};
|
||||||
|
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "sockets.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
launchd.agents.yubikey-agent = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
ProgramArguments = [
|
||||||
|
"${cfg.package}/bin/yubikey-agent"
|
||||||
|
"-l"
|
||||||
|
"/tmp/yubikey-agent.sock"
|
||||||
|
];
|
||||||
|
|
||||||
|
KeepAlive = {
|
||||||
|
Crashed = true;
|
||||||
|
SuccessfulExit = false;
|
||||||
|
};
|
||||||
|
ProcessType = "Background";
|
||||||
|
Sockets = {
|
||||||
|
Listener = {
|
||||||
|
SockPathName = "/tmp/yubikey-agent.sock";
|
||||||
|
SockPathMode = 384; # 0600 in decimal
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
systemd.user.sockets.yubikey-agent = {
|
};
|
||||||
Unit = {
|
};
|
||||||
Description = "Unix domain socket for Yubikey SSH agent";
|
|
||||||
Documentation = "https://github.com/FiloSottile/yubikey-agent";
|
|
||||||
};
|
|
||||||
|
|
||||||
Socket = {
|
|
||||||
ListenStream = "%t/yubikey-agent/yubikey-agent.sock";
|
|
||||||
RuntimeDirectory = "yubikey-agent";
|
|
||||||
SocketMode = "0600";
|
|
||||||
DirectoryMode = "0700";
|
|
||||||
};
|
|
||||||
|
|
||||||
Install = {
|
|
||||||
WantedBy = [ "sockets.target" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
home.sessionVariables = {
|
|
||||||
SSH_AUTH_SOCK = "\${XDG_RUNTIME_DIR:-/run/user/$UID}/yubikey-agent/yubikey-agent.sock";
|
|
||||||
};
|
|
||||||
})
|
|
||||||
|
|
||||||
(mkIf pkgs.stdenv.isDarwin {
|
|
||||||
launchd.agents.yubikey-agent = {
|
|
||||||
enable = true;
|
|
||||||
config = {
|
|
||||||
ProgramArguments = [
|
|
||||||
"${cfg.package}/bin/yubikey-agent"
|
|
||||||
"-l"
|
|
||||||
"/tmp/yubikey-agent.sock"
|
|
||||||
];
|
|
||||||
|
|
||||||
KeepAlive = {
|
|
||||||
Crashed = true;
|
|
||||||
SuccessfulExit = false;
|
|
||||||
};
|
|
||||||
ProcessType = "Background";
|
|
||||||
Sockets = {
|
|
||||||
Listener = {
|
|
||||||
SockPathName = "/tmp/yubikey-agent.sock";
|
|
||||||
SockPathMode = 384; # 0600 in decimal
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
home.sessionVariables = {
|
|
||||||
SSH_AUTH_SOCK = "/tmp/yubikey-agent.sock";
|
|
||||||
};
|
|
||||||
})
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,9 +62,9 @@
|
|||||||
|
|
||||||
extensions = [
|
extensions = [
|
||||||
(config.lib.vicinae.mkRayCastExtension {
|
(config.lib.vicinae.mkRayCastExtension {
|
||||||
name = "gif-search";
|
name = "cdnjs";
|
||||||
sha256 = "sha256-G7il8T1L+P/2mXWJsb68n4BCbVKcrrtK8GnBNxzt73Q=";
|
sha256 = "sha256-k3YfruMxSOMf8K65iTW84aZxiknADCcntJOAE89agYc=";
|
||||||
rev = "4d417c2dfd86a5b2bea202d4a7b48d8eb3dbaeb1";
|
rev = "ac7c50844bf77d0cf51daa840e369d999f2add59";
|
||||||
})
|
})
|
||||||
(config.lib.vicinae.mkExtension {
|
(config.lib.vicinae.mkExtension {
|
||||||
name = "test-extension";
|
name = "test-extension";
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
assertFileExists "home-files/.config/vicinae/settings.json"
|
assertFileExists "home-files/.config/vicinae/settings.json"
|
||||||
assertFileExists "home-files/.config/systemd/user/vicinae.service"
|
assertFileExists "home-files/.config/systemd/user/vicinae.service"
|
||||||
assertFileExists "home-files/.local/share/vicinae/themes/catppuccin-mocha.toml"
|
assertFileExists "home-files/.local/share/vicinae/themes/catppuccin-mocha.toml"
|
||||||
assertFileExists "home-files/.local/share/vicinae/extensions/gif-search/package.json"
|
assertFileExists "home-files/.local/share/vicinae/extensions/cdnjs/package.json"
|
||||||
assertFileExists "home-files/.local/share/vicinae/extensions/test-extension/package.json"
|
assertFileExists "home-files/.local/share/vicinae/extensions/test-extension/package.json"
|
||||||
assertFileContent "home-files/.config/systemd/user/vicinae.service" ${./service.service}
|
assertFileContent "home-files/.config/systemd/user/vicinae.service" ${./service.service}
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -26,5 +26,5 @@ Type=oneshot
|
|||||||
Wants=podman-user-wait-network-online.service
|
Wants=podman-user-wait-network-online.service
|
||||||
After=podman-user-wait-network-online.service
|
After=podman-user-wait-network-online.service
|
||||||
Description=Service for build my-bld
|
Description=Service for build my-bld
|
||||||
RequiresMountsFor=%t/containers
|
|
||||||
SourcePath=/nix/store/00000000000000000000000000000000-home-build-podman-my-bld/quadlets/podman-my-bld.build
|
SourcePath=/nix/store/00000000000000000000000000000000-home-build-podman-my-bld/quadlets/podman-my-bld.build
|
||||||
|
RequiresMountsFor=%t/containers
|
||||||
|
|||||||
@@ -4,50 +4,50 @@
|
|||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
{
|
||||||
lib.mkIf config.test.enableLegacyIfd {
|
|
||||||
imports = [ ./podman-stubs.nix ];
|
imports = [ ./podman-stubs.nix ];
|
||||||
|
config = lib.mkIf config.test.enableLegacyIfd {
|
||||||
|
services.podman = {
|
||||||
|
enable = true;
|
||||||
|
builds = {
|
||||||
|
"my-bld" = {
|
||||||
|
file =
|
||||||
|
let
|
||||||
|
containerFile = pkgs.writeTextFile {
|
||||||
|
name = "Containerfile";
|
||||||
|
text = ''
|
||||||
|
FROM docker.io/alpine:latest
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
"${containerFile}";
|
||||||
|
};
|
||||||
|
|
||||||
services.podman = {
|
"my-bld-2" = {
|
||||||
enable = true;
|
file = "https://www.github.com/././Containerfile";
|
||||||
builds = {
|
extraConfig = {
|
||||||
"my-bld" = {
|
Build.ImageTag = [
|
||||||
file =
|
"locahost/somethingelse"
|
||||||
let
|
"localhost/anothertag"
|
||||||
containerFile = pkgs.writeTextFile {
|
];
|
||||||
name = "Containerfile";
|
};
|
||||||
text = ''
|
|
||||||
FROM docker.io/alpine:latest
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
"${containerFile}";
|
|
||||||
};
|
|
||||||
|
|
||||||
"my-bld-2" = {
|
|
||||||
file = "https://www.github.com/././Containerfile";
|
|
||||||
extraConfig = {
|
|
||||||
Build.ImageTag = [
|
|
||||||
"locahost/somethingelse"
|
|
||||||
"localhost/anothertag"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
test.asserts.assertions.expected = [
|
||||||
|
''In 'my-bld-2' config. Build.ImageTag: '[ "locahost/somethingelse" "localhost/anothertag" ]' does not contain 'homemanager/my-bld-2'.''
|
||||||
|
];
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
configPath=home-files/.config/systemd/user
|
||||||
|
buildFile=$configPath/podman-my-bld-build.service
|
||||||
|
|
||||||
|
assertFileExists $buildFile
|
||||||
|
|
||||||
|
buildFile=$(normalizeStorePaths $buildFile)
|
||||||
|
|
||||||
|
assertFileContent $buildFile ${./build-expected.service}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
test.asserts.assertions.expected = [
|
|
||||||
''In 'my-bld-2' config. Build.ImageTag: '[ "locahost/somethingelse" "localhost/anothertag" ]' does not contain 'homemanager/my-bld-2'.''
|
|
||||||
];
|
|
||||||
|
|
||||||
nmt.script = ''
|
|
||||||
configPath=home-files/.config/systemd/user
|
|
||||||
buildFile=$configPath/podman-my-bld-build.service
|
|
||||||
|
|
||||||
assertFileExists $buildFile
|
|
||||||
|
|
||||||
buildFile=$(normalizeStorePaths $buildFile)
|
|
||||||
|
|
||||||
assertFileContent $buildFile ${./build-expected.service}
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,18 +27,18 @@ WantedBy=default.target
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Environment=PATH=/run/wrappers/bin:/run/current-system/sw/bin:/home/hm-user/.nix-profile/bin:@systemd@/bin
|
Environment=PATH=/run/wrappers/bin:/run/current-system/sw/bin:@nftables@/bin:/home/hm-user/.nix-profile/bin:@systemd@/bin
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
TimeoutStopSec=30
|
TimeoutStopSec=30
|
||||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||||
KillMode=mixed
|
KillMode=mixed
|
||||||
ExecStop=/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i --cidfile=%t/%N.cid
|
ExecStop=/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container
|
||||||
ExecStopPost=-/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i --cidfile=%t/%N.cid
|
ExecStopPost=-/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container
|
||||||
Delegate=yes
|
Delegate=yes
|
||||||
Type=notify
|
Type=notify
|
||||||
NotifyAccess=all
|
NotifyAccess=all
|
||||||
SyslogIdentifier=%N
|
SyslogIdentifier=%N
|
||||||
ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman run --name my-container --cidfile=%t/%N.cid --replace --rm --cgroups=split --entrypoint /sleep.sh --network-alias test-alias-1 --network-alias test-alias-2 --read-only-tmpfs --network mynet --sdnotify=conmon -d --device /dev/null:/dev/null -v /tmp:/tmp --label io.containers.autoupdate=registry --publish 8080:80 --env VAL_A=A --env VAL_B=2 --env VAL_C=false --label nix.home-manager.managed=true --security-opt=no-new-privileges docker.io/alpine:latest
|
ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman run --name my-container --replace --rm --cgroups=split --entrypoint /sleep.sh --network-alias test-alias-1 --network-alias test-alias-2 --read-only-tmpfs --network mynet --sdnotify=conmon -d --device /dev/null:/dev/null -v /tmp:/tmp --label io.containers.autoupdate=registry --publish 8080:80 --env VAL_A=A --env VAL_B=2 --env VAL_C=false --label nix.home-manager.managed=true --security-opt=no-new-privileges docker.io/alpine:latest
|
||||||
|
|
||||||
[Unit]
|
[Unit]
|
||||||
Wants=podman-user-wait-network-online.service
|
Wants=podman-user-wait-network-online.service
|
||||||
|
|||||||
@@ -1,61 +1,62 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
{
|
||||||
lib.mkIf config.test.enableLegacyIfd {
|
|
||||||
imports = [ ./podman-stubs.nix ];
|
imports = [ ./podman-stubs.nix ];
|
||||||
|
config = lib.mkIf config.test.enableLegacyIfd {
|
||||||
|
|
||||||
services.podman = {
|
services.podman = {
|
||||||
enable = true;
|
enable = true;
|
||||||
containers = {
|
containers = {
|
||||||
"my-container" = {
|
"my-container" = {
|
||||||
description = "home-manager test";
|
description = "home-manager test";
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
autoUpdate = "registry";
|
autoUpdate = "registry";
|
||||||
devices = [ "/dev/null:/dev/null" ];
|
devices = [ "/dev/null:/dev/null" ];
|
||||||
entrypoint = "/sleep.sh";
|
entrypoint = "/sleep.sh";
|
||||||
environment = {
|
environment = {
|
||||||
"VAL_A" = "A";
|
"VAL_A" = "A";
|
||||||
"VAL_B" = 2;
|
"VAL_B" = 2;
|
||||||
"VAL_C" = false;
|
"VAL_C" = false;
|
||||||
};
|
|
||||||
extraPodmanArgs = [ "--security-opt=no-new-privileges" ];
|
|
||||||
extraConfig = {
|
|
||||||
Container = {
|
|
||||||
ReadOnlyTmpfs = true;
|
|
||||||
NetworkAlias = "test-alias-2";
|
|
||||||
};
|
};
|
||||||
Service.Restart = "on-failure";
|
extraPodmanArgs = [ "--security-opt=no-new-privileges" ];
|
||||||
Unit.Before = "fake.target";
|
extraConfig = {
|
||||||
|
Container = {
|
||||||
|
ReadOnlyTmpfs = true;
|
||||||
|
NetworkAlias = "test-alias-2";
|
||||||
|
};
|
||||||
|
Service.Restart = "on-failure";
|
||||||
|
Unit.Before = "fake.target";
|
||||||
|
};
|
||||||
|
image = "docker.io/alpine:latest";
|
||||||
|
# Should not generate Requires/After for network because there is no
|
||||||
|
# services.podman.networks.mynet.
|
||||||
|
network = "mynet";
|
||||||
|
networkAlias = [ "test-alias-1" ];
|
||||||
|
ports = [ "8080:80" ];
|
||||||
|
volumes = [ "/tmp:/tmp" ];
|
||||||
};
|
};
|
||||||
image = "docker.io/alpine:latest";
|
|
||||||
# Should not generate Requires/After for network because there is no
|
|
||||||
# services.podman.networks.mynet.
|
|
||||||
network = "mynet";
|
|
||||||
networkAlias = [ "test-alias-1" ];
|
|
||||||
ports = [ "8080:80" ];
|
|
||||||
volumes = [ "/tmp:/tmp" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
"my-container-2" = {
|
"my-container-2" = {
|
||||||
image = "docker.io/alpine:latest";
|
image = "docker.io/alpine:latest";
|
||||||
extraConfig = {
|
extraConfig = {
|
||||||
Container.ContainerName = "some-other-container-name";
|
Container.ContainerName = "some-other-container-name";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
test.asserts.assertions.expected = [
|
||||||
|
''In 'my-container-2' config. Container.ContainerName: 'some-other-container-name' does not match expected type: value "my-container-2" (singular enum)''
|
||||||
|
];
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
configPath=home-files/.config/systemd/user
|
||||||
|
containerFile=$configPath/podman-my-container.service
|
||||||
|
|
||||||
|
assertFileExists $containerFile
|
||||||
|
|
||||||
|
containerFile=$(normalizeStorePaths $containerFile)
|
||||||
|
|
||||||
|
assertFileContent $containerFile ${./container-expected.service}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
test.asserts.assertions.expected = [
|
|
||||||
''In 'my-container-2' config. Container.ContainerName: 'some-other-container-name' does not match expected type: value "my-container-2" (singular enum)''
|
|
||||||
];
|
|
||||||
|
|
||||||
nmt.script = ''
|
|
||||||
configPath=home-files/.config/systemd/user
|
|
||||||
containerFile=$configPath/podman-my-container.service
|
|
||||||
|
|
||||||
assertFileExists $containerFile
|
|
||||||
|
|
||||||
containerFile=$(normalizeStorePaths $containerFile)
|
|
||||||
|
|
||||||
assertFileContent $containerFile ${./container-expected.service}
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
{
|
||||||
lib.mkIf config.test.enableLegacyIfd {
|
|
||||||
imports = [ ./podman-stubs.nix ];
|
imports = [ ./podman-stubs.nix ];
|
||||||
|
config = lib.mkIf config.test.enableLegacyIfd {
|
||||||
services.podman = {
|
services.podman = {
|
||||||
enable = true;
|
enable = true;
|
||||||
images = {
|
images = {
|
||||||
"my-img" = {
|
"my-img" = {
|
||||||
image = "docker.io/alpine:latest";
|
image = "docker.io/alpine:latest";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
configPath=home-files/.config/systemd/user
|
||||||
|
imageFile=$configPath/podman-my-img-image.service
|
||||||
|
assertFileExists $imageFile
|
||||||
|
|
||||||
|
imageFile=$(normalizeStorePaths $imageFile)
|
||||||
|
|
||||||
|
assertFileContent $imageFile ${./image-expected.service}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
nmt.script = ''
|
|
||||||
configPath=home-files/.config/systemd/user
|
|
||||||
imageFile=$configPath/podman-my-img-image.service
|
|
||||||
assertFileExists $imageFile
|
|
||||||
|
|
||||||
imageFile=$(normalizeStorePaths $imageFile)
|
|
||||||
|
|
||||||
assertFileContent $imageFile ${./image-expected.service}
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,5 +26,5 @@ Type=oneshot
|
|||||||
Wants=podman-user-wait-network-online.service
|
Wants=podman-user-wait-network-online.service
|
||||||
After=podman-user-wait-network-online.service
|
After=podman-user-wait-network-online.service
|
||||||
Description=Service for build my-bld
|
Description=Service for build my-bld
|
||||||
RequiresMountsFor=%t/containers
|
|
||||||
SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container-bld/quadlets/podman-my-bld.build
|
SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container-bld/quadlets/podman-my-bld.build
|
||||||
|
RequiresMountsFor=%t/containers
|
||||||
|
|||||||
@@ -15,24 +15,24 @@ WantedBy=default.target
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Environment=PATH=/run/wrappers/bin:/run/current-system/sw/bin:/home/hm-user/.nix-profile/bin:@systemd@/bin
|
Environment=PATH=/run/wrappers/bin:/run/current-system/sw/bin:@nftables@/bin:/home/hm-user/.nix-profile/bin:@systemd@/bin
|
||||||
Restart=always
|
Restart=always
|
||||||
TimeoutStopSec=30
|
TimeoutStopSec=30
|
||||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||||
KillMode=mixed
|
KillMode=mixed
|
||||||
ExecStop=/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i --cidfile=%t/%N.cid
|
ExecStop=/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container-bld
|
||||||
ExecStopPost=-/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i --cidfile=%t/%N.cid
|
ExecStopPost=-/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container-bld
|
||||||
Delegate=yes
|
Delegate=yes
|
||||||
Type=notify
|
Type=notify
|
||||||
NotifyAccess=all
|
NotifyAccess=all
|
||||||
SyslogIdentifier=%N
|
SyslogIdentifier=%N
|
||||||
ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman run --name my-container-bld --cidfile=%t/%N.cid --replace --rm --cgroups=split --sdnotify=conmon -d --label nix.home-manager.managed=true homemanager/my-bld
|
ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman run --name my-container-bld --replace --rm --cgroups=split --sdnotify=conmon -d --label nix.home-manager.managed=true homemanager/my-bld
|
||||||
|
|
||||||
[Unit]
|
[Unit]
|
||||||
Wants=podman-user-wait-network-online.service
|
Wants=podman-user-wait-network-online.service
|
||||||
After=podman-user-wait-network-online.service
|
After=podman-user-wait-network-online.service
|
||||||
Description=Service for container my-container-bld
|
Description=Service for container my-container-bld
|
||||||
SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container-bld/quadlets/podman-my-container-bld.container
|
SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container-bld/quadlets/podman-my-container-bld.container
|
||||||
|
RequiresMountsFor=%t/containers
|
||||||
Requires=podman-my-bld-build.service
|
Requires=podman-my-bld-build.service
|
||||||
After=podman-my-bld-build.service
|
After=podman-my-bld-build.service
|
||||||
RequiresMountsFor=%t/containers
|
|
||||||
|
|||||||
@@ -18,27 +18,27 @@ WantedBy=default.target
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Environment=PATH=/run/wrappers/bin:/run/current-system/sw/bin:/home/hm-user/.nix-profile/bin:@systemd@/bin
|
Environment=PATH=/run/wrappers/bin:/run/current-system/sw/bin:@nftables@/bin:/home/hm-user/.nix-profile/bin:@systemd@/bin
|
||||||
Restart=always
|
Restart=always
|
||||||
TimeoutStopSec=30
|
TimeoutStopSec=30
|
||||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||||
KillMode=mixed
|
KillMode=mixed
|
||||||
ExecStop=/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i --cidfile=%t/%N.cid
|
ExecStop=/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container
|
||||||
ExecStopPost=-/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i --cidfile=%t/%N.cid
|
ExecStopPost=-/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container
|
||||||
Delegate=yes
|
Delegate=yes
|
||||||
Type=notify
|
Type=notify
|
||||||
NotifyAccess=all
|
NotifyAccess=all
|
||||||
SyslogIdentifier=%N
|
SyslogIdentifier=%N
|
||||||
ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman run --name my-container --cidfile=%t/%N.cid --replace --rm --cgroups=split --network my-app --network externalnet --sdnotify=conmon -d -v my-app:/data --label nix.home-manager.managed=true docker.io/alpine:latest
|
ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman run --name my-container --replace --rm --cgroups=split --network my-app --network externalnet --sdnotify=conmon -d -v my-app:/data --label nix.home-manager.managed=true docker.io/alpine:latest
|
||||||
|
|
||||||
[Unit]
|
[Unit]
|
||||||
Wants=podman-user-wait-network-online.service
|
Wants=podman-user-wait-network-online.service
|
||||||
After=podman-user-wait-network-online.service
|
After=podman-user-wait-network-online.service
|
||||||
Description=Service for container my-container
|
Description=Service for container my-container
|
||||||
SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container/quadlets/podman-my-container.container
|
SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container/quadlets/podman-my-container.container
|
||||||
|
RequiresMountsFor=%t/containers
|
||||||
Requires=podman-my-img-image.service
|
Requires=podman-my-img-image.service
|
||||||
After=podman-my-img-image.service
|
After=podman-my-img-image.service
|
||||||
RequiresMountsFor=%t/containers
|
|
||||||
Requires=podman-my-app-network.service
|
Requires=podman-my-app-network.service
|
||||||
After=podman-my-app-network.service
|
After=podman-my-app-network.service
|
||||||
Requires=podman-my-app-volume.service
|
Requires=podman-my-app-volume.service
|
||||||
|
|||||||
@@ -4,78 +4,79 @@
|
|||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
{
|
||||||
lib.mkIf config.test.enableLegacyIfd {
|
|
||||||
imports = [ ./podman-stubs.nix ];
|
imports = [ ./podman-stubs.nix ];
|
||||||
|
|
||||||
services.podman = {
|
config = lib.mkIf config.test.enableLegacyIfd {
|
||||||
enable = true;
|
services.podman = {
|
||||||
builds."my-bld" = {
|
enable = true;
|
||||||
file =
|
builds."my-bld" = {
|
||||||
let
|
file =
|
||||||
containerFile = pkgs.writeTextFile {
|
let
|
||||||
name = "Containerfile";
|
containerFile = pkgs.writeTextFile {
|
||||||
text = ''
|
name = "Containerfile";
|
||||||
FROM docker.io/alpine:latest
|
text = ''
|
||||||
'';
|
FROM docker.io/alpine:latest
|
||||||
};
|
'';
|
||||||
in
|
};
|
||||||
"${containerFile}";
|
in
|
||||||
};
|
"${containerFile}";
|
||||||
containers = {
|
|
||||||
"my-container" = {
|
|
||||||
image = "my-img.image";
|
|
||||||
network = [
|
|
||||||
"my-app.network"
|
|
||||||
"externalnet"
|
|
||||||
];
|
|
||||||
volumes = [ "my-app.volume:/data" ];
|
|
||||||
};
|
};
|
||||||
"my-container-bld" = {
|
containers = {
|
||||||
image = "my-bld.build";
|
"my-container" = {
|
||||||
|
image = "my-img.image";
|
||||||
|
network = [
|
||||||
|
"my-app.network"
|
||||||
|
"externalnet"
|
||||||
|
];
|
||||||
|
volumes = [ "my-app.volume:/data" ];
|
||||||
|
};
|
||||||
|
"my-container-bld" = {
|
||||||
|
image = "my-bld.build";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
images."my-img" = {
|
||||||
|
image = "docker.io/alpine:latest";
|
||||||
|
};
|
||||||
|
networks."my-app" = {
|
||||||
|
gateway = "192.168.123.1";
|
||||||
|
subnet = "192.168.123.0/24";
|
||||||
|
};
|
||||||
|
volumes."my-app" = {
|
||||||
|
device = "tmpfs";
|
||||||
|
preserve = false;
|
||||||
|
type = "tmpfs";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
images."my-img" = {
|
|
||||||
image = "docker.io/alpine:latest";
|
nmt.script = ''
|
||||||
};
|
configPath=home-files/.config/systemd/user
|
||||||
networks."my-app" = {
|
buildFile=$configPath/podman-my-bld-build.service
|
||||||
gateway = "192.168.123.1";
|
containerFile=$configPath/podman-my-container.service
|
||||||
subnet = "192.168.123.0/24";
|
containerBldFile=$configPath/podman-my-container-bld.service
|
||||||
};
|
imageFile=$configPath/podman-my-img-image.service
|
||||||
volumes."my-app" = {
|
networkFile=$configPath/podman-my-app-network.service
|
||||||
device = "tmpfs";
|
volumeFile=$configPath/podman-my-app-volume.service
|
||||||
preserve = false;
|
assertFileExists $buildFile
|
||||||
type = "tmpfs";
|
assertFileExists $containerFile
|
||||||
};
|
assertFileExists $containerBldFile
|
||||||
|
assertFileExists $imageFile
|
||||||
|
assertFileExists $networkFile
|
||||||
|
assertFileExists $volumeFile
|
||||||
|
|
||||||
|
buildFile=$(normalizeStorePaths $buildFile)
|
||||||
|
containerFile=$(normalizeStorePaths $containerFile)
|
||||||
|
containerBldFile=$(normalizeStorePaths $containerBldFile)
|
||||||
|
imageFile=$(normalizeStorePaths $imageFile)
|
||||||
|
networkFile=$(normalizeStorePaths $networkFile)
|
||||||
|
volumeFile=$(normalizeStorePaths $volumeFile)
|
||||||
|
|
||||||
|
assertFileContent $buildFile ${./integration-build-expected.service}
|
||||||
|
assertFileContent $containerFile ${./integration-container-expected.service}
|
||||||
|
assertFileContent $containerBldFile ${./integration-container-bld-expected.service}
|
||||||
|
assertFileContent $imageFile ${./integration-image-expected.service}
|
||||||
|
assertFileContent $networkFile ${./integration-network-expected.service}
|
||||||
|
assertFileContent $volumeFile ${./integration-volume-expected.service}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
nmt.script = ''
|
|
||||||
configPath=home-files/.config/systemd/user
|
|
||||||
buildFile=$configPath/podman-my-bld-build.service
|
|
||||||
containerFile=$configPath/podman-my-container.service
|
|
||||||
containerBldFile=$configPath/podman-my-container-bld.service
|
|
||||||
imageFile=$configPath/podman-my-img-image.service
|
|
||||||
networkFile=$configPath/podman-my-app-network.service
|
|
||||||
volumeFile=$configPath/podman-my-app-volume.service
|
|
||||||
assertFileExists $buildFile
|
|
||||||
assertFileExists $containerFile
|
|
||||||
assertFileExists $containerBldFile
|
|
||||||
assertFileExists $imageFile
|
|
||||||
assertFileExists $networkFile
|
|
||||||
assertFileExists $volumeFile
|
|
||||||
|
|
||||||
buildFile=$(normalizeStorePaths $buildFile)
|
|
||||||
containerFile=$(normalizeStorePaths $containerFile)
|
|
||||||
containerBldFile=$(normalizeStorePaths $containerBldFile)
|
|
||||||
imageFile=$(normalizeStorePaths $imageFile)
|
|
||||||
networkFile=$(normalizeStorePaths $networkFile)
|
|
||||||
volumeFile=$(normalizeStorePaths $volumeFile)
|
|
||||||
|
|
||||||
assertFileContent $buildFile ${./integration-build-expected.service}
|
|
||||||
assertFileContent $containerFile ${./integration-container-expected.service}
|
|
||||||
assertFileContent $containerBldFile ${./integration-container-bld-expected.service}
|
|
||||||
assertFileContent $imageFile ${./integration-image-expected.service}
|
|
||||||
assertFileContent $networkFile ${./integration-network-expected.service}
|
|
||||||
assertFileContent $volumeFile ${./integration-volume-expected.service}
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,62 +1,62 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
{
|
||||||
lib.mkIf config.test.enableLegacyIfd {
|
|
||||||
imports = [ ./podman-stubs.nix ];
|
imports = [ ./podman-stubs.nix ];
|
||||||
|
config = lib.mkIf config.test.enableLegacyIfd {
|
||||||
|
services.podman = {
|
||||||
|
enable = true;
|
||||||
|
containers."my-container-1" = {
|
||||||
|
description = "home-manager test";
|
||||||
|
autoUpdate = "registry";
|
||||||
|
autoStart = true;
|
||||||
|
image = "docker.io/alpine:latest";
|
||||||
|
entrypoint = "sleep 1000";
|
||||||
|
environment = {
|
||||||
|
"VAL_A" = "A";
|
||||||
|
"VAL_B" = 2;
|
||||||
|
"VAL_C" = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
services.podman = {
|
services.podman.containers."my-container-2" = {
|
||||||
enable = true;
|
|
||||||
containers."my-container-1" = {
|
|
||||||
description = "home-manager test";
|
description = "home-manager test";
|
||||||
autoUpdate = "registry";
|
autoUpdate = "registry";
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
image = "docker.io/alpine:latest";
|
image = "docker.io/alpine:latest";
|
||||||
entrypoint = "sleep 1000";
|
entrypoint = "sleep 1000";
|
||||||
environment = {
|
environment = {
|
||||||
"VAL_A" = "A";
|
"VAL_A" = "B";
|
||||||
"VAL_B" = 2;
|
"VAL_B" = 3;
|
||||||
"VAL_C" = false;
|
"VAL_C" = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
services.podman.containers."my-container-2" = {
|
services.podman.networks."mynet-1" = {
|
||||||
description = "home-manager test";
|
subnet = "192.168.1.0/24";
|
||||||
autoUpdate = "registry";
|
gateway = "192.168.1.1";
|
||||||
autoStart = true;
|
|
||||||
image = "docker.io/alpine:latest";
|
|
||||||
entrypoint = "sleep 1000";
|
|
||||||
environment = {
|
|
||||||
"VAL_A" = "B";
|
|
||||||
"VAL_B" = 3;
|
|
||||||
"VAL_C" = true;
|
|
||||||
};
|
};
|
||||||
|
services.podman.networks."mynet-2" = {
|
||||||
|
subnet = "192.168.2.0/24";
|
||||||
|
gateway = "192.168.2.1";
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
configPath=home-files/.config/podman
|
||||||
|
containerManifest=$configPath/containers.manifest
|
||||||
|
networkManifest=$configPath/networks.manifest
|
||||||
|
|
||||||
|
assertFileExists $containerManifest
|
||||||
|
assertFileExists $networkManifest
|
||||||
|
|
||||||
|
assertFileContent $containerManifest ${builtins.toFile "containers.expected" ''
|
||||||
|
my-container-1
|
||||||
|
my-container-2
|
||||||
|
''}
|
||||||
|
|
||||||
|
assertFileContent $networkManifest ${builtins.toFile "networks.expected" ''
|
||||||
|
mynet-1
|
||||||
|
mynet-2
|
||||||
|
''}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
services.podman.networks."mynet-1" = {
|
|
||||||
subnet = "192.168.1.0/24";
|
|
||||||
gateway = "192.168.1.1";
|
|
||||||
};
|
|
||||||
services.podman.networks."mynet-2" = {
|
|
||||||
subnet = "192.168.2.0/24";
|
|
||||||
gateway = "192.168.2.1";
|
|
||||||
};
|
|
||||||
|
|
||||||
nmt.script = ''
|
|
||||||
configPath=home-files/.config/podman
|
|
||||||
containerManifest=$configPath/containers.manifest
|
|
||||||
networkManifest=$configPath/networks.manifest
|
|
||||||
|
|
||||||
assertFileExists $containerManifest
|
|
||||||
assertFileExists $networkManifest
|
|
||||||
|
|
||||||
assertFileContent $containerManifest ${builtins.toFile "containers.expected" ''
|
|
||||||
my-container-1
|
|
||||||
my-container-2
|
|
||||||
''}
|
|
||||||
|
|
||||||
assertFileContent $networkManifest ${builtins.toFile "networks.expected" ''
|
|
||||||
mynet-1
|
|
||||||
mynet-2
|
|
||||||
''}
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,52 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
{
|
||||||
lib.mkIf config.test.enableLegacyIfd {
|
|
||||||
imports = [ ./podman-stubs.nix ];
|
imports = [ ./podman-stubs.nix ];
|
||||||
|
config = lib.mkIf config.test.enableLegacyIfd {
|
||||||
services.podman = {
|
services.podman = {
|
||||||
enable = true;
|
enable = true;
|
||||||
networks = {
|
networks = {
|
||||||
"my-net" = {
|
"my-net" = {
|
||||||
subnet = "192.168.1.0/24";
|
subnet = "192.168.1.0/24";
|
||||||
gateway = "192.168.1.1";
|
gateway = "192.168.1.1";
|
||||||
extraPodmanArgs = [ "--ipam-driver dhcp" ];
|
extraPodmanArgs = [ "--ipam-driver dhcp" ];
|
||||||
extraConfig = {
|
extraConfig = {
|
||||||
Network = {
|
Network = {
|
||||||
NetworkName = "my-net";
|
NetworkName = "my-net";
|
||||||
Options = {
|
Options = {
|
||||||
isolate = "true";
|
isolate = "true";
|
||||||
|
};
|
||||||
|
PodmanArgs = [
|
||||||
|
"--dns=192.168.55.1"
|
||||||
|
"--log-level=debug"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
PodmanArgs = [
|
|
||||||
"--dns=192.168.55.1"
|
|
||||||
"--log-level=debug"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
"my-net-2" = {
|
"my-net-2" = {
|
||||||
subnet = "192.168.2.0/24";
|
subnet = "192.168.2.0/24";
|
||||||
gateway = "192.168.2.1";
|
gateway = "192.168.2.1";
|
||||||
extraConfig = {
|
extraConfig = {
|
||||||
Network = {
|
Network = {
|
||||||
NetworkName = "some-other-network-name";
|
NetworkName = "some-other-network-name";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
test.asserts.assertions.expected = [
|
||||||
|
''In 'my-net-2' config. Network.NetworkName: 'some-other-network-name' does not match expected type: value "my-net-2" (singular enum)''
|
||||||
|
];
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
configPath=home-files/.config/systemd/user
|
||||||
|
networkFile=$configPath/podman-my-net-network.service
|
||||||
|
assertFileExists $networkFile
|
||||||
|
|
||||||
|
networkFile=$(normalizeStorePaths $networkFile)
|
||||||
|
|
||||||
|
assertFileContent $networkFile ${./network-expected.service}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
test.asserts.assertions.expected = [
|
|
||||||
''In 'my-net-2' config. Network.NetworkName: 'some-other-network-name' does not match expected type: value "my-net-2" (singular enum)''
|
|
||||||
];
|
|
||||||
|
|
||||||
nmt.script = ''
|
|
||||||
configPath=home-files/.config/systemd/user
|
|
||||||
networkFile=$configPath/podman-my-net-network.service
|
|
||||||
assertFileExists $networkFile
|
|
||||||
|
|
||||||
networkFile=$(normalizeStorePaths $networkFile)
|
|
||||||
|
|
||||||
assertFileContent $networkFile ${./network-expected.service}
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,44 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
{
|
||||||
lib.mkIf config.test.enableLegacyIfd {
|
|
||||||
imports = [ ./podman-stubs.nix ];
|
imports = [ ./podman-stubs.nix ];
|
||||||
|
config = lib.mkIf config.test.enableLegacyIfd {
|
||||||
services.podman = {
|
services.podman = {
|
||||||
enable = true;
|
enable = true;
|
||||||
volumes = {
|
volumes = {
|
||||||
"my-vol" = {
|
"my-vol" = {
|
||||||
device = "tmpfs";
|
device = "tmpfs";
|
||||||
extraConfig = {
|
extraConfig = {
|
||||||
Volume = {
|
Volume = {
|
||||||
User = 1000;
|
User = 1000;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
extraPodmanArgs = [ "--module=/etc/nvd.conf" ];
|
||||||
|
group = 1000;
|
||||||
|
type = "tmpfs";
|
||||||
};
|
};
|
||||||
extraPodmanArgs = [ "--module=/etc/nvd.conf" ];
|
|
||||||
group = 1000;
|
|
||||||
type = "tmpfs";
|
|
||||||
};
|
|
||||||
|
|
||||||
"my-vol-2" = {
|
"my-vol-2" = {
|
||||||
extraConfig = {
|
extraConfig = {
|
||||||
Volume = {
|
Volume = {
|
||||||
VolumeName = "some-other-volume-name";
|
VolumeName = "some-other-volume-name";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
test.asserts.assertions.expected = [
|
||||||
|
''In 'my-vol-2' config. Volume.VolumeName: 'some-other-volume-name' does not match expected type: value "my-vol-2" (singular enum)''
|
||||||
|
];
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
configPath=home-files/.config/systemd/user
|
||||||
|
volumeFile=$configPath/podman-my-vol-volume.service
|
||||||
|
assertFileExists $volumeFile
|
||||||
|
|
||||||
|
volumeFile=$(normalizeStorePaths $volumeFile)
|
||||||
|
|
||||||
|
assertFileContent $volumeFile ${./volume-expected.service}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
test.asserts.assertions.expected = [
|
|
||||||
''In 'my-vol-2' config. Volume.VolumeName: 'some-other-volume-name' does not match expected type: value "my-vol-2" (singular enum)''
|
|
||||||
];
|
|
||||||
|
|
||||||
nmt.script = ''
|
|
||||||
configPath=home-files/.config/systemd/user
|
|
||||||
volumeFile=$configPath/podman-my-vol-volume.service
|
|
||||||
assertFileExists $volumeFile
|
|
||||||
|
|
||||||
volumeFile=$(normalizeStorePaths $volumeFile)
|
|
||||||
|
|
||||||
assertFileContent $volumeFile ${./volume-expected.service}
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user