git.iko.soy/typeable/nixpkgs
on master help sign in
Merge pull request #141650 from 06kellyjac/agate
commita6d259faf34b251fa3d29ec1e1d9f154f564268f authorSandro <sandro.jaeckel@gmail.com> dateWed 16 Feb 2022, 00:56 (5 years ago) parent5c5a8df354b240
7 files changed+192−1
nixos/doc/manual/from_md/release-notes/rl-2205.section.xml+8 nixos/doc/manual/release-notes/rl-2205.section.md+2 nixos/modules/module-list.nix+1 nixos/modules/services/web-servers/agate.nix+148 nixos/tests/all-tests.nix+1 nixos/tests/web-servers/agate.nix+29 pkgs/servers/gemini/agate/default.nix+3−1
nixos/doc/manual/from_md/release-notes/rl-2205.section.xml+8
@@ -160,6 +160,14 @@
160160 <link linkend="opt-services.tetrd.enable">services.tetrd</link>.
161161 </para>
162162 </listitem>
163+ <listitem>
164+ <para>
165+ <link xlink:href="https://github.com/mbrubeck/agate">agate</link>,
166+ a very simple server for the Gemini hypertext protocol.
167+ Available as
168+ <link xlink:href="options.html#opt-services.agate.enable">services.agate</link>.
169+ </para>
170+ </listitem>
163171 <listitem>
164172 <para>
165173 <link xlink:href="https://github.com/JustArchiNET/ArchiSteamFarm">ArchiSteamFarm</link>,
nixos/doc/manual/release-notes/rl-2205.section.md+2
@@ -49,6 +49,8 @@ In addition to numerous new and upgraded packages, this release has the followin
4949
5050- [tetrd](https://tetrd.app), share your internet connection from your device to your PC and vice versa through a USB cable. Available at [services.tetrd](#opt-services.tetrd.enable).
5151
52+- [agate](https://github.com/mbrubeck/agate), a very simple server for the Gemini hypertext protocol. Available as [services.agate](options.html#opt-services.agate.enable).
53+
5254- [ArchiSteamFarm](https://github.com/JustArchiNET/ArchiSteamFarm), a C# application with primary purpose of idling Steam cards from multiple accounts simultaneously. Available as [services.archisteamfarm](options.html#opt-services.archisteamfarm.enable).
5355
5456- [teleport](https://goteleport.com), allows engineers and security professionals to unify access for SSH servers, Kubernetes clusters, web applications, and databases across all environments. Available at [services.teleport](#opt-services.teleport.enable).
nixos/modules/module-list.nix+1
@@ -1057,6 +1057,7 @@
10571057 ./services/web-apps/wordpress.nix
10581058 ./services/web-apps/youtrack.nix
10591059 ./services/web-apps/zabbix.nix
1060+ ./services/web-servers/agate.nix
10601061 ./services/web-servers/apache-httpd/default.nix
10611062 ./services/web-servers/caddy/default.nix
10621063 ./services/web-servers/darkhttpd.nix
nixos/modules/services/web-servers/agate.nixnew file+148
@@ -0,0 +1,148 @@
1+{ config, lib, pkgs, ... }:
2+
3+with lib;
4+
5+let
6+ cfg = config.services.agate;
7+in
8+{
9+ options = {
10+ services.agate = {
11+ enable = mkEnableOption "Agate Server";
12+
13+ package = mkOption {
14+ type = types.package;
15+ default = pkgs.agate;
16+ defaultText = literalExpression "pkgs.agate";
17+ description = "The package to use";
18+ };
19+
20+ addresses = mkOption {
21+ type = types.listOf types.str;
22+ default = [ "0.0.0.0:1965" ];
23+ description = ''
24+ Addresses to listen on, IP:PORT, if you haven't disabled forwarding
25+ only set IPv4.
26+ '';
27+ };
28+
29+ contentDir = mkOption {
30+ default = "/var/lib/agate/content";
31+ type = types.path;
32+ description = "Root of the content directory.";
33+ };
34+
35+ certificatesDir = mkOption {
36+ default = "/var/lib/agate/certificates";
37+ type = types.path;
38+ description = "Root of the certificate directory.";
39+ };
40+
41+ hostnames = mkOption {
42+ default = [ ];
43+ type = types.listOf types.str;
44+ description = ''
45+ Domain name of this Gemini server, enables checking hostname and port
46+ in requests. (multiple occurences means basic vhosts)
47+ '';
48+ };
49+
50+ language = mkOption {
51+ default = null;
52+ type = types.nullOr types.str;
53+ description = "RFC 4646 Language code for text/gemini documents.";
54+ };
55+
56+ onlyTls_1_3 = mkOption {
57+ default = false;
58+ type = types.bool;
59+ description = "Only use TLSv1.3 (default also allows TLSv1.2).";
60+ };
61+
62+ extraArgs = mkOption {
63+ type = types.listOf types.str;
64+ default = [ "" ];
65+ example = [ "--log-ip" ];
66+ description = "Extra arguments to use running agate.";
67+ };
68+ };
69+ };
70+
71+ config = mkIf cfg.enable {
72+ # available for generating certs by hand
73+ # it can be a bit arduous with openssl
74+ environment.systemPackages = [ cfg.package ];
75+
76+ systemd.services.agate = {
77+ description = "Agate";
78+ wantedBy = [ "multi-user.target" ];
79+ after = [ "network.target" "network-online.target" ];
80+
81+ script =
82+ let
83+ prefixKeyList = key: list: concatMap (v: [ key v ]) list;
84+ addresses = prefixKeyList "--addr" cfg.addresses;
85+ hostnames = prefixKeyList "--hostname" cfg.hostnames;
86+ in
87+ ''
88+ exec ${cfg.package}/bin/agate ${
89+ escapeShellArgs (
90+ [
91+ "--content" "${cfg.contentDir}"
92+ "--certs" "${cfg.certificatesDir}"
93+ ] ++
94+ addresses ++
95+ (optionals (cfg.hostnames != []) hostnames) ++
96+ (optionals (cfg.language != null) [ "--lang" cfg.language ]) ++
97+ (optionals cfg.onlyTls_1_3 [ "--only-tls13" ]) ++
98+ (optionals (cfg.extraArgs != []) cfg.extraArgs)
99+ )
100+ }
101+ '';
102+
103+ serviceConfig = {
104+ Restart = "always";
105+ RestartSec = "5s";
106+ DynamicUser = true;
107+ StateDirectory = "agate";
108+
109+ # Security options:
110+ AmbientCapabilities = "";
111+ CapabilityBoundingSet = "";
112+
113+ # ProtectClock= adds DeviceAllow=char-rtc r
114+ DeviceAllow = "";
115+
116+ LockPersonality = true;
117+
118+ PrivateTmp = true;
119+ PrivateDevices = true;
120+ PrivateUsers = true;
121+
122+ ProtectClock = true;
123+ ProtectControlGroups = true;
124+ ProtectHostname = true;
125+ ProtectKernelLogs = true;
126+ ProtectKernelModules = true;
127+ ProtectKernelTunables = true;
128+
129+ RestrictNamespaces = true;
130+ RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
131+ RestrictRealtime = true;
132+
133+ SystemCallArchitectures = "native";
134+ SystemCallErrorNumber = "EPERM";
135+ SystemCallFilter = [
136+ "@system-service"
137+ "~@cpu-emulation"
138+ "~@debug"
139+ "~@keyring"
140+ "~@memlock"
141+ "~@obsolete"
142+ "~@privileged"
143+ "~@setuid"
144+ ];
145+ };
146+ };
147+ };
148+}
nixos/tests/all-tests.nix+1
@@ -32,6 +32,7 @@ in
3232 acme = handleTest ./acme.nix {};
3333 adguardhome = handleTest ./adguardhome.nix {};
3434 aesmd = handleTest ./aesmd.nix {};
35+ agate = handleTest ./web-servers/agate.nix {};
3536 agda = handleTest ./agda.nix {};
3637 airsonic = handleTest ./airsonic.nix {};
3738 amazon-init-shell = handleTest ./amazon-init-shell.nix {};
nixos/tests/web-servers/agate.nixnew file+29
@@ -0,0 +1,29 @@
1+import ../make-test-python.nix (
2+ { pkgs, lib, ... }:
3+ {
4+ name = "agate";
5+ meta = with lib.maintainers; { maintainers = [ jk ]; };
6+
7+ nodes = {
8+ geminiserver = { pkgs, ... }: {
9+ services.agate = {
10+ enable = true;
11+ hostnames = [ "localhost" ];
12+ contentDir = pkgs.writeTextDir "index.gmi" ''
13+ # Hello NixOS!
14+ '';
15+ };
16+ };
17+ };
18+
19+ testScript = { nodes, ... }: ''
20+ geminiserver.wait_for_unit("agate")
21+ geminiserver.wait_for_open_port(1965)
22+
23+ with subtest("check is serving over gemini"):
24+ response = geminiserver.succeed("${pkgs.gmni}/bin/gmni -j once -i -N gemini://localhost:1965")
25+ print(response)
26+ assert "Hello NixOS!" in response
27+ '';
28+ }
29+)
pkgs/servers/gemini/agate/default.nix+3−1
@@ -1,4 +1,4 @@
1−{ lib, stdenv, fetchFromGitHub, rustPlatform, libiconv, Security }:
1+{ lib, stdenv, nixosTests, fetchFromGitHub, rustPlatform, libiconv, Security }:
22
33rustPlatform.buildRustPackage rec {
44 pname = "agate";
@@ -23,6 +23,8 @@ rustPlatform.buildRustPackage rec {
2323 runHook postInstallCheck
2424 '';
2525
26+ passthru.tests = { inherit (nixosTests) agate; };
27+
2628 meta = with lib; {
2729 homepage = "https://github.com/mbrubeck/agate";
2830 changelog = "https://github.com/mbrubeck/agate/blob/master/CHANGELOG.md";