alpha
Login
or
Join now
lass.pds.lassul.us
/
superconfig
Star
0
Fork
1
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
This repository has no description
Star
0
Fork
1
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
1
Pipelines
3modules.parley: init
author
lassulus
date
3 weeks ago
(Sep 28, 2026, 4:51 PM CEST)
commit
765d2884
765d2884aabbcd01b28d3d2262d00dd3f46fc6df
parent
81ca9911
81ca99113806728ff9b7329b06a9ae5b23ccb2a7
+142
2 changed files
Expand all
Collapse all
Unified
Split
3modules
default.nix
parley.nix
+1
3modules/default.nix
View file
Reviewed
···
4
4
./screenlock.nix
5
5
./fetchWallpaper.nix
6
6
./sync-containers3.nix
7
7
+
./parley.nix
7
8
];
8
9
}
+141
3modules/parley.nix
View file
Reviewed
···
1
1
+
{
2
2
+
self,
3
3
+
config,
4
4
+
lib,
5
5
+
pkgs,
6
6
+
...
7
7
+
}:
8
8
+
let
9
9
+
cfg = config.lass.parley;
10
10
+
generators = config.clan.core.vars.generators;
11
11
+
in
12
12
+
{
13
13
+
options.lass.parley = {
14
14
+
enable = lib.mkEnableOption "parley, federated chat that speaks plain IRC";
15
15
+
16
16
+
package = lib.mkOption {
17
17
+
type = lib.types.package;
18
18
+
default = self.packages.${pkgs.stdenv.hostPlatform.system}.parley;
19
19
+
};
20
20
+
21
21
+
settings = lib.mkOption {
22
22
+
type = lib.types.attrsOf lib.types.str;
23
23
+
default = { };
24
24
+
example = {
25
25
+
PARLEY_DOMAIN = "example.com";
26
26
+
PARLEY_ENDPOINT = "https://chat.example.com";
27
27
+
};
28
28
+
description = "PARLEY_* environment variables for parleyd (upstream README, Configuration).";
29
29
+
};
30
30
+
31
31
+
users = lib.mkOption {
32
32
+
default = { };
33
33
+
description = ''
34
34
+
Local accounts. Each gets a generated password
35
35
+
(`clan vars get <machine> parley-user-<nick>/password`); after every
36
36
+
start the account is created, or reset to its declared role and
37
37
+
password. Accounts not listed here are left alone.
38
38
+
'';
39
39
+
type = lib.types.attrsOf (
40
40
+
lib.types.submodule {
41
41
+
options.role = lib.mkOption {
42
42
+
type = lib.types.enum [
43
43
+
"admin"
44
44
+
"user"
45
45
+
"bot"
46
46
+
];
47
47
+
default = "user";
48
48
+
};
49
49
+
}
50
50
+
);
51
51
+
};
52
52
+
};
53
53
+
54
54
+
config = lib.mkIf cfg.enable {
55
55
+
lass.parley.settings = {
56
56
+
PARLEY_DATA_DIR = "/var/lib/parley";
57
57
+
PARLEY_IRC_LISTEN = lib.mkDefault "127.0.0.1:6667";
58
58
+
PARLEY_HTTP_LISTEN = lib.mkDefault "127.0.0.1:8443";
59
59
+
};
60
60
+
61
61
+
clan.core.vars.generators = {
62
62
+
parley = {
63
63
+
# The instance key is the domain's identity: peers cache its public
64
64
+
# half, so regenerating it is a key rotation every peer has to re-learn.
65
65
+
files."identity.key" = { };
66
66
+
files."env" = { };
67
67
+
runtimeInputs = [ pkgs.openssl ];
68
68
+
script = ''
69
69
+
# parley's key format: base64 of a 32-byte ed25519 seed
70
70
+
openssl rand -base64 32 > "$out/identity.key"
71
71
+
echo "PARLEY_ADMIN_TOKEN=$(openssl rand -hex 32)" > "$out/env"
72
72
+
'';
73
73
+
};
74
74
+
}
75
75
+
// lib.mapAttrs' (
76
76
+
nick: _:
77
77
+
lib.nameValuePair "parley-user-${nick}" {
78
78
+
files."password" = { };
79
79
+
runtimeInputs = [ pkgs.openssl ];
80
80
+
script = ''
81
81
+
openssl rand -hex 24 > "$out/password"
82
82
+
'';
83
83
+
}
84
84
+
) cfg.users;
85
85
+
86
86
+
users.users.parley = {
87
87
+
isSystemUser = true;
88
88
+
group = "parley";
89
89
+
};
90
90
+
users.groups.parley = { };
91
91
+
92
92
+
environment.systemPackages = [ cfg.package ];
93
93
+
94
94
+
systemd.services.parley = {
95
95
+
wantedBy = [ "multi-user.target" ];
96
96
+
after = [ "network-online.target" ];
97
97
+
wants = [ "network-online.target" ];
98
98
+
environment = cfg.settings;
99
99
+
path = [
100
100
+
cfg.package
101
101
+
pkgs.curl
102
102
+
];
103
103
+
preStart = ''
104
104
+
install -m 0600 "$CREDENTIALS_DIRECTORY/identity.key" identity.key
105
105
+
'';
106
106
+
postStart = lib.optionalString (cfg.users != { }) ''
107
107
+
export PARLEY_ENDPOINT=http://$PARLEY_HTTP_LISTEN
108
108
+
until curl -fs -o /dev/null "$PARLEY_ENDPOINT/healthz"; do sleep 1; done
109
109
+
${lib.concatStrings (
110
110
+
lib.mapAttrsToList (nick: user: ''
111
111
+
pw="$CREDENTIALS_DIRECTORY/user-${nick}"
112
112
+
parleyctl accounts update ${nick} -role ${user.role} -password-stdin < "$pw" > /dev/null \
113
113
+
|| parleyctl accounts create ${nick} -role ${user.role} -password-stdin < "$pw" > /dev/null
114
114
+
'') cfg.users
115
115
+
)}
116
116
+
'';
117
117
+
serviceConfig = {
118
118
+
ExecStart = lib.getExe' cfg.package "parleyd";
119
119
+
User = "parley";
120
120
+
Group = "parley";
121
121
+
StateDirectory = "parley";
122
122
+
StateDirectoryMode = "0700";
123
123
+
WorkingDirectory = "/var/lib/parley";
124
124
+
UMask = "0077";
125
125
+
EnvironmentFile = generators.parley.files."env".path;
126
126
+
LoadCredential = [
127
127
+
"identity.key:${generators.parley.files."identity.key".path}"
128
128
+
]
129
129
+
++ lib.mapAttrsToList (
130
130
+
nick: _: "user-${nick}:${generators."parley-user-${nick}".files."password".path}"
131
131
+
) cfg.users;
132
132
+
Restart = "on-failure";
133
133
+
NoNewPrivileges = true;
134
134
+
ProtectSystem = "strict";
135
135
+
ProtectHome = true;
136
136
+
PrivateTmp = true;
137
137
+
PrivateDevices = true;
138
138
+
};
139
139
+
};
140
140
+
};
141
141
+
}