atagen

vineyard

public
Star0
Watch0
25d14e49ab6861630869e2129d40652900bc5833
1
ssh://brewery@pls.lobotomise.me:33/atagen/vineyard.git
nix/module.nixNix128 lines4.0 KB
1
self: { config, lib, pkgs, ... }:
2
let
3
  cfg = config.services.vineyard;
4
  toml = pkgs.formats.toml { };
5
  peerToml = peer: {
6
    url = peer.url;
7
    query_limit = peer.queryLimit;
8
  } // lib.optionalAttrs (peer.rescanFrom != null) {
9
    rescan_from = peer.rescanFrom;
10
  };
11
  configFile = toml.generate "vineyard.toml" {
12
    listen = cfg.listen;
13
    public_url = cfg.publicUrl;
14
    database = "/var/lib/vineyard/events.sqlite";
15
    forge_pubkeys = cfg.forgePubkeys;
16
    peers = map peerToml cfg.peers;
17
    allow_private_discovery = cfg.allowPrivateDiscovery;
18
    limits = cfg.limits;
19
  };
20
  port = lib.strings.toIntBase10 (lib.last (lib.splitString ":" cfg.listen));
21
in
22
{
23
  options.services.vineyard = {
24
    enable = lib.mkEnableOption "vineyard";
25
    package = lib.mkOption {
26
      type = lib.types.package;
27
      default = self.packages.${pkgs.stdenv.hostPlatform.system}.default;
28
      description = "vineyard package to run";
29
    };
30
    listen = lib.mkOption {
31
      type = lib.types.str;
32
      default = "127.0.0.1:7777";
33
      description = "address and port for vineyard to listen on";
34
    };
35
    publicUrl = lib.mkOption {
36
      type = lib.types.str;
37
      default = "";
38
      description = "public websocket url for vineyard";
39
    };
40
    forgePubkeys = lib.mkOption {
41
      type = lib.types.listOf lib.types.str;
42
      default = [ ];
43
      description = "locally hosted forge public keys in hex";
44
    };
45
    peers = lib.mkOption {
46
      type = lib.types.listOf (lib.types.submodule {
47
        options = {
48
          url = lib.mkOption {
49
            type = lib.types.str;
50
            description = "peer relay url";
51
          };
52
          queryLimit = lib.mkOption {
53
            type = lib.types.ints.positive;
54
            default = 500;
55
            description = "peer query limit";
56
          };
57
          rescanFrom = lib.mkOption {
58
            type = lib.types.nullOr lib.types.ints.unsigned;
59
            default = null;
60
            description = "peer rescan timestamp";
61
          };
62
        };
63
      });
64
      default = [ ];
65
      description = "peer relays for event exchange";
66
    };
67
    allowPrivateDiscovery = lib.mkOption {
68
      type = lib.types.bool;
69
      default = false;
70
      description = "allow discovered relays on private networks";
71
    };
72
    limits = lib.mkOption {
73
      type = lib.types.attrsOf lib.types.int;
74
      default = { };
75
      description = "relay limit overrides";
76
    };
77
    openFirewall = lib.mkOption {
78
      type = lib.types.bool;
79
      default = false;
80
      description = "open firewall for listen port";
81
    };
82
  };
83
  config = lib.mkIf cfg.enable {
84
    assertions = [
85
      {
86
        assertion = cfg.publicUrl != "";
87
        message = "publicUrl must be set";
88
      }
89
      {
90
        assertion = cfg.forgePubkeys != [ ];
91
        message = "forgePubkeys must not be empty";
92
      }
93
    ];
94
    networking.firewall.allowedTCPPorts = lib.optionals cfg.openFirewall [ port ];
95
    systemd.services.vineyard = {
96
      description = "vineyard nostr relay";
97
      wantedBy = [ "multi-user.target" ];
98
      after = [ "network-online.target" ];
99
      wants = [ "network-online.target" ];
100
      serviceConfig = {
101
        ExecStartPre = "${cfg.package}/bin/vineyard check-config --config ${configFile}";
102
        ExecStart = "${cfg.package}/bin/vineyard serve --config ${configFile}";
103
        DynamicUser = true;
104
        StateDirectory = "vineyard";
105
        StateDirectoryMode = "0700";
106
        WorkingDirectory = "/var/lib/vineyard";
107
        UMask = "0077";
108
        Restart = "on-failure";
109
        RestartSec = "5";
110
        NoNewPrivileges = true;
111
        ProtectSystem = "strict";
112
        ProtectHome = true;
113
        PrivateTmp = true;
114
        PrivateDevices = true;
115
        ProtectKernelTunables = true;
116
        ProtectKernelModules = true;
117
        ProtectControlGroups = true;
118
        RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ];
119
        RestrictNamespaces = true;
120
        LockPersonality = true;
121
        RestrictRealtime = true;
122
        RestrictSUIDSGID = true;
123
        RemoveIPC = true;
124
        CapabilityBoundingSet = "";
125
      };
126
    };
127
  };
128
}