{ config, lib, pkgs, ... }: with lib; let in { options = { enable = mkEnableOption "Enable Fudo Paris user server."; state-directory = mkOption { type = str; description = "Directory at which to store server state."; }; networking = { interface = mkOption { type = str; description = "Parent host interface on which to listen."; }; ipv4 = mkOption { type = nullOr (submodule { options = { address = mkOption { type = str; description = "IP address."; }; prefixLength = mkOption { type = int; description = "Significant bits in the address."; }; }; }); default = null; }; ipv6 = mkOption { type = nullOr (submodule { options = { address = mkOption { type = str; description = "IP address."; }; prefixLength = mkOption { type = int; description = "Significant bits in the address."; }; }; }); default = null; }; }; }; config = { systemd.tmpfiles.rules = [ "d ${cfg.state-directory}/home 0700 root root - -" ]; containers.paris = { tmpfs = true; macvlans = [ cfg.networking.interface ]; bindMounts = { "/home" = { hostPath = "${cfg.state-directory}/home"; isReadOnly = false; }; }; additionalCapabilities = [ "CAP_NET_ADMIN" ]; config = { nixpkgs.pkgs = pkgs; environment.systemPackages = with pkgs; [ rtorrent ]; networking = { defaultGateway = { address = getSiteGatewayV4 siteName; interface = "mv-${cfg.networking.interface}"; }; enableIPv6 = !isNull cfg.networking.ipv6; nameservers = config.networking.nameservers; firewall = { enable = true; allowedTCPPorts = [ 22 ] ++ cfg.ports; }; interfaces."mv-${cfg.networking.interface}" = { ipv4.addresses = optional (!isNull cfg.networking.ipv4) { address = cfg.networking.ipv4.address; prefixLength = cfg.networking.ipv4.prefixLength; }; ipv6.addresses = optional (!isNull cfg.networking.ipv6) { address = cfg.networking.ipv6.address; prefixLength = cfg.networking.ipv6.prefixLength; }; }; }; }; }; }; }