diff --git a/flake.nix b/flake.nix
index 5e141ef1..b6b93954 100644
--- a/flake.nix
+++ b/flake.nix
@@ -59,6 +59,8 @@
set +x
runHook postInstall
'';
+
+ passthru.tests = pkgs.testers.runNixOSTest (import ./nix/tests/test_1.nix self);
};
update-nix = pkgs.writeShellApplication {
@@ -88,5 +90,9 @@
];
};
}
- );
-}
\ No newline at end of file
+ )
+ //
+ {
+ nixosModules.default = import ./nix/modules/default self;
+ };
+}
diff --git a/nix/modules/default/default.nix b/nix/modules/default/default.nix
new file mode 100644
index 00000000..6a29e538
--- /dev/null
+++ b/nix/modules/default/default.nix
@@ -0,0 +1,99 @@
+self: { config, lib, pkgs, spacebar, ... }:
+
+let
+ cfg = config.services.spacebarchat-server;
+ jsonFormat = pkgs.formats.json {};
+ configFile = jsonFormat.generate "spacebarchat-server.json" cfg.settings;
+in
+{
+ options.services.spacebarchat-server = {
+ enable = lib.mkEnableOption "spacebarchat-server";
+ package = lib.mkPackageOption self.packages.${pkgs.stdenv.hostPlatform.system} "spacebar-server" { default = "default"; };
+ extraEnvironment = lib.mkOption {
+ default = {};
+ description = ''
+ Environment variables passed to spacebarchat-server.
+ See .
+ '';
+ type = lib.types.submodule {
+ freeformType = with lib.types; attrsOf (oneOf [ str bool ]);
+ options = {
+ THREADS = lib.mkOption {
+ type = lib.types.ints.positive;
+ default = 1;
+ description = "Number of threads to run Spacebar on when using bundle. Make sure you've enabled RabbitMQ if using more than one.";
+ };
+ PORT = lib.mkOption {
+ type = lib.types.port;
+ default = 3001;
+ description = "Port to listen on. Used by all components, including bundle. If using bundle, all components run under the same port";
+ };
+ DATABASE = lib.mkOption {
+ type = lib.types.str;
+ default = "database.db";
+ example = "postgres://username:passwort@host-IP:port/databaseName";
+ description = "Database connection string. Defaults to SQLite3 at project root";
+ };
+ };
+ };
+ };
+
+ settings = lib.mkOption {
+ type = jsonFormat.type;
+ default = {};
+ description = ''
+ Configuration for spacebarchat-server.
+ See for supported values.
+ '';
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ assertions = [ {
+ assertion = !((cfg.extraEnvironment.THREADS > 1) && !config.services.rabbitmq.enable);
+ message = "Make sure you've setup RabbitMQ when using more than one thread with Spacebar";
+ } ];
+
+ systemd.services.spacebarchat-server = {
+ description = "Spacebarchat Server";
+ documentation = [ "https://docs.spacebar.chat/" ];
+ wantedBy = [ "multi-user.target" ];
+ wants = [ "network-online.target" ];
+ after = [ "network-online.target" ];
+ environment = builtins.mapAttrs (_: val: builtins.toString val) (cfg.extraEnvironment // { CONFIG_PATH = configFile; CONFIG_READONLY = 1; });
+ serviceConfig = {
+ DynamicUser = true;
+ User = "spacebarchat-server";
+ LockPersonality = true;
+ ProtectClock = true;
+ ProtectControlGroups = true;
+ ProtectHostname = true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ PrivateDevices = true;
+ PrivateMounts = true;
+ PrivateUsers = true;
+ RestrictAddressFamilies = [
+ "AF_INET"
+ "AF_INET6"
+ ];
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ SystemCallArchitectures = "native";
+ SystemCallFilter = [
+ "@system-service"
+ "~@privileged"
+ ];
+ StateDirectory = "spacebarchat-server";
+ StateDirectoryMode = "0700";
+ ExecStart = "${cfg.package}/bin/start-bundle";
+ Restart = "on-failure";
+ RestartSec = 10;
+ StartLimitBurst = 5;
+ UMask = "077";
+ WorkingDirectory = "/var/lib/spacebarchat-server/";
+ };
+ };
+ };
+}
diff --git a/nix/tests/test_1.nix b/nix/tests/test_1.nix
new file mode 100644
index 00000000..54543e40
--- /dev/null
+++ b/nix/tests/test_1.nix
@@ -0,0 +1,16 @@
+self:
+{ config, lib, pkgs, ... }:
+
+{
+ name = "example-test";
+
+ nodes.machine = {
+ imports = [ self.nixosModules.default ];
+
+ services.spacebarchat-server.enable = true;
+ };
+
+ testScript = ''
+ machine.wait_for_unit("spacebarchat-server")
+ '';
+}