aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos/modules/services/networking/unifi.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/services/networking/unifi.nix')
-rw-r--r--nixpkgs/nixos/modules/services/networking/unifi.nix189
1 files changed, 189 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/networking/unifi.nix b/nixpkgs/nixos/modules/services/networking/unifi.nix
new file mode 100644
index 00000000000..c922ba15960
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/networking/unifi.nix
@@ -0,0 +1,189 @@
+{ config, lib, pkgs, utils, ... }:
+with lib;
+let
+ cfg = config.services.unifi;
+ stateDir = "/var/lib/unifi";
+ cmd = ''
+ @${cfg.jrePackage}/bin/java java \
+ ${optionalString (cfg.initialJavaHeapSize != null) "-Xms${(toString cfg.initialJavaHeapSize)}m"} \
+ ${optionalString (cfg.maximumJavaHeapSize != null) "-Xmx${(toString cfg.maximumJavaHeapSize)}m"} \
+ -jar ${stateDir}/lib/ace.jar
+ '';
+ mountPoints = [
+ {
+ what = "${cfg.unifiPackage}/dl";
+ where = "${stateDir}/dl";
+ }
+ {
+ what = "${cfg.unifiPackage}/lib";
+ where = "${stateDir}/lib";
+ }
+ {
+ what = "${cfg.mongodbPackage}/bin";
+ where = "${stateDir}/bin";
+ }
+ {
+ what = "${cfg.dataDir}";
+ where = "${stateDir}/data";
+ }
+ ];
+ systemdMountPoints = map (m: "${utils.escapeSystemdPath m.where}.mount") mountPoints;
+in
+{
+
+ options = {
+
+ services.unifi.enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether or not to enable the unifi controller service.
+ '';
+ };
+
+ services.unifi.jrePackage = mkOption {
+ type = types.package;
+ default = pkgs.jre8;
+ defaultText = "pkgs.jre8";
+ description = ''
+ The JRE package to use. Check the release notes to ensure it is supported.
+ '';
+ };
+
+ services.unifi.unifiPackage = mkOption {
+ type = types.package;
+ default = pkgs.unifiLTS;
+ defaultText = "pkgs.unifiLTS";
+ description = ''
+ The unifi package to use.
+ '';
+ };
+
+ services.unifi.mongodbPackage = mkOption {
+ type = types.package;
+ default = pkgs.mongodb;
+ defaultText = "pkgs.mongodb";
+ description = ''
+ The mongodb package to use.
+ '';
+ };
+
+ services.unifi.dataDir = mkOption {
+ type = types.str;
+ default = "${stateDir}/data";
+ description = ''
+ Where to store the database and other data.
+
+ This directory will be bind-mounted to ${stateDir}/data as part of the service startup.
+ '';
+ };
+
+ services.unifi.openPorts = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether or not to open the minimum required ports on the firewall.
+
+ This is necessary to allow firmware upgrades and device discovery to
+ work. For remote login, you should additionally open (or forward) port
+ 8443.
+ '';
+ };
+
+ services.unifi.initialJavaHeapSize = mkOption {
+ type = types.nullOr types.int;
+ default = null;
+ example = 1024;
+ description = ''
+ Set the initial heap size for the JVM in MB. If this option isn't set, the
+ JVM will decide this value at runtime.
+ '';
+ };
+
+ services.unifi.maximumJavaHeapSize = mkOption {
+ type = types.nullOr types.int;
+ default = null;
+ example = 4096;
+ description = ''
+ Set the maximimum heap size for the JVM in MB. If this option isn't set, the
+ JVM will decide this value at runtime.
+ '';
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+
+ users.users.unifi = {
+ uid = config.ids.uids.unifi;
+ description = "UniFi controller daemon user";
+ home = "${stateDir}";
+ };
+
+ networking.firewall = mkIf cfg.openPorts {
+ # https://help.ubnt.com/hc/en-us/articles/218506997
+ allowedTCPPorts = [
+ 8080 # Port for UAP to inform controller.
+ 8880 # Port for HTTP portal redirect, if guest portal is enabled.
+ 8843 # Port for HTTPS portal redirect, ditto.
+ 6789 # Port for UniFi mobile speed test.
+ ];
+ allowedUDPPorts = [
+ 3478 # UDP port used for STUN.
+ 10001 # UDP port used for device discovery.
+ ];
+ };
+
+ # We must create the binary directories as bind mounts instead of symlinks
+ # This is because the controller resolves all symlinks to absolute paths
+ # to be used as the working directory.
+ systemd.mounts = map ({ what, where }: {
+ bindsTo = [ "unifi.service" ];
+ partOf = [ "unifi.service" ];
+ unitConfig.RequiresMountsFor = stateDir;
+ options = "bind";
+ what = what;
+ where = where;
+ }) mountPoints;
+
+ systemd.tmpfiles.rules = [
+ "e '${stateDir}' 0700 unifi - - -"
+ "d '${stateDir}/data' 0700 unifi - - -"
+ ];
+
+ systemd.services.unifi = {
+ description = "UniFi controller daemon";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ] ++ systemdMountPoints;
+ partOf = systemdMountPoints;
+ bindsTo = systemdMountPoints;
+ unitConfig.RequiresMountsFor = stateDir;
+ # This a HACK to fix missing dependencies of dynamic libs extracted from jars
+ environment.LD_LIBRARY_PATH = with pkgs.stdenv; "${cc.cc.lib}/lib";
+
+ preStart = ''
+ # Create the volatile webapps
+ rm -rf "${stateDir}/webapps"
+ mkdir -p "${stateDir}/webapps"
+ ln -s "${cfg.unifiPackage}/webapps/ROOT" "${stateDir}/webapps/ROOT"
+ '';
+
+ postStop = ''
+ rm -rf "${stateDir}/webapps"
+ '';
+
+ serviceConfig = {
+ Type = "simple";
+ ExecStart = "${(removeSuffix "\n" cmd)} start";
+ ExecStop = "${(removeSuffix "\n" cmd)} stop";
+ Restart = "on-failure";
+ User = "unifi";
+ UMask = "0077";
+ WorkingDirectory = "${stateDir}";
+ };
+ };
+
+ };
+
+ meta.maintainers = with lib.maintainers; [ erictapen ];
+}