modules/laminar.nix (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | { config , lib , pkgs , ... }: let cfg = config.services.laminar; inherit (lib) mkEnableOption mkPackageOption mkOption mkIf optionalAttrs types; in { options.services.laminar = { enable = mkEnableOption "Lightweight and modular Continuous Integration service for Linux."; user = mkOption { type = types.str; default = "laminar"; description = "User account under which laminar runs."; }; group = mkOption { type = types.str; default = "laminar"; description = "User account under which laminar runs."; }; package = mkPackageOption pkgs "laminar" { }; homeDir = mkOption { type = types.path; default = "/var/lib/laminar"; description = "Home directory for laminar user."; }; settings = mkOption { default = { }; description = '' Configuration for laminar. See https://laminar.ohwg.net/docs.html#Service-configuration-file ''; type = types.submodule { options = { bindHTTP = mkOption { type = types.str; default = "*:8080"; description = "The interface/port or unix socket on which laminard should listen for incoming connections to the web frontend."; }; bindRPC = mkOption { type = types.str; default = "unix-abstract:laminar"; description = "The interface/port or unix socket on which laminard should listen for incoming commands such as build triggers."; }; title = mkOption { type = types.str; default = ""; description = "The page title to show in the web frontend."; }; keepRundirs = mkOption { type = types.int; default = 0; description = "Set to an integer defining how many rundirs to keep per job. The lowest-numbered ones will be deleted."; }; baseURL = mkOption { type = types.str; default = "/"; description = "Base url for the frontend."; }; archiveURL = mkOption { type = with types; nullOr str; default = null; example = "http://localhost:8080"; description = "If set, the web frontend served by laminard will use this URL to form links to artefacts archived jobs."; }; }; }; }; }; config = mkIf cfg.enable { systemd.services.laminar = { description = "Laminar continuous integration service"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { User = cfg.user; Group = cfg.group; ExecStart = "${cfg.package}/bin/laminard -v"; EnvironmentFile = pkgs.writeText "laminar.conf" '' LAMINAR_HOME=${cfg.homeDir} LAMINAR_BIND_HTTP=${cfg.settings.bindHTTP} LAMINAR_BIND_RPC=${cfg.settings.bindRPC} LAMINAR_TITLE=${cfg.settings.title} LAMINAR_KEEP_RUNDIRS=${toString cfg.settings.keepRundirs} LAMINAR_BASE_URL=${cfg.settings.baseURL} ${lib.optionalString (cfg.settings.archiveURL != null) "LAMINAR_ARCHIVE_URL=${cfg.settings.archiveURL}" } ''; }; unitConfig = { Documentation = [ "man:laminard(8)" "https://laminar.ohwg.net/docs.html" ]; }; }; environment.systemPackages = [ pkgs.laminar ]; users.users = optionalAttrs (cfg.user == "laminar") { laminar = { inherit (cfg) group; home = cfg.homeDir; createHome = true; isSystemUser = true; }; }; users.groups = optionalAttrs (cfg.group == "laminar") { laminar = { }; }; }; } |