From 354821c1e8e30ce8522dc90ccb3e2026b31067b7 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Sat, 29 Jul 2023 11:20:37 +0100 Subject: [PATCH] nixos/eris-server: init --- .../manual/release-notes/rl-2311.section.md | 2 + nixos/modules/module-list.nix | 1 + .../network-filesystems/eris-server.nix | 103 ++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/eris-server.nix | 23 ++++ pkgs/servers/eris-go/default.nix | 4 +- 6 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 nixos/modules/services/network-filesystems/eris-server.nix create mode 100644 nixos/tests/eris-server.nix diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index e4e2c49859b3..30188efaabed 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -36,6 +36,8 @@ - [systemd-sysupdate](https://www.freedesktop.org/software/systemd/man/systemd-sysupdate.html), atomically updates the host OS, container images, portable service images or other sources. Available as [systemd.sysupdate](opt-systemd.sysupdate). +- [eris-server](https://codeberg.org/eris/eris-go). [ERIS](https://eris.codeberg.page/) is an encoding for immutable storage and this server provides block exchange as well as content decoding over HTTP and through a FUSE file-system. Available as [services.eris-server](#opt-services.eris-server.enable). + ## Backward Incompatibilities {#sec-release-23.11-incompatibilities} - The `boot.loader.raspberryPi` options have been marked deprecated, with intent for removal for NixOS 24.11. They had a limited use-case, and do not work like people expect. They required either very old installs ([before mid-2019](https://github.com/NixOS/nixpkgs/pull/62462)) or customized builds out of scope of the standard and generic AArch64 support. That option set never supported the Raspberry Pi 4 family of devices. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index e4e5fa97608a..583225e03a01 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -805,6 +805,7 @@ ./services/network-filesystems/davfs2.nix ./services/network-filesystems/diod.nix ./services/network-filesystems/drbd.nix + ./services/network-filesystems/eris-server.nix ./services/network-filesystems/glusterfs.nix ./services/network-filesystems/kbfs.nix ./services/network-filesystems/kubo.nix diff --git a/nixos/modules/services/network-filesystems/eris-server.nix b/nixos/modules/services/network-filesystems/eris-server.nix new file mode 100644 index 000000000000..66eccfac408c --- /dev/null +++ b/nixos/modules/services/network-filesystems/eris-server.nix @@ -0,0 +1,103 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.eris-server; + stateDirectoryPath = "\${STATE_DIRECTORY}"; +in { + + options.services.eris-server = { + + enable = lib.mkEnableOption "an ERIS server"; + + package = lib.mkOption { + type = lib.types.package; + default = pkgs.eris-go; + defaultText = lib.literalExpression "pkgs.eris-go"; + description = "Package to use for the ERIS server."; + }; + + decode = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Whether the HTTP service (when enabled) will decode ERIS content at /uri-res/N2R?urn:eris:. + Enabling this is recommended only for private or local-only servers. + ''; + }; + + listenCoap = lib.mkOption { + type = lib.types.str; + default = ":5683"; + example = "[::1]:5683"; + description = '' + Server CoAP listen address. Listen on all IP addresses at port 5683 by default. + Please note that the server can service client requests for ERIS-blocks by + querying other clients connected to the server. Whether or not blocks are + relayed back to the server depends on client configuration but be aware this + may leak sensitive metadata and trigger network activity. + ''; + }; + + listenHttp = lib.mkOption { + type = lib.types.str; + default = ""; + example = "[::1]:8080"; + description = "Server HTTP listen address. Do not listen by default."; + }; + + backends = lib.mkOption { + type = with lib.types; listOf str; + description = '' + List of backend URLs. + Add "get" and "put" as query elements to enable those operations. + ''; + example = [ + "bolt+file:///srv/eris.bolt?get&put" + "coap+tcp://eris.example.com:5683?get" + ]; + }; + + mountpoint = lib.mkOption { + type = lib.types.str; + default = ""; + example = "/eris"; + description = '' + Mountpoint for FUSE namespace that exposes "urn:eris:…" files. + ''; + }; + + }; + + config = lib.mkIf cfg.enable { + systemd.services.eris-server = let + cmd = + "${cfg.package}/bin/eris-go server --coap '${cfg.listenCoap}' --http '${cfg.listenHttp}' ${ + lib.optionalString cfg.decode "--decode " + }${ + lib.optionalString (cfg.mountpoint != "") + ''--mountpoint "${cfg.mountpoint}" '' + }${lib.strings.escapeShellArgs cfg.backends}"; + in { + description = "ERIS block server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + script = lib.mkIf (cfg.mountpoint != "") '' + export PATH=${config.security.wrapperDir}:$PATH + ${cmd} + ''; + serviceConfig = let + umounter = lib.mkIf (cfg.mountpoint != "") + "-${config.security.wrapperDir}/fusermount -uz ${cfg.mountpoint}"; + in { + ExecStartPre = umounter; + ExecStart = lib.mkIf (cfg.mountpoint == "") cmd; + ExecStopPost = umounter; + Restart = "always"; + RestartSec = 20; + AmbientCapabilities = "CAP_NET_BIND_SERVICE"; + }; + }; + }; + + meta.maintainers = with lib.maintainers; [ ehmry ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index c707200def09..05f5337d044f 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -252,6 +252,7 @@ in { envoy = handleTest ./envoy.nix {}; ergo = handleTest ./ergo.nix {}; ergochat = handleTest ./ergochat.nix {}; + eris-server = handleTest ./eris-server.nix {}; esphome = handleTest ./esphome.nix {}; etc = pkgs.callPackage ../modules/system/etc/test.nix { inherit evalMinimalConfig; }; activation = pkgs.callPackage ../modules/system/activation/test.nix { }; diff --git a/nixos/tests/eris-server.nix b/nixos/tests/eris-server.nix new file mode 100644 index 000000000000..a50db3afebf5 --- /dev/null +++ b/nixos/tests/eris-server.nix @@ -0,0 +1,23 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: { + name = "eris-server"; + meta.maintainers = with lib.maintainers; [ ehmry ]; + + nodes.server = { + environment.systemPackages = [ pkgs.eris-go pkgs.nim.pkgs.eris ]; + services.eris-server = { + enable = true; + decode = true; + listenHttp = "[::1]:80"; + backends = [ "badger+file:///var/cache/eris.badger?get&put" ]; + mountpoint = "/eris"; + }; + }; + + testScript = '' + start_all() + server.wait_for_unit("eris-server.service") + server.wait_for_open_port(5683) + server.wait_for_open_port(80) + server.succeed("eriscmd get http://[::1] $(echo 'Hail ERIS!' | eriscmd put coap+tcp://[::1]:5683)") + ''; +}) diff --git a/pkgs/servers/eris-go/default.nix b/pkgs/servers/eris-go/default.nix index ae9f7ac6e8ce..fa2517b9ba2a 100644 --- a/pkgs/servers/eris-go/default.nix +++ b/pkgs/servers/eris-go/default.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, buildGoModule, fetchFromGitea }: +{ lib, stdenv, buildGoModule, fetchFromGitea, nixosTests }: buildGoModule rec { pname = "eris-go"; @@ -14,6 +14,8 @@ buildGoModule rec { vendorHash = "sha256-Z6rirsiiBzH0herQAkxZp1Xr++489qNoiD4fqoLt9/A="; + passthru.tests = { inherit (nixosTests) eris-server; }; + meta = src.meta // { description = "Implementation of ERIS for Go"; homepage = "https://codeberg.org/eris/eris-go";