Unverified Commit 8330abc5 authored by Weijia Wang's avatar Weijia Wang Committed by GitHub
Browse files

nixos/frp: support multiple instances (#386406)

parents bf81c853 67d9b4b9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -922,7 +922,7 @@ Make sure to also check the many updates in the [Nixpkgs library](#sec-release-2

- [frp](https://github.com/fatedier/frp), a fast reverse proxy to help you
  expose a local server behind a NAT or firewall to the Internet. Available as
  [services.frp](#opt-services.frp.enable).
  `services.frp`.

- [river](https://github.com/riverwm/river), A dynamic tiling wayland
  compositor. Available as `programs.river`.
+2 −0
Original line number Diff line number Diff line
@@ -26,4 +26,6 @@

<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->

- `services.frp` now supports multiple instances through `services.frp.instances` to make it possible to run multiple frp clients or servers at the same time.

- `services.openssh` now supports generating host SSH keys by setting `services.openssh.generateHostKeys = true` while leaving `services.openssh.enable` disabled.  This is particularly useful for systems that have no need of an SSH daemon but want SSH host keys for other purposes such as using agenix or sops-nix.
+101 −75
Original line number Diff line number Diff line
@@ -7,17 +7,29 @@
let
  cfg = config.services.frp;
  settingsFormat = pkgs.formats.toml { };
  configFile = settingsFormat.generate "frp.toml" cfg.settings;
  isClient = (cfg.role == "client");
  isServer = (cfg.role == "server");
  enabledInstances = lib.filterAttrs (name: conf: conf.enable) cfg.instances;
in
{
  imports = [
    (lib.mkRenamedOptionModule
      [ "services" "frp" "enable" ]
      [ "services" "frp" "instances" "" "enable" ]
    )
    (lib.mkRenamedOptionModule [ "services" "frp" "role" ] [ "services" "frp" "instances" "" "role" ])
    (lib.mkRenamedOptionModule
      [ "services" "frp" "settings" ]
      [ "services" "frp" "instances" "" "settings" ]
    )
  ];

  options = {
    services.frp = {
      instances = lib.mkOption {
        type = lib.types.attrsOf (
          lib.types.submodule {
            options = {
              enable = lib.mkEnableOption "frp";

      package = lib.mkPackageOption pkgs "frp" { };

              role = lib.mkOption {
                type = lib.types.enum [
                  "server"
@@ -45,20 +57,34 @@ in
                };
              };
            };
          }
        );
        default = { };
        description = ''
          Frp instances.
        '';
      };

      package = lib.mkPackageOption pkgs "frp" { };
    };
  };

  config =
  config = lib.mkIf (enabledInstances != { }) {
    systemd.services = lib.mapAttrs' (
      instance: options:
      let
        serviceName = "frp" + lib.optionalString (instance != "") ("-" + instance);
        configFile = settingsFormat.generate "${serviceName}.toml" options.settings;
        isClient = (options.role == "client");
        isServer = (options.role == "server");
        serviceCapability = lib.optionals isServer [ "CAP_NET_BIND_SERVICE" ];
        executableFile = if isClient then "frpc" else "frps";
      in
    lib.mkIf cfg.enable {
      systemd.services = {
        frp = {
      lib.nameValuePair serviceName {
        wants = lib.optionals isClient [ "network-online.target" ];
        after = if isClient then [ "network-online.target" ] else [ "network.target" ];
        wantedBy = [ "multi-user.target" ];
          description = "A fast reverse proxy frp ${cfg.role}";
        description = "A fast reverse proxy frp ${options.role} for instance ${instance}";
        serviceConfig = {
          Type = "simple";
          Restart = "on-failure";
@@ -93,8 +119,8 @@ in
          StateDirectoryMode = "0700";
          UMask = "0007";
        };
        };
      };
      }
    ) enabledInstances;
  };

  meta.maintainers = with lib.maintainers; [ zaldnoay ];