mirror of
https://github.com/foo-dogsquared/nixos-config.git
synced 2025-04-25 12:19:12 +00:00
nixos/programs/sessiond: init
This commit is contained in:
parent
d1dc2953c7
commit
1d3bc3c013
@ -5,6 +5,7 @@
|
|||||||
./programs/distrobox.nix
|
./programs/distrobox.nix
|
||||||
./programs/gnome-session
|
./programs/gnome-session
|
||||||
./programs/pop-launcher.nix
|
./programs/pop-launcher.nix
|
||||||
|
./programs/sessiond
|
||||||
./programs/wezterm.nix
|
./programs/wezterm.nix
|
||||||
./services/archivebox.nix
|
./services/archivebox.nix
|
||||||
./services/gallery-dl.nix
|
./services/gallery-dl.nix
|
||||||
|
124
modules/nixos/programs/sessiond/default.nix
Normal file
124
modules/nixos/programs/sessiond/default.nix
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
{ config, lib, pkgs, utils, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.programs.sessiond;
|
||||||
|
|
||||||
|
sessionPackages = lib.mapAttrsToList
|
||||||
|
(name: session:
|
||||||
|
let
|
||||||
|
displaySession = ''
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=${session.fullName}
|
||||||
|
Comment=${session.description}
|
||||||
|
Exec="@out@/libexec/${name}-session"
|
||||||
|
Type=Application
|
||||||
|
DesktopNames=${lib.concatStringsSep ";" session.desktopNames};
|
||||||
|
'';
|
||||||
|
|
||||||
|
sessionScript = ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
|
||||||
|
${lib.getExe' cfg.package "sessionctl"} run "${name}.target"
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
pkgs.runCommandLocal "${name}-desktop-session-files"
|
||||||
|
{
|
||||||
|
inherit displaySession sessionScript;
|
||||||
|
passAsFile = [ "displaySession" "sessionScript" ];
|
||||||
|
passthru.providedSessions = [ name ];
|
||||||
|
}
|
||||||
|
''
|
||||||
|
SESSION_SCRIPT="$out/libexec/${name}-session"
|
||||||
|
install -Dm0755 "$sessionScriptPath" "$SESSION_SCRIPT"
|
||||||
|
substituteAllInPlace "$SESSION_SCRIPT"
|
||||||
|
|
||||||
|
DISPLAY_SESSION_FILE="$out/share/xsessions/${name}.desktop"
|
||||||
|
install -Dm0644 "$displaySessionPath" "$DISPLAY_SESSION_FILE"
|
||||||
|
substituteAllInPlace "$DISPLAY_SESSION_FILE"
|
||||||
|
''
|
||||||
|
)
|
||||||
|
cfg.sessions;
|
||||||
|
|
||||||
|
sessionSystemdUnits = lib.mapAttrsToList
|
||||||
|
(name: session:
|
||||||
|
let
|
||||||
|
inherit (utils.systemdUtils.lib)
|
||||||
|
pathToUnit serviceToUnit targetToUnit timerToUnit socketToUnit;
|
||||||
|
|
||||||
|
sessionComponents =
|
||||||
|
lib.foldlAttrs
|
||||||
|
(acc: name: component:
|
||||||
|
acc // {
|
||||||
|
"${component.id}.service" = serviceToUnit component.id component.serviceUnit;
|
||||||
|
"${component.id}.target" = targetToUnit component.id component.targetUnit;
|
||||||
|
} // lib.optionalAttrs (component.socketUnit != null) {
|
||||||
|
"${component.id}.socket" = socketToUnit component.id component.socketUnit;
|
||||||
|
} // lib.optionalAttrs (component.timerUnit != null) {
|
||||||
|
"${component.id}.timer" = timerToUnit component.id component.timerUnit;
|
||||||
|
} // lib.optionalAttrs (component.pathUnit != null) {
|
||||||
|
"${component.id}.path" = pathToUnit component.id component.pathUnit;
|
||||||
|
})
|
||||||
|
{ }
|
||||||
|
session.components;
|
||||||
|
in
|
||||||
|
sessionComponents // {
|
||||||
|
"${name}.service" = serviceToUnit name session.serviceUnit;
|
||||||
|
"${name}.target" = targetToUnit name session.targetUnit;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
cfg.sessions;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.programs.sessiond = {
|
||||||
|
package = lib.mkOption {
|
||||||
|
type = lib.types.package;
|
||||||
|
default = pkgs.sessiond;
|
||||||
|
defaultText = "pkgs.sessiond";
|
||||||
|
description = ''
|
||||||
|
The package containing sessiond executable and systemd units. This
|
||||||
|
module will use the `sessiond` executable for the generated session
|
||||||
|
script.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
sessions = lib.mkOption {
|
||||||
|
type = with lib.types; attrsOf (submoduleWith {
|
||||||
|
specialArgs = {
|
||||||
|
inherit utils pkgs;
|
||||||
|
sessiondPkg = cfg.package;
|
||||||
|
};
|
||||||
|
modules = [ ./submodules/session-type.nix ];
|
||||||
|
});
|
||||||
|
description = ''
|
||||||
|
A set of desktop sessions to be configured with sessiond. Each of the
|
||||||
|
attribute name will be used as the identifier of the desktop
|
||||||
|
environment.
|
||||||
|
|
||||||
|
::: {.tip}
|
||||||
|
While you can make identifiers in any way, it is
|
||||||
|
encouraged to stick to a naming scheme. Here's two common ways to name
|
||||||
|
a desktop environment.
|
||||||
|
|
||||||
|
* Reverse DNS-like scheme (e.g., `com.example.MoseyBranch`).
|
||||||
|
* Kebab-case (e.g., `mosey-branch`).
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf (cfg.sessions != { }) {
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
|
# Install all of the desktop session files.
|
||||||
|
services.xserver.displayManager.sessionPackages = sessionPackages;
|
||||||
|
|
||||||
|
# Import those systemd units from sessiond as well.
|
||||||
|
systemd.packages = [ cfg.package ];
|
||||||
|
systemd.user.units = lib.mkMerge sessionSystemdUnits;
|
||||||
|
|
||||||
|
# We're disabling the upstream sessiond service since there can be multiple
|
||||||
|
# sessiond sessions here.
|
||||||
|
systemd.user.services.sessiond.enable = false;
|
||||||
|
};
|
||||||
|
}
|
228
modules/nixos/programs/sessiond/submodules/component-type.nix
Normal file
228
modules/nixos/programs/sessiond/submodules/component-type.nix
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
{ name, config, lib, session, utils, ... }: {
|
||||||
|
options = {
|
||||||
|
description = lib.mkOption {
|
||||||
|
type = lib.types.nonEmptyStr;
|
||||||
|
description = "One-sentence description of the component.";
|
||||||
|
example = "Desktop widgets";
|
||||||
|
};
|
||||||
|
|
||||||
|
# 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`.
|
||||||
|
|
||||||
|
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 with the service unit. You should configure `targetUnit` for
|
||||||
|
that instead.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
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 is generated by default alongside the service where it is
|
||||||
|
configured to be a part of the target unit.
|
||||||
|
|
||||||
|
This has the same options as {option}`systemd.user.targets.<name>`
|
||||||
|
but without certain options from stage 2 counterparts such as
|
||||||
|
`reloadTriggers` and `restartTriggers`.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
timerUnit = lib.mkOption {
|
||||||
|
type =
|
||||||
|
let
|
||||||
|
inherit (utils.systemdUtils.unitOptions) timerOptions commonUnitOptions;
|
||||||
|
inherit (utils.systemdUtils.lib) unitConfig;
|
||||||
|
in
|
||||||
|
with lib.types; nullOr (submodule [
|
||||||
|
commonUnitOptions
|
||||||
|
timerOptions
|
||||||
|
unitConfig
|
||||||
|
]);
|
||||||
|
description = ''
|
||||||
|
An optional systemd timer 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.timers.<name>`
|
||||||
|
but without certain options from stage 2 counterparts such as
|
||||||
|
`reloadTriggers` and `restartTriggers`.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
socketUnit = lib.mkOption {
|
||||||
|
type =
|
||||||
|
let
|
||||||
|
inherit (utils.systemdUtils.unitOptions) socketOptions commonUnitOptions;
|
||||||
|
inherit (utils.systemdUtils.lib) unitConfig;
|
||||||
|
in
|
||||||
|
with lib.types; nullOr (submodule [
|
||||||
|
commonUnitOptions
|
||||||
|
socketOptions
|
||||||
|
unitConfig
|
||||||
|
]);
|
||||||
|
description = ''
|
||||||
|
An optional systemd socket 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.sockets.<name>`
|
||||||
|
but without certain options from stage 2 counterparts such as
|
||||||
|
`reloadTriggers` and `restartTriggers`.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
pathUnit = lib.mkOption {
|
||||||
|
type =
|
||||||
|
let
|
||||||
|
inherit (utils.systemdUtils.unitOptions) pathOptions commonUnitOptions;
|
||||||
|
inherit (utils.systemdUtils.lib) unitConfig;
|
||||||
|
in
|
||||||
|
with lib.types; nullOr (submodule [
|
||||||
|
commonUnitOptions
|
||||||
|
pathOptions
|
||||||
|
unitConfig
|
||||||
|
]);
|
||||||
|
description = ''
|
||||||
|
An optional systemd path 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.paths.<name>`
|
||||||
|
but without certain options from stage 2 counterparts such as
|
||||||
|
`reloadTriggers` and `restartTriggers`.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
id = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = ''
|
||||||
|
The identifier of the component used in generating filenames for its
|
||||||
|
`.desktop` files and as part of systemd unit names.
|
||||||
|
'';
|
||||||
|
default = "${session.name}.${name}";
|
||||||
|
defaultText = "\${session-name}.\${name}";
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
/*
|
||||||
|
Setting some recommendation and requirements for sessiond components.
|
||||||
|
Note there are the missing directives that COULD include some sane
|
||||||
|
defaults here.
|
||||||
|
|
||||||
|
* The `Unit.OnFailure=` and `Unit.OnFailureJobMode=` directives. Since
|
||||||
|
different components don't have the same priority and don't handle
|
||||||
|
failures the same way, we didn't set it here. This is on the user to
|
||||||
|
know how different desktop components interact with each other
|
||||||
|
especially if one of them failed.
|
||||||
|
|
||||||
|
TODO: Is `Type=notify` a good default?
|
||||||
|
* `Service.Type=` is obviously not included since not all desktop
|
||||||
|
components are the same either. Some of them could a D-Bus service,
|
||||||
|
some of them are oneshots, etc. Not to mention, this is already implied
|
||||||
|
to be `Type=simple` by systemd anyways.
|
||||||
|
|
||||||
|
* `Service.OOMScoreAdjust=` have different values for different
|
||||||
|
components so it isn't included.
|
||||||
|
|
||||||
|
* Most sandboxing options. Aside from the fact we're dealing with a
|
||||||
|
systemd user unit, much of them are unnecessary and rarely needed (if
|
||||||
|
ever like `Service.PrivateTmp=`?) so we didn't set such defaults here.
|
||||||
|
|
||||||
|
As you can tell, this module does not provide a framework for the user
|
||||||
|
to easily compose their own desktop environment. THIS MODULE ALREADY
|
||||||
|
DOES A LOT, ALRIGHT! CUT ME SOME SLACK!
|
||||||
|
|
||||||
|
Take note that the default service configuration is leaning on the
|
||||||
|
desktop component being a simple type of service like how most NixOS
|
||||||
|
service modules are deployed.
|
||||||
|
*/
|
||||||
|
serviceUnit = {
|
||||||
|
description = lib.mkDefault config.description;
|
||||||
|
|
||||||
|
# The typical workflow for service units to have them set as part of
|
||||||
|
# the respective target unit.
|
||||||
|
requisite = [ "${config.id}.target" ];
|
||||||
|
before = [ "${config.id}.target" ];
|
||||||
|
partOf = [ "${config.id}.target" ];
|
||||||
|
|
||||||
|
# Some sane service configuration for a desktop component.
|
||||||
|
serviceConfig = {
|
||||||
|
Slice = lib.mkDefault "session.slice";
|
||||||
|
Restart = lib.mkDefault "on-failure";
|
||||||
|
TimeoutStopSec = lib.mkDefault 5;
|
||||||
|
};
|
||||||
|
|
||||||
|
startLimitBurst = lib.mkDefault 3;
|
||||||
|
startLimitIntervalSec = lib.mkDefault 15;
|
||||||
|
|
||||||
|
unitConfig = {
|
||||||
|
# We leave those up to the target units to start the services.
|
||||||
|
RefuseManualStart = lib.mkDefault true;
|
||||||
|
RefuseManualStop = lib.mkDefault true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Similarly, there are things that COULD make it here but didn't for a
|
||||||
|
variety of reasons.
|
||||||
|
|
||||||
|
* `Unit.PartOf=`, `Unit.Requisite=`, and the like since some components
|
||||||
|
require starting up earlier than the others. We could include it here
|
||||||
|
if we make it clear in the documentation or if it proves to be a
|
||||||
|
painful experience to configure this by a first-timer. For now, this is
|
||||||
|
on the user to know.
|
||||||
|
*/
|
||||||
|
targetUnit = {
|
||||||
|
wants = [ "${config.id}.service" ];
|
||||||
|
description = lib.mkDefault config.description;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
235
modules/nixos/programs/sessiond/submodules/session-type.nix
Normal file
235
modules/nixos/programs/sessiond/submodules/session-type.nix
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
{ name, config, pkgs, lib, utils, sessiondPkg, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
# For an updated list, see `menu/menu-spec.xml` from
|
||||||
|
# https://gitlab.freedesktop.org/xdg/xdg-specs.
|
||||||
|
validDesktopNames = [
|
||||||
|
"GNOME"
|
||||||
|
"GNOME-Classic"
|
||||||
|
"GNOME-Flashback"
|
||||||
|
"KDE"
|
||||||
|
"LXDE"
|
||||||
|
"LXQt"
|
||||||
|
"MATE"
|
||||||
|
"Razor"
|
||||||
|
"ROX"
|
||||||
|
"TDE"
|
||||||
|
"Unity"
|
||||||
|
"XFCE"
|
||||||
|
"EDE"
|
||||||
|
"Cinnamon"
|
||||||
|
"Pantheon"
|
||||||
|
"Budgie"
|
||||||
|
"Enlightenment"
|
||||||
|
"DDE"
|
||||||
|
"Endless"
|
||||||
|
"Old"
|
||||||
|
];
|
||||||
|
|
||||||
|
# This is used both as the configuration format for sessiond.conf and its
|
||||||
|
# hooks.
|
||||||
|
settingsFormat = pkgs.formats.toml { };
|
||||||
|
sessionSettingsFile = settingsFormat.generate "sessiond-conf-${name}" config.settings;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
fullName = lib.mkOption {
|
||||||
|
type = lib.types.nonEmptyStr;
|
||||||
|
description = "The display name of the desktop environment.";
|
||||||
|
default = name;
|
||||||
|
example = "Mosey Branch";
|
||||||
|
};
|
||||||
|
|
||||||
|
desktopNames = lib.mkOption {
|
||||||
|
type = with lib.types; listOf nonEmptyStr;
|
||||||
|
description = ''
|
||||||
|
Names to be used as `DesktopNames=` entry of the session `.desktop`
|
||||||
|
file. Useful if you're creating a customized version of an already
|
||||||
|
existing desktop session.
|
||||||
|
|
||||||
|
::: {.note}
|
||||||
|
This module sanitizes the values by prepending the given names with
|
||||||
|
`X-` if they aren't part of the registered values from XDG spec.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
default = [ config.fullName ];
|
||||||
|
defaultText = "[ <session>.fullName ]";
|
||||||
|
apply = names:
|
||||||
|
builtins.map
|
||||||
|
(name:
|
||||||
|
if (lib.elem name validDesktopNames) || (lib.hasPrefix "X-" name) then
|
||||||
|
name
|
||||||
|
else
|
||||||
|
"X-${name}")
|
||||||
|
names;
|
||||||
|
example = [ "GNOME" "Garden" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = lib.mkOption {
|
||||||
|
type = settingsFormat.type;
|
||||||
|
default = { };
|
||||||
|
example = {
|
||||||
|
Idle = {
|
||||||
|
Inputs = [ "motion" "button-press" ];
|
||||||
|
IdleSec = 60;
|
||||||
|
};
|
||||||
|
|
||||||
|
Lock = {
|
||||||
|
OnIdle = true;
|
||||||
|
OnSleep = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
DPMS.Enable = true;
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
The settings associated with the sessiond session. For more
|
||||||
|
details, please see {manpage}`sessiond.conf(5)`. If not given, it
|
||||||
|
will use the default configuration from the compiled package.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
description = lib.mkOption {
|
||||||
|
type = lib.types.nonEmptyStr;
|
||||||
|
description = ''
|
||||||
|
A one-sentence description of the desktop environment.
|
||||||
|
'';
|
||||||
|
default = "${config.fullName} desktop environment";
|
||||||
|
defaultText = lib.literalExpression "\${<name>.fullName} desktop environment";
|
||||||
|
example = "A desktop environment featuring a scrolling compositor.";
|
||||||
|
};
|
||||||
|
|
||||||
|
components = lib.mkOption {
|
||||||
|
type = with lib.types; attrsOf (submoduleWith {
|
||||||
|
specialArgs = {
|
||||||
|
inherit utils;
|
||||||
|
session = {
|
||||||
|
inherit (config) fullName desktopNames description;
|
||||||
|
inherit name;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
modules = [ ./component-type.nix ];
|
||||||
|
});
|
||||||
|
description = ''
|
||||||
|
The individual components to be launched with the desktop session.
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
`<name>.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`.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
defaultText = ''
|
||||||
|
{
|
||||||
|
wants = ... # All of the required components as a target unit.
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
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 for the sessiond session
|
||||||
|
itself.
|
||||||
|
|
||||||
|
:::{.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`).
|
||||||
|
|
||||||
|
On a typical case, you shouldn't mess with much of the dependency
|
||||||
|
ordering with the service unit. You should configure `targetUnit` for
|
||||||
|
that instead.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraArgs = lib.mkOption {
|
||||||
|
type = with lib.types; listOf str;
|
||||||
|
description = ''
|
||||||
|
A list of arguments from {program}`sessiond` to be added for the session
|
||||||
|
script.
|
||||||
|
'';
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
[
|
||||||
|
"--hooksd=''${./config/sessiond/hooks.d}"
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Append the session argument.
|
||||||
|
config = {
|
||||||
|
extraArgs = lib.optional (config.settings != { }) "--config=${sessionSettingsFile}";
|
||||||
|
|
||||||
|
targetUnit = {
|
||||||
|
description = config.description;
|
||||||
|
requires = [ "${name}.service" ];
|
||||||
|
wants =
|
||||||
|
let
|
||||||
|
componentTargetUnits =
|
||||||
|
lib.mapAttrsToList (_: component: "${component.id}.target") config.components;
|
||||||
|
in
|
||||||
|
componentTargetUnits;
|
||||||
|
};
|
||||||
|
|
||||||
|
serviceUnit = {
|
||||||
|
description = config.description;
|
||||||
|
partOf = [ "${name}.target" ];
|
||||||
|
before = [ "${name}.target" ];
|
||||||
|
requisite = [ "${name}.target" ];
|
||||||
|
requires = [ "dbus.socket" ];
|
||||||
|
after = [ "dbus.socket" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = lib.mkForce "dbus";
|
||||||
|
BusName = lib.mkForce "org.sessiond.session1";
|
||||||
|
ExecStart = lib.mkForce "${lib.getExe' sessiondPkg "sessiond"} ${lib.concatStringsSep " " config.extraArgs}";
|
||||||
|
Restart = "always";
|
||||||
|
};
|
||||||
|
|
||||||
|
unitConfig = {
|
||||||
|
RefuseManualStart = true;
|
||||||
|
RefuseManualStop = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user