Loading nixos/modules/module-list.nix +1 −0 Original line number Diff line number Diff line Loading @@ -865,6 +865,7 @@ ./services/networking/bitlbee.nix ./services/networking/blockbook-frontend.nix ./services/networking/blocky.nix ./services/networking/centrifugo.nix ./services/networking/cgit.nix ./services/networking/charybdis.nix ./services/networking/chisel-server.nix Loading nixos/modules/services/networking/centrifugo.nix 0 → 100644 +123 −0 Original line number Diff line number Diff line { config, lib, pkgs, ... }: let cfg = config.services.centrifugo; settingsFormat = pkgs.formats.json { }; configFile = settingsFormat.generate "centrifugo.json" cfg.settings; in { options.services.centrifugo = { enable = lib.mkEnableOption (lib.mdDoc "Centrifugo messaging server"); package = lib.mkPackageOptionMD pkgs "centrifugo" { }; settings = lib.mkOption { type = settingsFormat.type; default = { }; description = lib.mdDoc '' Declarative Centrifugo configuration. See the [Centrifugo documentation] for a list of options. [Centrifugo documentation]: https://centrifugal.dev/docs/server/configuration ''; }; credentials = lib.mkOption { type = lib.types.attrsOf lib.types.path; default = { }; example = { CENTRIFUGO_UNI_GRPC_TLS_KEY = "/run/keys/centrifugo-uni-grpc-tls.key"; }; description = lib.mdDoc '' Environment variables with absolute paths to credentials files to load on service startup. ''; }; environmentFiles = lib.mkOption { type = lib.types.listOf lib.types.path; default = [ ]; description = lib.mdDoc '' Files to load environment variables from. Options set via environment variables take precedence over {option}`settings`. See the [Centrifugo documentation] for the environment variable name format. [Centrifugo documentation]: https://centrifugal.dev/docs/server/configuration#os-environment-variables ''; }; extraGroups = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; example = [ "redis-centrifugo" ]; description = lib.mdDoc '' Additional groups for the systemd service. ''; }; }; config = lib.mkIf cfg.enable { systemd.services.centrifugo = { description = "Centrifugo messaging server"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { Type = "exec"; ExecStartPre = "${lib.getExe cfg.package} checkconfig --config ${configFile}"; ExecStart = "${lib.getExe cfg.package} --config ${configFile}"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; Restart = "always"; RestartSec = "1s"; # Copy files to the credentials directory with file name being the # environment variable name. Note that "%d" specifier expands to the # path of the credentials directory. LoadCredential = lib.mapAttrsToList (name: value: "${name}:${value}") cfg.credentials; Environment = lib.mapAttrsToList (name: _: "${name}=%d/${name}") cfg.credentials; EnvironmentFile = cfg.environmentFiles; SupplementaryGroups = cfg.extraGroups; DynamicUser = true; UMask = "0077"; ProtectHome = true; ProtectProc = "invisible"; ProcSubset = "pid"; ProtectClock = true; ProtectHostname = true; ProtectControlGroups = true; ProtectKernelLogs = true; ProtectKernelModules = true; ProtectKernelTunables = true; PrivateUsers = true; PrivateDevices = true; RestrictRealtime = true; RestrictNamespaces = true; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; DeviceAllow = [ "" ]; DevicePolicy = "closed"; CapabilityBoundingSet = [ "" ]; MemoryDenyWriteExecute = true; LockPersonality = true; SystemCallArchitectures = "native"; SystemCallErrorNumber = "EPERM"; SystemCallFilter = [ "@system-service" "~@privileged" ]; }; }; }; } nixos/tests/all-tests.nix +1 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,7 @@ in { cassandra_3_0 = handleTest ./cassandra.nix { testPackage = pkgs.cassandra_3_0; }; cassandra_3_11 = handleTest ./cassandra.nix { testPackage = pkgs.cassandra_3_11; }; cassandra_4 = handleTest ./cassandra.nix { testPackage = pkgs.cassandra_4; }; centrifugo = runTest ./centrifugo.nix; ceph-multi-node = handleTestOn [ "aarch64-linux" "x86_64-linux" ] ./ceph-multi-node.nix {}; ceph-single-node = handleTestOn [ "aarch64-linux" "x86_64-linux" ] ./ceph-single-node.nix {}; ceph-single-node-bluestore = handleTestOn [ "aarch64-linux" "x86_64-linux" ] ./ceph-single-node-bluestore.nix {}; Loading nixos/tests/centrifugo.nix 0 → 100644 +80 −0 Original line number Diff line number Diff line let redisPort = 6379; centrifugoPort = 8080; nodes = [ "centrifugo1" "centrifugo2" "centrifugo3" ]; in { lib, ... }: { name = "centrifugo"; meta.maintainers = [ lib.maintainers.tie ]; nodes = lib.listToAttrs (lib.imap0 (index: name: { inherit name; value = { config, ... }: { services.centrifugo = { enable = true; settings = { inherit name; port = centrifugoPort; # See https://centrifugal.dev/docs/server/engines#redis-sharding engine = "redis"; # Connect to local Redis shard via Unix socket. redis_address = let otherNodes = lib.take index nodes ++ lib.drop (index + 1) nodes; in map (name: "${name}:${toString redisPort}") otherNodes ++ [ "unix://${config.services.redis.servers.centrifugo.unixSocket}" ]; usage_stats_disable = true; api_insecure = true; }; extraGroups = [ config.services.redis.servers.centrifugo.user ]; }; services.redis.servers.centrifugo = { enable = true; bind = null; # all interfaces port = redisPort; openFirewall = true; settings.protected-mode = false; }; }; }) nodes); testScript = '' import json redisPort = ${toString redisPort} centrifugoPort = ${toString centrifugoPort} start_all() for machine in machines: machine.wait_for_unit("redis-centrifugo.service") machine.wait_for_open_port(redisPort) for machine in machines: machine.wait_for_unit("centrifugo.service") machine.wait_for_open_port(centrifugoPort) # See https://centrifugal.dev/docs/server/server_api#info def list_nodes(machine): curl = "curl --fail-with-body --silent" body = "{}" resp = json.loads(machine.succeed(f"{curl} -d '{body}' http://localhost:{centrifugoPort}/api/info")) return resp["result"]["nodes"] machineNames = {m.name for m in machines} for machine in machines: nodes = list_nodes(machine) assert len(nodes) == len(machines) nodeNames = {n['name'] for n in nodes} assert machineNames == nodeNames ''; } pkgs/by-name/ce/centrifugo/package.nix 0 → 100644 +60 −0 Original line number Diff line number Diff line { lib , buildGoModule , fetchFromGitHub , nix-update-script , nixosTests , testers , centrifugo }: let # Inspect build flags with `go version -m centrifugo`. statsEndpoint = "https://graphite-prod-01-eu-west-0.grafana.net/graphite/metrics,https://stats.centrifugal.dev/usage"; statsToken = "425599:eyJrIjoi" + "OWJhMTcyZGNjN2FkYjEzM2E1OTQwZjIyMTU3MTBjMjUyYzAyZWE2MSIsIm4iOiJVc2FnZSBTdGF0cyIsImlkIjo2NDUzOTN9"; in buildGoModule rec { pname = "centrifugo"; version = "5.1.1"; src = fetchFromGitHub { owner = "centrifugal"; repo = "centrifugo"; rev = "v${version}"; hash = "sha256-g496cXjgliDi2XLkdE+dERrUl5hBGLICJx5JundeOfo="; }; vendorHash = "sha256-VuxnP9Dryo0L7sGvtvAIicYGkHoQ2iGVBtAdkmiqL7E="; ldflags = [ "-s" "-w" "-X=github.com/centrifugal/centrifugo/v5/internal/build.Version=${version}" "-X=github.com/centrifugal/centrifugo/v5/internal/build.UsageStatsEndpoint=${statsEndpoint}" "-X=github.com/centrifugal/centrifugo/v5/internal/build.UsageStatsToken=${statsToken}" ]; excludedPackages = [ "./internal/gen/api" ]; passthru = { updateScript = nix-update-script { }; tests = { inherit (nixosTests) centrifugo; version = testers.testVersion { package = centrifugo; command = "${pname} version"; version = "v${version}"; }; }; }; meta = { description = "Scalable real-time messaging server"; homepage = "https://centrifugal.dev"; changelog = "https://github.com/centrifugal/centrifugo/releases/tag/v${version}"; license = lib.licenses.asl20; maintainers = [ lib.maintainers.tie ]; mainProgram = "centrifugo"; }; } Loading
nixos/modules/module-list.nix +1 −0 Original line number Diff line number Diff line Loading @@ -865,6 +865,7 @@ ./services/networking/bitlbee.nix ./services/networking/blockbook-frontend.nix ./services/networking/blocky.nix ./services/networking/centrifugo.nix ./services/networking/cgit.nix ./services/networking/charybdis.nix ./services/networking/chisel-server.nix Loading
nixos/modules/services/networking/centrifugo.nix 0 → 100644 +123 −0 Original line number Diff line number Diff line { config, lib, pkgs, ... }: let cfg = config.services.centrifugo; settingsFormat = pkgs.formats.json { }; configFile = settingsFormat.generate "centrifugo.json" cfg.settings; in { options.services.centrifugo = { enable = lib.mkEnableOption (lib.mdDoc "Centrifugo messaging server"); package = lib.mkPackageOptionMD pkgs "centrifugo" { }; settings = lib.mkOption { type = settingsFormat.type; default = { }; description = lib.mdDoc '' Declarative Centrifugo configuration. See the [Centrifugo documentation] for a list of options. [Centrifugo documentation]: https://centrifugal.dev/docs/server/configuration ''; }; credentials = lib.mkOption { type = lib.types.attrsOf lib.types.path; default = { }; example = { CENTRIFUGO_UNI_GRPC_TLS_KEY = "/run/keys/centrifugo-uni-grpc-tls.key"; }; description = lib.mdDoc '' Environment variables with absolute paths to credentials files to load on service startup. ''; }; environmentFiles = lib.mkOption { type = lib.types.listOf lib.types.path; default = [ ]; description = lib.mdDoc '' Files to load environment variables from. Options set via environment variables take precedence over {option}`settings`. See the [Centrifugo documentation] for the environment variable name format. [Centrifugo documentation]: https://centrifugal.dev/docs/server/configuration#os-environment-variables ''; }; extraGroups = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; example = [ "redis-centrifugo" ]; description = lib.mdDoc '' Additional groups for the systemd service. ''; }; }; config = lib.mkIf cfg.enable { systemd.services.centrifugo = { description = "Centrifugo messaging server"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { Type = "exec"; ExecStartPre = "${lib.getExe cfg.package} checkconfig --config ${configFile}"; ExecStart = "${lib.getExe cfg.package} --config ${configFile}"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; Restart = "always"; RestartSec = "1s"; # Copy files to the credentials directory with file name being the # environment variable name. Note that "%d" specifier expands to the # path of the credentials directory. LoadCredential = lib.mapAttrsToList (name: value: "${name}:${value}") cfg.credentials; Environment = lib.mapAttrsToList (name: _: "${name}=%d/${name}") cfg.credentials; EnvironmentFile = cfg.environmentFiles; SupplementaryGroups = cfg.extraGroups; DynamicUser = true; UMask = "0077"; ProtectHome = true; ProtectProc = "invisible"; ProcSubset = "pid"; ProtectClock = true; ProtectHostname = true; ProtectControlGroups = true; ProtectKernelLogs = true; ProtectKernelModules = true; ProtectKernelTunables = true; PrivateUsers = true; PrivateDevices = true; RestrictRealtime = true; RestrictNamespaces = true; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; DeviceAllow = [ "" ]; DevicePolicy = "closed"; CapabilityBoundingSet = [ "" ]; MemoryDenyWriteExecute = true; LockPersonality = true; SystemCallArchitectures = "native"; SystemCallErrorNumber = "EPERM"; SystemCallFilter = [ "@system-service" "~@privileged" ]; }; }; }; }
nixos/tests/all-tests.nix +1 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,7 @@ in { cassandra_3_0 = handleTest ./cassandra.nix { testPackage = pkgs.cassandra_3_0; }; cassandra_3_11 = handleTest ./cassandra.nix { testPackage = pkgs.cassandra_3_11; }; cassandra_4 = handleTest ./cassandra.nix { testPackage = pkgs.cassandra_4; }; centrifugo = runTest ./centrifugo.nix; ceph-multi-node = handleTestOn [ "aarch64-linux" "x86_64-linux" ] ./ceph-multi-node.nix {}; ceph-single-node = handleTestOn [ "aarch64-linux" "x86_64-linux" ] ./ceph-single-node.nix {}; ceph-single-node-bluestore = handleTestOn [ "aarch64-linux" "x86_64-linux" ] ./ceph-single-node-bluestore.nix {}; Loading
nixos/tests/centrifugo.nix 0 → 100644 +80 −0 Original line number Diff line number Diff line let redisPort = 6379; centrifugoPort = 8080; nodes = [ "centrifugo1" "centrifugo2" "centrifugo3" ]; in { lib, ... }: { name = "centrifugo"; meta.maintainers = [ lib.maintainers.tie ]; nodes = lib.listToAttrs (lib.imap0 (index: name: { inherit name; value = { config, ... }: { services.centrifugo = { enable = true; settings = { inherit name; port = centrifugoPort; # See https://centrifugal.dev/docs/server/engines#redis-sharding engine = "redis"; # Connect to local Redis shard via Unix socket. redis_address = let otherNodes = lib.take index nodes ++ lib.drop (index + 1) nodes; in map (name: "${name}:${toString redisPort}") otherNodes ++ [ "unix://${config.services.redis.servers.centrifugo.unixSocket}" ]; usage_stats_disable = true; api_insecure = true; }; extraGroups = [ config.services.redis.servers.centrifugo.user ]; }; services.redis.servers.centrifugo = { enable = true; bind = null; # all interfaces port = redisPort; openFirewall = true; settings.protected-mode = false; }; }; }) nodes); testScript = '' import json redisPort = ${toString redisPort} centrifugoPort = ${toString centrifugoPort} start_all() for machine in machines: machine.wait_for_unit("redis-centrifugo.service") machine.wait_for_open_port(redisPort) for machine in machines: machine.wait_for_unit("centrifugo.service") machine.wait_for_open_port(centrifugoPort) # See https://centrifugal.dev/docs/server/server_api#info def list_nodes(machine): curl = "curl --fail-with-body --silent" body = "{}" resp = json.loads(machine.succeed(f"{curl} -d '{body}' http://localhost:{centrifugoPort}/api/info")) return resp["result"]["nodes"] machineNames = {m.name for m in machines} for machine in machines: nodes = list_nodes(machine) assert len(nodes) == len(machines) nodeNames = {n['name'] for n in nodes} assert machineNames == nodeNames ''; }
pkgs/by-name/ce/centrifugo/package.nix 0 → 100644 +60 −0 Original line number Diff line number Diff line { lib , buildGoModule , fetchFromGitHub , nix-update-script , nixosTests , testers , centrifugo }: let # Inspect build flags with `go version -m centrifugo`. statsEndpoint = "https://graphite-prod-01-eu-west-0.grafana.net/graphite/metrics,https://stats.centrifugal.dev/usage"; statsToken = "425599:eyJrIjoi" + "OWJhMTcyZGNjN2FkYjEzM2E1OTQwZjIyMTU3MTBjMjUyYzAyZWE2MSIsIm4iOiJVc2FnZSBTdGF0cyIsImlkIjo2NDUzOTN9"; in buildGoModule rec { pname = "centrifugo"; version = "5.1.1"; src = fetchFromGitHub { owner = "centrifugal"; repo = "centrifugo"; rev = "v${version}"; hash = "sha256-g496cXjgliDi2XLkdE+dERrUl5hBGLICJx5JundeOfo="; }; vendorHash = "sha256-VuxnP9Dryo0L7sGvtvAIicYGkHoQ2iGVBtAdkmiqL7E="; ldflags = [ "-s" "-w" "-X=github.com/centrifugal/centrifugo/v5/internal/build.Version=${version}" "-X=github.com/centrifugal/centrifugo/v5/internal/build.UsageStatsEndpoint=${statsEndpoint}" "-X=github.com/centrifugal/centrifugo/v5/internal/build.UsageStatsToken=${statsToken}" ]; excludedPackages = [ "./internal/gen/api" ]; passthru = { updateScript = nix-update-script { }; tests = { inherit (nixosTests) centrifugo; version = testers.testVersion { package = centrifugo; command = "${pname} version"; version = "v${version}"; }; }; }; meta = { description = "Scalable real-time messaging server"; homepage = "https://centrifugal.dev"; changelog = "https://github.com/centrifugal/centrifugo/releases/tag/v${version}"; license = lib.licenses.asl20; maintainers = [ lib.maintainers.tie ]; mainProgram = "centrifugo"; }; }