1{ config, lib, pkgs, ... }:
2
3with lib;
4
5{
6 options = {
7
8 services.xray = {
9 enable = mkOption {
10 type = types.bool;
11 default = false;
12 description = lib.mdDoc ''
13 Whether to run xray server.
14
15 Either `settingsFile` or `settings` must be specified.
16 '';
17 };
18
19 package = mkOption {
20 type = types.package;
21 default = pkgs.xray;
22 defaultText = literalExpression "pkgs.xray";
23 description = lib.mdDoc ''
24 Which xray package to use.
25 '';
26 };
27
28 settingsFile = mkOption {
29 type = types.nullOr types.path;
30 default = null;
31 example = "/etc/xray/config.json";
32 description = lib.mdDoc ''
33 The absolute path to the configuration file.
34
35 Either `settingsFile` or `settings` must be specified.
36
37 See <https://www.v2fly.org/en_US/config/overview.html>.
38 '';
39 };
40
41 settings = mkOption {
42 type = types.nullOr (types.attrsOf types.unspecified);
43 default = null;
44 example = {
45 inbounds = [{
46 port = 1080;
47 listen = "127.0.0.1";
48 protocol = "http";
49 }];
50 outbounds = [{
51 protocol = "freedom";
52 }];
53 };
54 description = lib.mdDoc ''
55 The configuration object.
56
57 Either `settingsFile` or `settings` must be specified.
58
59 See <https://www.v2fly.org/en_US/config/overview.html>.
60 '';
61 };
62 };
63
64 };
65
66 config = let
67 cfg = config.services.xray;
68 settingsFile = if cfg.settingsFile != null
69 then cfg.settingsFile
70 else pkgs.writeTextFile {
71 name = "xray.json";
72 text = builtins.toJSON cfg.settings;
73 checkPhase = ''
74 ${cfg.package}/bin/xray -test -config $out
75 '';
76 };
77
78 in mkIf cfg.enable {
79 assertions = [
80 {
81 assertion = (cfg.settingsFile == null) != (cfg.settings == null);
82 message = "Either but not both `settingsFile` and `settings` should be specified for xray.";
83 }
84 ];
85
86 systemd.services.xray = {
87 description = "xray Daemon";
88 after = [ "network.target" ];
89 wantedBy = [ "multi-user.target" ];
90 serviceConfig = {
91 DynamicUser = true;
92 ExecStart = "${cfg.package}/bin/xray -config ${settingsFile}";
93 };
94 };
95 };
96}