nixos/programs/gnome-session: add top-level systemd namespace for systemd-specific options

Also included a little refactor.
This commit is contained in:
Gabriel Arazas 2024-08-21 18:51:57 +08:00
parent 23b2be907f
commit 03f51384cf
No known key found for this signature in database
GPG Key ID: 62104B43D00AA360
3 changed files with 150 additions and 137 deletions

View File

@ -107,20 +107,20 @@ let
pathToUnit serviceToUnit targetToUnit timerToUnit socketToUnit;
mkSystemdUnits = name: component: {
"${component.id}.service" = serviceToUnit component.serviceUnit;
"${component.id}.target" = targetToUnit component.targetUnit;
} // lib.optionalAttrs (component.socketUnit != null) {
"${component.id}.socket" = socketToUnit component.socketUnit;
} // lib.optionalAttrs (component.timerUnit != null) {
"${component.id}.timer" = timerToUnit component.timerUnit;
} // lib.optionalAttrs (component.pathUnit != null) {
"${component.id}.path" = pathToUnit component.pathUnit;
"${component.id}.service" = serviceToUnit component.systemd.serviceUnit;
"${component.id}.target" = targetToUnit component.systemd.targetUnit;
} // lib.optionalAttrs (component.systemd.socketUnit != null) {
"${component.id}.socket" = socketToUnit component.systemd.socketUnit;
} // lib.optionalAttrs (component.systemd.timerUnit != null) {
"${component.id}.timer" = timerToUnit component.systemd.timerUnit;
} // lib.optionalAttrs (component.systemd.pathUnit != null) {
"${component.id}.path" = pathToUnit component.systemd.pathUnit;
};
componentsUnits = lib.concatMapAttrs mkSystemdUnits session.components;
in
componentsUnits // {
"gnome-session@${session.name}.target" = targetToUnit session.targetUnit;
"gnome-session@${session.name}.target" = targetToUnit session.systemd.targetUnit;
}
)
cfg.sessions;

View File

