1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8with lib;
9
10let
11 cfg = config.services.x2goserver;
12
13 defaults = {
14 superenicer = {
15 enable = cfg.superenicer.enable;
16 };
17 };
18 confText = generators.toINI { } (recursiveUpdate defaults cfg.settings);
19 x2goServerConf = pkgs.writeText "x2goserver.conf" confText;
20
21 x2goAgentOptions = pkgs.writeText "x2goagent.options" ''
22 X2GO_NXOPTIONS=""
23 X2GO_NXAGENT_DEFAULT_OPTIONS="${concatStringsSep " " cfg.nxagentDefaultOptions}"
24 '';
25
26in
27{
28 imports = [
29 (mkRenamedOptionModule [ "programs" "x2goserver" ] [ "services" "x2goserver" ])
30 ];
31
32 options.services.x2goserver = {
33 enable = mkEnableOption "x2goserver" // {
34 description = ''
35 Enables the x2goserver module.
36 NOTE: This will create a good amount of symlinks in `/usr/local/bin`
37 '';
38 };
39
40 package = mkPackageOption pkgs "x2goserver" { };
41
42 superenicer = {
43 enable = mkEnableOption "superenicer" // {
44 description = ''
45 Enables the SupeReNicer code in x2gocleansessions, this will renice
46 suspended sessions to nice level 19 and renice them to level 0 if the
47 session becomes marked as running again
48 '';
49 };
50 };
51
52 nxagentDefaultOptions = mkOption {
53 type = types.listOf types.str;
54 default = [
55 "-extension GLX"
56 "-nolisten tcp"
57 ];
58 description = ''
59 List of default nx agent options.
60 '';
61 };
62
63 settings = mkOption {
64 type = types.attrsOf types.attrs;
65 default = { };
66 description = ''
67 x2goserver.conf ini configuration as nix attributes. See
68 `x2goserver.conf(5)` for details
69 '';
70 example = literalExpression ''
71 {
72 superenicer = {
73 "enable" = "yes";
74 "idle-nice-level" = 19;
75 };
76 telekinesis = { "enable" = "no"; };
77 }
78 '';
79 };
80 };
81
82 config = mkIf cfg.enable {
83
84 # x2goserver can run X11 program even if "services.xserver.enable = false"
85 xdg = {
86 autostart.enable = true;
87 menus.enable = true;
88 mime.enable = true;
89 icons.enable = true;
90 };
91
92 environment.systemPackages = [ cfg.package ];
93
94 users.groups.x2go = { };
95 users.users.x2go = {
96 home = "/var/lib/x2go/db";
97 group = "x2go";
98 isSystemUser = true;
99 };
100
101 security.wrappers.x2gosqliteWrapper = {
102 source = "${cfg.package}/lib/x2go/libx2go-server-db-sqlite3-wrapper.pl";
103 owner = "x2go";
104 group = "x2go";
105 setuid = false;
106 setgid = true;
107 };
108 security.wrappers.x2goprintWrapper = {
109 source = "${cfg.package}/bin/x2goprint";
110 owner = "x2go";
111 group = "x2go";
112 setuid = false;
113 setgid = true;
114 };
115
116 systemd.tmpfiles.rules =
117 with pkgs;
118 [
119 "d /var/lib/x2go/ - x2go x2go - -"
120 "d /var/lib/x2go/db - x2go x2go - -"
121 "d /var/lib/x2go/conf - x2go x2go - -"
122 "d /run/x2go 0755 x2go x2go - -"
123 ]
124 ++
125 # x2goclient sends SSH commands with preset PATH set to
126 # "/usr/local/bin;/usr/bin;/bin". Since we cannot filter arbitrary ssh
127 # commands, we have to make the following executables available.
128 map (f: "L+ /usr/local/bin/${f} - - - - ${cfg.package}/bin/${f}") [
129 "x2goagent"
130 "x2gobasepath"
131 "x2gocleansessions"
132 "x2gocmdexitmessage"
133 "x2godbadmin"
134 "x2gofeature"
135 "x2gofeaturelist"
136 "x2gofm"
137 "x2gogetapps"
138 "x2gogetservers"
139 "x2golistdesktops"
140 "x2golistmounts"
141 "x2golistsessions"
142 "x2golistsessions_root"
143 "x2golistshadowsessions"
144 "x2gomountdirs"
145 "x2gopath"
146 "x2goprint"
147 "x2goresume-desktopsharing"
148 "x2goresume-session"
149 "x2goruncommand"
150 "x2goserver-run-extensions"
151 "x2gosessionlimit"
152 "x2gosetkeyboard"
153 "x2goshowblocks"
154 "x2gostartagent"
155 "x2gosuspend-desktopsharing"
156 "x2gosuspend-session"
157 "x2goterminate-desktopsharing"
158 "x2goterminate-session"
159 "x2goumount-session"
160 "x2goversion"
161 ]
162 ++ [
163 "L+ /usr/local/bin/awk - - - - ${gawk}/bin/awk"
164 "L+ /usr/local/bin/chmod - - - - ${coreutils}/bin/chmod"
165 "L+ /usr/local/bin/cp - - - - ${coreutils}/bin/cp"
166 "L+ /usr/local/bin/sed - - - - ${gnused}/bin/sed"
167 "L+ /usr/local/bin/setsid - - - - ${util-linux}/bin/setsid"
168 "L+ /usr/local/bin/xrandr - - - - ${xorg.xrandr}/bin/xrandr"
169 "L+ /usr/local/bin/xmodmap - - - - ${xorg.xmodmap}/bin/xmodmap"
170 ];
171
172 systemd.services.x2goserver = {
173 description = "X2Go Server Daemon";
174 wantedBy = [ "multi-user.target" ];
175 unitConfig.Documentation = "man:x2goserver.conf(5)";
176 serviceConfig = {
177 Type = "forking";
178 ExecStart = "${cfg.package}/bin/x2gocleansessions";
179 PIDFile = "/run/x2go/x2goserver.pid";
180 User = "x2go";
181 Group = "x2go";
182 RuntimeDirectory = "x2go";
183 StateDirectory = "x2go";
184 };
185 preStart = ''
186 if [ ! -e /var/lib/x2go/setup_ran ]
187 then
188 mkdir -p /var/lib/x2go/conf
189 cp -r ${cfg.package}/etc/x2go/* /var/lib/x2go/conf/
190 ln -sf ${x2goServerConf} /var/lib/x2go/conf/x2goserver.conf
191 ln -sf ${x2goAgentOptions} /var/lib/x2go/conf/x2goagent.options
192 ${cfg.package}/bin/x2godbadmin --createdb
193 touch /var/lib/x2go/setup_ran
194 fi
195 '';
196 };
197
198 # https://bugs.x2go.org/cgi-bin/bugreport.cgi?bug=276
199 security.sudo.extraConfig = ''
200 Defaults env_keep+=QT_GRAPHICSSYSTEM
201 '';
202 security.sudo-rs.extraConfig = ''
203 Defaults env_keep+=QT_GRAPHICSSYSTEM
204 '';
205 };
206}