1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-08 19:46:05 +01:00
home-manager/modules/services/lorri.nix
Jairo Llopis 80437a57ca lorri: don't start until daemon is really running
Sometimes a race condition will make the events stream start after the
daemon is running, and then no events will be streamed.

This fixes the problem by checking the daemon status and failing the
unit if not ready yet. It will restart 5 seconds later, which will
probably be enough.

@moduon MT-1075
2025-10-25 21:21:03 -05:00

154 lines
4 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.lorri;
in
{
meta.maintainers = [
lib.maintainers.gerschtli
lib.maintainers.nyarly
];
options.services.lorri = {
enable = lib.mkEnableOption "lorri build daemon";
enableNotifications = lib.mkEnableOption "lorri build notifications";
package = lib.mkPackageOption pkgs "lorri" { };
nixPackage = lib.mkOption {
type = lib.types.package;
default = pkgs.nix;
defaultText = lib.literalExpression "pkgs.nix";
example = lib.literalExpression "pkgs.nixVersions.unstable";
description = "Which nix package to use.";
};
};
config = lib.mkIf cfg.enable {
assertions = [
(lib.hm.assertions.assertPlatform "services.lorri" pkgs lib.platforms.linux)
];
home.packages = [ cfg.package ];
systemd.user = {
services.lorri = {
Unit = {
Description = "lorri build daemon";
Requires = "lorri.socket";
After = "lorri.socket";
RefuseManualStart = true;
};
Service = {
ExecStart = "${cfg.package}/bin/lorri daemon";
PrivateTmp = true;
ProtectSystem = "strict";
ProtectHome = "read-only";
ReadWritePaths = [
# /run/user/1000 for the socket
"%t"
# Needs to update own cache
"%C/lorri"
# Needs %C/nix/fetcher-cache-v1.sqlite
"%C/nix"
];
CacheDirectory = [ "lorri" ];
Restart = "on-failure";
Environment =
let
path =
with pkgs;
lib.makeSearchPath "bin" [
cfg.nixPackage
gitMinimal
gnutar
gzip
];
in
[ "PATH=${path}" ];
};
};
sockets.lorri = {
Unit = {
Description = "Socket for lorri build daemon";
};
Socket = {
ListenStream = "%t/lorri/daemon.socket";
RuntimeDirectory = "lorri";
};
Install = {
WantedBy = [ "sockets.target" ];
};
};
services.lorri-notify = lib.mkIf cfg.enableNotifications {
Unit = {
Description = "lorri build notifications";
After = "lorri.service";
Requires = "lorri.service";
};
Service = {
# Don't start until lorri daemon is actually running
ExecStartPre = pkgs.writeShellScript "lorri-notify-check" ''
lorri info --shell-file . | grep 'Lorri Daemon Status:.*running'
'';
RestartSec = "5s";
ExecStart =
let
jqFile = ''
(
(.Started? | values | ["Build starting", .nix_file, "emblem-synchronizing"]),
(.Completed? | values | ["Build complete", .nix_file, "checkmark"]),
(.Failure? | values | ["Build failed", .nix_file, "dialog-error"])
)
| @tsv
'';
notifyScript = pkgs.writeShellScript "lorri-notify" ''
set -o pipefail
lorri internal stream-events --kind live \
| jq --unbuffered -r '${jqFile}' \
| while IFS=$'\t' read -r status nixFile icon; do
notify-send --app-name "Lorri" --hint=int:transient:1 \
--icon "$icon" "$status" "$nixFile"
done
'';
in
toString notifyScript;
Restart = "on-failure";
Environment =
let
path = lib.makeSearchPath "bin" (
with pkgs;
[
bash
gnugrep
jq
libnotify
cfg.package
]
);
in
"PATH=${path}";
};
Install = {
WantedBy = [ "lorri.service" ];
};
};
};
};
}