@ -1,10 +1,13 @@
{ name, config, pkgs, lib, utils, session, ... }:
let
optionalSystemdUnitOption = type: systemdModuleAttribute:
optionalSystemdUnitOption = {
unitType, systemdModuleAttribute, otherType,
}:
lib.mkOption {
type = lib.types.nullOr otherType;
description = ''
An optional systemd ${type} configuration to be generated. This should
An optional systemd ${unitType} configuration to be generated. This should
be configured if the session is managed by systemd.
:::{.note}
@ -73,106 +76,114 @@ in
};
};
# Most of the systemd config types are trying to eliminate as much of the
# NixOS systemd extensions as much as possible. For more details, see
# `config` attribute of the `sessionType`.
serviceUnit = lib.mkOption {
type =
let
inherit (utils.systemdUtils.lib) unitConfig serviceConfig;
inherit (utils.systemdUtils.unitOptions) commonUnitOptions serviceOptions;
in
lib.types.submodule [
commonUnitOptions
serviceOptions
serviceConfig
unitConfig
];
description = ''
systemd service configuration to be generated. This should be
configured if the session is managed by systemd.
systemd = {
# Most of the systemd config types are trying to eliminate as much of the
# NixOS systemd extensions as much as possible. For more details, see
# `config` attribute of the `sessionType`.
serviceUnit = lib.mkOption {
type =
let
inherit (utils.systemdUtils.lib) unitConfig serviceConfig;
inherit (utils.systemdUtils.unitOptions) commonUnitOptions serviceOptions;
in
lib.types.submodule [
commonUnitOptions
serviceOptions
serviceConfig
unitConfig
];
description = ''
systemd service configuration to be generated. This should be
configured if the session is managed by systemd.
:::{.note}
This has the same options as {option}`systemd.user.services.<name>`
but without certain options from stage 2 counterparts such as
`reloadTriggers` and `restartTriggers`.
:::{.note}
This has the same options as {option}`systemd.user.services.<name>`
but without certain options from stage 2 counterparts such as
`reloadTriggers` and `restartTriggers`.
By default, this module sets the service unit as part of the respective
target unit (i.e., `PartOf=$COMPONENTID.target`).
By default, this module sets the service unit as part of the respective
target unit (i.e., `PartOf=$COMPONENTID.target`).
On a typical case, you shouldn't mess with much of the dependency
ordering of the service unit. You should configure `targetUnit` for
that instead.
:::
'';
default = { };
visible = "shallow";
};
On a typical case, you shouldn't mess with much of the dependency
ordering of the service unit. You should configure `targetUnit` for
that instead.
:::
'';
default = { };
visible = "shallow";
};
targetUnit = lib.mkOption {
type =
let
inherit (utils.systemdUtils.lib) unitConfig;
inherit (utils.systemdUtils.unitOptions) commonUnitOptions;
in
lib.types.submodule [
commonUnitOptions
unitConfig
];
description = ''
systemd target configuration to be generated. This should be
configured if the session is managed by systemd.
targetUnit = lib.mkOption {
type =
let
inherit (utils.systemdUtils.lib) unitConfig;
inherit (utils.systemdUtils.unitOptions) commonUnitOptions;
in
lib.types.submodule [
commonUnitOptions
unitConfig
];
description = ''
systemd target configuration to be generated. This should be
configured if the session is managed by systemd.
:::{.note}
This has the same options as {option}`systemd.user.targets.<name>`
but without certain options from stage 2 counterparts such as
`reloadTriggers` and `restartTriggers`.
:::{.note}
This has the same options as {option}`systemd.user.targets.<name>`
but without certain options from stage 2 counterparts such as
`reloadTriggers` and `restartTriggers`.
This module doesn't set the typical dependency ordering relative to
gnome-session targets. This is on the user to manually set them.
:::
'';
default = { };
visible = "shallow";
};
This module doesn't set the typical dependency ordering relative to
gnome-session targets. This is on the user to manually set them.
:::
'';
default = { };
visible = "shallow";
};
timerUnit = optionalSystemdUnitOption "timer" "timers" // {
type =
let
inherit (utils.systemdUtils.unitOptions) timerOptions commonUnitOptions;
inherit (utils.systemdUtils.lib) unitConfig;
in
with lib.types; nullOr (submodule [
commonUnitOptions
timerOptions
unitConfig
]);
};
timerUnit = optionalSystemdUnitOption {
unitType = "timer";
systemdModuleAttribute = "timers";
otherType =
let
inherit (utils.systemdUtils.unitOptions) timerOptions commonUnitOptions;
inherit (utils.systemdUtils.lib) unitConfig;
in
lib.types.submodule [
commonUnitOptions
timerOptions
unitConfig
];
};
socketUnit = optionalSystemdUnitOption "socket" "sockets" // {
type =
let
inherit (utils.systemdUtils.unitOptions) socketOptions commonUnitOptions;
inherit (utils.systemdUtils.lib) unitConfig;
in
with lib.types; nullOr (submodule [
commonUnitOptions
socketOptions
unitConfig
]);
};
socketUnit = optionalSystemdUnitOption {
unitType = "socket";
systemdModuleAttribute = "sockets";
otherType =
let
inherit (utils.systemdUtils.unitOptions) socketOptions commonUnitOptions;
inherit (utils.systemdUtils.lib) unitConfig;
in
lib.types.submodule [
commonUnitOptions
socketOptions
unitConfig
];
};
pathUnit = optionalSystemdUnitOption "path" "paths" // {
type =
let
inherit (utils.systemdUtils.unitOptions) pathOptions commonUnitOptions;
inherit (utils.systemdUtils.lib) unitConfig;
in
with lib.types; nullOr (submodule [
commonUnitOptions
pathOptions
unitConfig
]);
pathUnit = optionalSystemdUnitOption {
unitType = "path";
systemdModuleAttribute = "paths";
otherType =
let
inherit (utils.systemdUtils.unitOptions) pathOptions commonUnitOptions;
inherit (utils.systemdUtils.lib) unitConfig;
in
lib.types.submodule [
commonUnitOptions
pathOptions
unitConfig
];
};
};
id = lib.mkOption {
@ -235,7 +246,7 @@ in
systemd user unit, much of them are unnecessary and rarely needed (if
ever like `Service.PrivateTmp=`?) so we didn't set such defaults here.
*/
serviceUnit = {
systemd.serviceUnit = {
script = lib.mkAfter config.script;
description = lib.mkDefault config.description;
@ -282,7 +293,7 @@ in
likely for a user to design their own desktop session with full control
so it would be better for these options to be empty for less confusion.
*/
targetUnit = {
systemd.targetUnit = {
# This should be the dependency-related directive to be configured. The
# rest is for the user to judge.
wants = [ "${config.id}.service" ];

View File

@ -184,40 +184,42 @@ in
];
};
targetUnit = lib.mkOption {
type =
let
inherit (utils.systemdUtils.lib) unitConfig;
inherit (utils.systemdUtils.unitOptions) commonUnitOptions;
in
lib.types.submodule [
commonUnitOptions
unitConfig
];
description = ''
systemd target configuration to be generated for
`gnome-session@<name>.target`. This should be configured if the
session is managed by systemd and you want to control the session
further (which is recommended since this module don't know what
components are more important, etc.).
systemd = {
targetUnit = lib.mkOption {
type =
let
inherit (utils.systemdUtils.lib) unitConfig;
inherit (utils.systemdUtils.unitOptions) commonUnitOptions;
in
lib.types.submodule [
commonUnitOptions
unitConfig
];
description = ''
systemd target configuration to be generated for
`gnome-session@<name>.target`. This should be configured if the
session is managed by systemd and you want to control the session
further (which is recommended since this module don't know what
components are more important, etc.).
By default, the session target will have all of its components from
{option}`<session>.requiredComponents` under `Wants=` directive. It
also assumes all of them have a target unit at
`''${requiredComponent}.target`.
By default, the session target will have all of its components from
{option}`<session>.requiredComponents` under `Wants=` directive. It
also assumes all of them have a target unit at
`''${requiredComponent}.target`.
:::{.note}
This has the same options as {option}`systemd.user.targets.<name>`
but without certain options from stage 2 counterparts such as
`reloadTriggers` and `restartTriggers`.
:::
'';
visible = "shallow";
defaultText = ''
{
wants = ... # All of the required components as a target unit.
}
'';
:::{.note}
This has the same options as {option}`systemd.user.targets.<name>`
but without certain options from stage 2 counterparts such as
`reloadTriggers` and `restartTriggers`.
:::
'';
visible = "shallow";
defaultText = ''
{
wants = ... # All of the required components as a target unit.
}
'';
};
};
};
@ -225,7 +227,7 @@ in
# Append the session argument.
extraArgs = [ "--session=${name}" ];
targetUnit = {
systemd.targetUnit = {
overrideStrategy = lib.mkForce "asDropin";
wants = lib.mkDefault (builtins.map (c: "${c}.target") config.requiredComponents);
};