From 9480ab324611a7c5c1b980740ed8bdf269baecde Mon Sep 17 00:00:00 2001 From: dadada Date: Sun, 9 Jul 2023 01:11:47 +0200 Subject: [PATCH] Install soft-serve on ninurta --- nixos/configurations.nix | 7 +- nixos/modules/default.nix | 1 + nixos/modules/networking.nix | 2 +- nixos/modules/soft-serve.nix | 212 ++++++++++++++++++++++++++++++++ nixos/ninurta/configuration.nix | 22 +++- overlays.nix | 4 + pkgs/soft-serve.nix | 37 ++++++ 7 files changed, 280 insertions(+), 5 deletions(-) create mode 100644 nixos/modules/soft-serve.nix create mode 100644 pkgs/soft-serve.nix diff --git a/nixos/configurations.nix b/nixos/configurations.nix index 821ad22..6c8f9da 100644 --- a/nixos/configurations.nix +++ b/nixos/configurations.nix @@ -17,6 +17,7 @@ let modules = [{ # Add flakes to registry and nix path. dadada.inputs = inputs // { dadada = self; }; + nixpkgs.overlays = nixpkgs.lib.attrValues self.overlays; }] ++ (nixpkgs.lib.attrValues self.nixosModules) ++ [ agenix.nixosModules.age ] ++ extraModules; }; in @@ -101,5 +102,9 @@ in ]; }; - ninurta = nixosSystem { extraModules = [ ./ninurta/configuration.nix ]; }; + ninurta = nixosSystem { + extraModules = [ + ./ninurta/configuration.nix + ]; + }; } diff --git a/nixos/modules/default.nix b/nixos/modules/default.nix index 9b8864e..f89d4ce 100644 --- a/nixos/modules/default.nix +++ b/nixos/modules/default.nix @@ -16,6 +16,7 @@ packages = import ./packages.nix; secrets = import ./secrets.nix; share = import ./share.nix; + soft-serve = import ./soft-serve.nix; steam = import ./steam.nix; sway = import ./sway.nix; vpnServer = import ./vpnServer.nix; diff --git a/nixos/modules/networking.nix b/nixos/modules/networking.nix index 43ddd8c..b58fb2d 100644 --- a/nixos/modules/networking.nix +++ b/nixos/modules/networking.nix @@ -132,7 +132,7 @@ in networking.wireguard.interfaces = mkIf (cfg.vpnExtension != null) { dadada = { - ips = [ "fd42:9c3b:f96d:201::${cfg.vpnExtension}/64" "192.168.120.${cfg.vpnExtension}/17" ]; + ips = [ "fd42:9c3b:f96d:201::${cfg.vpnExtension}/64" "192.168.120.${cfg.vpnExtension}/24" ]; listenPort = 51234; privateKeyFile = "/var/lib/wireguard/privkey"; postSetup = '' diff --git a/nixos/modules/soft-serve.nix b/nixos/modules/soft-serve.nix new file mode 100644 index 0000000..a2e1a27 --- /dev/null +++ b/nixos/modules/soft-serve.nix @@ -0,0 +1,212 @@ +{ config, lib, pkgs, ... }: +with lib; + +let + cfg = config.services.soft-serve; + configFile = format.generate "config.yaml" cfg.settings; + exe = getExe cfg.package; + format = pkgs.formats.yaml { }; + user = "soft-serve"; +in +{ + options = { + services.soft-serve = { + enable = mkEnableOption "Enable soft-serve service"; + + package = mkPackageOption pkgs "soft-serve" { }; + + stateDir = mkOption { + type = types.path; + default = "/var/lib/soft-serve"; + description = lib.mdDoc '' + The absolute path to the data directory. + + See . + ''; + }; + + user = mkOption { + type = types.str; + default = user; + description = lib.mdDoc "User account under which soft-serve runs."; + }; + + group = mkOption { + type = types.str; + default = user; + description = lib.mdDoc "Group account under which soft-serve runs."; + }; + + settings = mkOption { + type = format.type; + default = { }; + description = lib.mdDoc '' + The contents of the configuration file. + + See . + ''; + example = literalExpression '' + { + # Soft Serve Server configurations + + # The name of the server. + # This is the name that will be displayed in the UI. + name = "Soft Serve"; + + # Log format to use. Valid values are "json", "logfmt", and "text". + log_format = "text"; + + # The SSH server configuration. + ssh = { + # The address on which the SSH server will listen. + listen_addr = ":23231"; + + # The public URL of the SSH server. + # This is the address that will be used to clone repositories. + public_url = "ssh://localhost:23231"; + + # The path to the SSH server's private key. + key_path = "ssh/soft_serve_host"; + + # The path to the SSH server's client private key. + # This key will be used to authenticate the server to make git requests to + # ssh remotes. + client_key_path = "ssh/soft_serve_client"; + + # The maximum number of seconds a connection can take. + # A value of 0 means no timeout. + max_timeout = 0; + + # The number of seconds a connection can be idle before it is closed. + idle_timeout = 120; + }; + # The Git daemon configuration. + git = { + # The address on which the Git daemon will listen. + listen_addr = ":9418"; + + # The maximum number of seconds a connection can take. + # A value of 0 means no timeout. + max_timeout = 0; + + # The number of seconds a connection can be idle before it is closed. + idle_timeout = 3; + + # The maximum number of concurrent connections. + max_connections = 32; + }; + + # The HTTP server configuration. + http = { + # The address on which the HTTP server will listen. + listen_addr = ":23232"; + + # The path to the TLS private key. + tls_key_path = ""; + + # The path to the TLS certificate. + tls_cert_path = ""; + + # The public URL of the HTTP server. + # This is the address that will be used to clone repositories. + # Make sure to use https:// if you are using TLS. + public_url = "http://localhost:23232"; + + }; + + # The stats server configuration. + stats = { + # The address on which the stats server will listen. + listen_addr = ":23233"; + }; + # Additional admin keys. + initial_admin_keys = [ + "ssh-rsa AAAAB3NzaC1yc2..." + ]; + }; + ''; + }; + }; + }; + + config = let stateDir = cfg.stateDir; in mkIf cfg.enable { + users.users = mkIf (cfg.user == "soft-serve") { + soft-serve = { + description = "soft-serve service"; + home = cfg.stateDir; + useDefaultShell = true; + group = cfg.group; + isSystemUser = true; + }; + }; + + users.groups = mkIf (cfg.group == "soft-serve") { + soft-serve = { }; + }; + + systemd.tmpfiles.rules = [ + "d '${stateDir}' 0750 ${cfg.user} ${cfg.group} - -" + ]; + + systemd.services.soft-serve = { + description = "Soft Serve git server 🍦"; + documentation = [ "https://github.com/charmbracelet/soft-serve" ]; + requires = [ "network-online.target" ]; + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + + environment = { + SOFT_SERVE_DATA_PATH = stateDir; + }; + + preStart = '' + # Link the settings file into the data directory. + ln -fs ${configFile} ${stateDir}/config.yaml + ''; + + serviceConfig = { + Type = "simple"; + User = cfg.user; + Group = cfg.group; + Restart = "always"; + RestartSec = "1"; + ExecStart = "${exe} serve"; + WorkingDirectory = stateDir; + RuntimeDirectory = "soft-serve"; + RuntimeDirectoryMode = "0750"; + ProcSubset = "pid"; + ProtectProc = "invisible"; + ReadWritePaths = [ stateDir ]; + UMask = "0027"; + CapabilityBoundingSet = ""; + NoNewPrivileges = true; + ProtectSystem = "strict"; + ProtectHome = true; + PrivateTmp = true; + PrivateDevices = true; + PrivateUsers = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + PrivateMounts = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "~@cpu-emulation @debug @keyring @module @mount @obsolete @privileged @raw-io @reboot @setuid @swap" + ]; + }; + }; + }; + + meta.maintainers = [ maintainers.dadada ]; +} diff --git a/nixos/ninurta/configuration.nix b/nixos/ninurta/configuration.nix index b198253..de73b3c 100644 --- a/nixos/ninurta/configuration.nix +++ b/nixos/ninurta/configuration.nix @@ -11,6 +11,7 @@ let wg0PresharedKey = "pruflas-wg0-preshared-key"; hydraGitHubAuth = "hydra-github-authorization"; initrdSshKey = "/etc/ssh/ssh_initrd_ed25519_key"; + softServePort = 23231; in { imports = [ @@ -18,6 +19,22 @@ in ./hardware-configuration.nix ]; + services.soft-serve = { + enable = true; + settings = { + name = "dadada's repos"; + log_format = "text"; + ssh = { + listen_addr = ":${toString softServePort}"; + public_url = "ssh://soft-serve.dadada.li:${toString softServePort}"; + max_timeout = 30; + idle_timeout = 120; + }; + stats.listen_addr = ":23233"; + initial_admin_keys = config.dadada.admin.users.dadada.keys; + }; + }; + dadada.backupClient.bs.enable = false; dadada.backupClient.backup1.enable = false; @@ -75,7 +92,7 @@ in }; }; - dadada.ddns.domains = [ "backup1.dadada.li" ]; + dadada.ddns.domains = [ "backup1.dadada.li" "soft-serve.dadada.li" ]; dadada.ddns.credentialsPath = config.age.secrets."ddns-credentials".path; dadada.ddns.interface = "backup"; @@ -350,6 +367,7 @@ in 80 # HTTP 443 # HTTPS 3000 # Hydra + softServePort ]; allowedUDPPorts = [ 51234 # Wireguard @@ -384,8 +402,6 @@ in ''; }; - - powerManagement = { enable = true; cpuFreqGovernor = "powersave"; diff --git a/overlays.nix b/overlays.nix index 6d636ec..7432ba5 100644 --- a/overlays.nix +++ b/overlays.nix @@ -38,4 +38,8 @@ }; }); }; + + soft-serve = final: prev: { + soft-serve = prev.callPackage ./pkgs/soft-serve.nix { }; + }; } diff --git a/pkgs/soft-serve.nix b/pkgs/soft-serve.nix new file mode 100644 index 0000000..a6fc8ac --- /dev/null +++ b/pkgs/soft-serve.nix @@ -0,0 +1,37 @@ +# Borrowed from nixpkgs. +# See https://github.com/NixOS/nixpkgs/issues/86349 +{ lib, buildGoModule, fetchFromGitHub, makeWrapper, git }: + +buildGoModule rec { + pname = "soft-serve"; + version = "0.5.4"; + + src = fetchFromGitHub { + owner = "charmbracelet"; + repo = "soft-serve"; + rev = "v${version}"; + sha256 = "sha256-pVUkmia6W5CVYLjrE6Ie2OVme3y2pmhMMxCYS5qyhgs="; + }; + + vendorHash = "sha256-wf2Dfo4uWHg/h2+EfEW5oGUgqf1kAgiTq7ivczI1w+c="; + + doCheck = false; + + ldflags = [ "-s" "-w" "-X=main.Version=${version}" ]; + + nativeBuildInputs = [ makeWrapper ]; + + postInstall = '' + wrapProgram $out/bin/soft \ + --prefix PATH : "${lib.makeBinPath [ git ]}" + ''; + + meta = with lib; { + description = "A tasty, self-hosted Git server for the command line"; + homepage = "https://github.com/charmbracelet/soft-serve"; + changelog = "https://github.com/charmbracelet/soft-serve/releases/tag/v${version}"; + mainProgram = "soft"; + license = licenses.mit; + maintainers = with maintainers; [ penguwin ]; + }; +}