1{
2 options,
3 config,
4 pkgs,
5 lib,
6 ...
7}:
8let
9 opt = options.services.rkvm;
10 cfg = config.services.rkvm;
11 toml = pkgs.formats.toml { };
12in
13{
14 meta.maintainers = [ ];
15
16 options.services.rkvm = {
17 enable = lib.mkOption {
18 default = cfg.server.enable || cfg.client.enable;
19 defaultText = lib.literalExpression "config.${opt.server.enable} || config.${opt.client.enable}";
20 type = lib.types.bool;
21 description = ''
22 Whether to enable rkvm, a Virtual KVM switch for Linux machines.
23 '';
24 };
25
26 package = lib.mkPackageOption pkgs "rkvm" { };
27
28 server = {
29 enable = lib.mkEnableOption "the rkvm server daemon (input transmitter)";
30
31 settings = lib.mkOption {
32 type = lib.types.submodule {
33 freeformType = toml.type;
34 options = {
35 listen = lib.mkOption {
36 type = lib.types.str;
37 default = "0.0.0.0:5258";
38 description = ''
39 An internet socket address to listen on, either IPv4 or IPv6.
40 '';
41 };
42
43 switch-keys = lib.mkOption {
44 type = lib.types.listOf lib.types.str;
45 default = [
46 "left-alt"
47 "left-ctrl"
48 ];
49 description = ''
50 A key list specifying a host switch combination.
51
52 _A list of key names is available in <https://github.com/htrefil/rkvm/blob/master/switch-keys.md>._
53 '';
54 };
55
56 certificate = lib.mkOption {
57 type = lib.types.path;
58 default = "/etc/rkvm/certificate.pem";
59 description = ''
60 TLS certificate path.
61
62 ::: {.note}
63 This should be generated with {command}`rkvm-certificate-gen`.
64 :::
65 '';
66 };
67
68 key = lib.mkOption {
69 type = lib.types.path;
70 default = "/etc/rkvm/key.pem";
71 description = ''
72 TLS key path.
73
74 ::: {.note}
75 This should be generated with {command}`rkvm-certificate-gen`.
76 :::
77 '';
78 };
79
80 password = lib.mkOption {
81 type = lib.types.str;
82 description = ''
83 Shared secret token to authenticate the client.
84 Make sure this matches your client's config.
85 '';
86 };
87 };
88 };
89
90 default = { };
91 description = "Structured server daemon configuration";
92 };
93 };
94
95 client = {
96 enable = lib.mkEnableOption "the rkvm client daemon (input receiver)";
97
98 settings = lib.mkOption {
99 type = lib.types.submodule {
100 freeformType = toml.type;
101 options = {
102 server = lib.mkOption {
103 type = lib.types.str;
104 example = "192.168.0.123:5258";
105 description = ''
106 An RKVM server's internet socket address, either IPv4 or IPv6.
107 '';
108 };
109
110 certificate = lib.mkOption {
111 type = lib.types.path;
112 default = "/etc/rkvm/certificate.pem";
113 description = ''
114 TLS ceritficate path.
115
116 ::: {.note}
117 This should be generated with {command}`rkvm-certificate-gen`.
118 :::
119 '';
120 };
121
122 password = lib.mkOption {
123 type = lib.types.str;
124 description = ''
125 Shared secret token to authenticate the client.
126 Make sure this matches your server's config.
127 '';
128 };
129 };
130 };
131
132 default = { };
133 description = "Structured client daemon configuration";
134 };
135 };
136
137 };
138
139 config = lib.mkIf cfg.enable {
140 environment.systemPackages = [ cfg.package ];
141
142 systemd.services =
143 let
144 mkBase = component: {
145 description = "RKVM ${component}";
146 wantedBy = [ "multi-user.target" ];
147 after =
148 {
149 server = [ "network.target" ];
150 client = [ "network-online.target" ];
151 }
152 .${component};
153 wants =
154 {
155 server = [ ];
156 client = [ "network-online.target" ];
157 }
158 .${component};
159 serviceConfig = {
160 ExecStart = "${cfg.package}/bin/rkvm-${component} ${
161 toml.generate "rkvm-${component}.toml" cfg.${component}.settings
162 }";
163 Restart = "always";
164 RestartSec = 5;
165 Type = "simple";
166 };
167 };
168 in
169 {
170 rkvm-server = lib.mkIf cfg.server.enable (mkBase "server");
171 rkvm-client = lib.mkIf cfg.client.enable (mkBase "client");
172 };
173 };
174
175}