{ config, lib, pkgs, ... }: with lib; let cfg = config.services.bar; in { options.services.bar = { enable = mkEnableOption "the Bar Inventory System"; user = mkOption { type = types.str; default = "bar"; description = "User to execute the daemon under"; }; group = mkOption { type = types.str; default = "bar"; description = "Group to execute the daemon under"; }; stateDir = mkOption { type = types.path; default = "/var/lib/bar"; description = "Directory for the daemon to store semi-transient state (encryption keys etc.)"; }; port = mkOption { type = types.int; default = 8080; description = "Port for the daemon to listen on"; }; host = mkOption { type = types.str; default = "localhost"; description = "Host to bind to"; }; approot = mkOption { type = types.str; default = "/"; description = "Subdirectory of the daemon-managed site relative to HTTP /; only useful when using a reverse proxy"; }; ipFromHeader = mkOption { type = types.bool; default = false; description = "Determine IP from a HTTP header"; }; thermoprintBaseURL = mkOption { type = with types; nullOr types.str; default = null; example = "http://localhost:80/thermoprint/api"; description = "Thermoprint base url"; }; postgresql = { user = mkOption { type = types.str; default = cfg.user; }; host = mkOption { type = types.str; default = "/tmp"; }; port = mkOption { type = types.int; default = 5432; }; database = mkOption { type = types.str; default = cfg.user; }; poolsize = mkOption { type = types.int; default = 10; }; }; }; imports = [ ./thermoprint-service.nix ]; config = mkIf cfg.enable { assertions = [ { assertion = config.services.postgresql.enable; message = "bar requires PostgreSQL"; } ]; nixpkgs.config.allowUnfree = true; packages.thermoprint.enable = cfg.thermoprintBaseURL != null; users.users."${cfg.user}" = { group = cfg.group; description = "User for the Bar Inventory System"; isSystemUser = true; home = cfg.stateDir; createHome = true; }; users.groups."${cfg.group}" = {}; nixpkgs.overlays = [(selfPkgs: superPkgs: { haskell = superPkgs.haskell // { packages = superPkgs.haskell.packages // { ghc844 = superPkgs.haskell.packages.ghc844.extend (selfH: superH: { bar = superPkgs.callPackage ./bar { haskellPackages = selfH // { thermoprint-client = if (cfg.thermoprintBaseURL != null) then selfH.thermoprint-client else null; }; }; }); }; }; inherit (selfPkgs.haskell.packages.ghc844) bar; })]; systemd.services."bar" = { environment = { PORT = toString cfg.port; HOST = cfg.host; APPROOT = cfg.approot; IP_FROM_HEADER = if cfg.ipFromHeader then "True" else "False"; TPRINT_BASEURL = mkIf (cfg.thermoprintBaseURL != null) cfg.thermoprintBaseURL; PGUSER = cfg.postgresql.user; PGHOST = cfg.postgresql.host; PGPORT = toString cfg.postgresql.port; PGDATABASE = cfg.postgresql.database; PGPOOLSIZE = toString cfg.postgresql.poolsize; }; bindsTo = [ "postgresql.service" ]; after = [ "postgresql.service" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "notify"; User = cfg.user; Group = cfg.group; WorkingDirectory = cfg.stateDir; ExecStart = "${pkgs.bar}/bin/bar"; }; }; }; }