pinchflat: init

This commit is contained in:
ibizaman 2025-09-16 21:17:46 +02:00
parent 0355f11481
commit 5ef5ed0358
7 changed files with 610 additions and 8 deletions

View file

@ -163,6 +163,7 @@ Also, the stack fits together nicely thanks to [contracts](#contracts).
- Hledger - Hledger
- Home-Assistant - Home-Assistant
- Jellyfin - Jellyfin
- Pinchflat
- Vaultwarden - Vaultwarden
Like explained above, those services all benefit from Like explained above, those services all benefit from

View file

@ -3320,6 +3320,129 @@
"services-nextcloudserver-usage-version": [ "services-nextcloudserver-usage-version": [
"services-nextcloud.html#services-nextcloudserver-usage-version" "services-nextcloud.html#services-nextcloudserver-usage-version"
], ],
"services-pinchflat": [
"services-pinchflat.html#services-pinchflat"
],
"services-pinchflat-options": [
"services-pinchflat.html#services-pinchflat-options"
],
"services-pinchflat-options-shb.pinchflat.backup": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.backup"
],
"services-pinchflat-options-shb.pinchflat.backup.request": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.backup.request"
],
"services-pinchflat-options-shb.pinchflat.backup.request.excludePatterns": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.backup.request.excludePatterns"
],
"services-pinchflat-options-shb.pinchflat.backup.request.hooks": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.backup.request.hooks"
],
"services-pinchflat-options-shb.pinchflat.backup.request.hooks.afterBackup": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.backup.request.hooks.afterBackup"
],
"services-pinchflat-options-shb.pinchflat.backup.request.hooks.beforeBackup": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.backup.request.hooks.beforeBackup"
],
"services-pinchflat-options-shb.pinchflat.backup.request.sourceDirectories": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.backup.request.sourceDirectories"
],
"services-pinchflat-options-shb.pinchflat.backup.request.user": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.backup.request.user"
],
"services-pinchflat-options-shb.pinchflat.backup.result": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.backup.result"
],
"services-pinchflat-options-shb.pinchflat.backup.result.backupService": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.backup.result.backupService"
],
"services-pinchflat-options-shb.pinchflat.backup.result.restoreScript": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.backup.result.restoreScript"
],
"services-pinchflat-options-shb.pinchflat.domain": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.domain"
],
"services-pinchflat-options-shb.pinchflat.enable": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.enable"
],
"services-pinchflat-options-shb.pinchflat.ldap": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.ldap"
],
"services-pinchflat-options-shb.pinchflat.ldap.enable": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.ldap.enable"
],
"services-pinchflat-options-shb.pinchflat.ldap.userGroup": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.ldap.userGroup"
],
"services-pinchflat-options-shb.pinchflat.mediaDir": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.mediaDir"
],
"services-pinchflat-options-shb.pinchflat.port": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.port"
],
"services-pinchflat-options-shb.pinchflat.secretKeyBase": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.secretKeyBase"
],
"services-pinchflat-options-shb.pinchflat.secretKeyBase.request": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.secretKeyBase.request"
],
"services-pinchflat-options-shb.pinchflat.secretKeyBase.request.group": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.secretKeyBase.request.group"
],
"services-pinchflat-options-shb.pinchflat.secretKeyBase.request.mode": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.secretKeyBase.request.mode"
],
"services-pinchflat-options-shb.pinchflat.secretKeyBase.request.owner": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.secretKeyBase.request.owner"
],
"services-pinchflat-options-shb.pinchflat.secretKeyBase.request.restartUnits": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.secretKeyBase.request.restartUnits"
],
"services-pinchflat-options-shb.pinchflat.secretKeyBase.result": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.secretKeyBase.result"
],
"services-pinchflat-options-shb.pinchflat.secretKeyBase.result.path": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.secretKeyBase.result.path"
],
"services-pinchflat-options-shb.pinchflat.ssl": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.ssl"
],
"services-pinchflat-options-shb.pinchflat.ssl.paths": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.ssl.paths"
],
"services-pinchflat-options-shb.pinchflat.ssl.paths.cert": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.ssl.paths.cert"
],
"services-pinchflat-options-shb.pinchflat.ssl.paths.key": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.ssl.paths.key"
],
"services-pinchflat-options-shb.pinchflat.ssl.systemdService": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.ssl.systemdService"
],
"services-pinchflat-options-shb.pinchflat.sso": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.sso"
],
"services-pinchflat-options-shb.pinchflat.sso.authEndpoint": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.sso.authEndpoint"
],
"services-pinchflat-options-shb.pinchflat.sso.authorization_policy": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.sso.authorization_policy"
],
"services-pinchflat-options-shb.pinchflat.sso.enable": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.sso.enable"
],
"services-pinchflat-options-shb.pinchflat.subdomain": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.subdomain"
],
"services-pinchflat-options-shb.pinchflat.timeZone": [
"services-pinchflat.html#services-pinchflat-options-shb.pinchflat.timeZone"
],
"services-pinchflat-usage": [
"services-pinchflat.html#services-pinchflat-usage"
],
"services-pinchflat-usage-backup": [
"services-pinchflat.html#services-pinchflat-usage-backup"
],
"services-vaultwarden": [ "services-vaultwarden": [
"services-vaultwarden.html#services-vaultwarden" "services-vaultwarden.html#services-vaultwarden"
], ],

View file

@ -11,14 +11,15 @@ Not all services are yet documented. You can find all available services [in the
The following table summarizes for each documented service what features it provides. More The following table summarizes for each documented service what features it provides. More
information is provided in the respective manual sections. information is provided in the respective manual sections.
| Service | Backup | Reverse Proxy | SSO | LDAP | Monitoring | Profiling | | Service | Backup | Reverse Proxy | SSO | LDAP | Monitoring | Profiling |
|-----------------------|--------|---------------|-----|-------|------------|-----------| |----------------------|--------|---------------|-----|-------|------------|-----------|
| [*Arr][] | Y (1) | Y | Y | Y (4) | Y (2) | N | | [*Arr][] | Y (1) | Y | Y | Y (4) | Y (2) | N |
| [Forgejo][] | Y (1) | Y | Y | Y | Y (2) | N | | [Forgejo][] | Y (1) | Y | Y | Y | Y (2) | N |
| [Jellyfin][] | Y (1) | Y | Y | Y | Y (2) | N | | [Jellyfin][] | Y (1) | Y | Y | Y | Y (2) | N |
| [Home-Assistant][] | Y (1) | Y | N | Y | Y (2) | N | | [Home-Assistant][] | Y (1) | Y | N | Y | Y (2) | N |
| [Nextcloud Server][] | Y (1) | Y | Y | Y | Y (2) | P (3) | | [Nextcloud Server][] | Y (1) | Y | Y | Y | Y (2) | P (3) |
| [Vaultwarden][] | Y (1) | Y | Y | Y | Y (2) | N | | [Pinchflat][] | Y | Y | Y | Y (4) | Y (5) | N |
| [Vaultwarden][] | Y (1) | Y | Y | Y | Y (2) | N |
Legend: **N**: no but WIP; **P**: partial; **Y**: yes Legend: **N**: no but WIP; **P**: partial; **Y**: yes
@ -34,6 +35,7 @@ Legend: **N**: no but WIP; **P**: partial; **Y**: yes
[Home-Assistant]: services-home-assistant.html [Home-Assistant]: services-home-assistant.html
[Jellyfin]: services-jellyfin.html [Jellyfin]: services-jellyfin.html
[Nextcloud Server]: services-nextcloud.html [Nextcloud Server]: services-nextcloud.html
[Pinchflat]: services-pinchflat.html
[Vaultwarden]: services-vaultwarden.html [Vaultwarden]: services-vaultwarden.html
```{=include=} chapters html:into-file=//services-arr.html ```{=include=} chapters html:into-file=//services-arr.html
@ -56,6 +58,10 @@ modules/services/home-assistant/docs/default.md
modules/services/nextcloud-server/docs/default.md modules/services/nextcloud-server/docs/default.md
``` ```
```{=include=} chapters html:into-file=//services-pinchflat.html
modules/services/pinchflat/docs/default.md
```
```{=include=} chapters html:into-file=//services-vaultwarden.html ```{=include=} chapters html:into-file=//services-vaultwarden.html
modules/services/vaultwarden/docs/default.md modules/services/vaultwarden/docs/default.md
``` ```

View file

@ -81,6 +81,7 @@
self.nixosModules.${system}.assistant self.nixosModules.${system}.assistant
self.nixosModules.${system}.jellyfin self.nixosModules.${system}.jellyfin
self.nixosModules.${system}.nextcloud-server self.nixosModules.${system}.nextcloud-server
self.nixosModules.${system}.pinchflat
self.nixosModules.${system}.vaultwarden self.nixosModules.${system}.vaultwarden
]; ];
}; };
@ -114,6 +115,7 @@
nixosModules.assistant = modules/services/home-assistant.nix; nixosModules.assistant = modules/services/home-assistant.nix;
nixosModules.jellyfin = modules/services/jellyfin.nix; nixosModules.jellyfin = modules/services/jellyfin.nix;
nixosModules.nextcloud-server = modules/services/nextcloud-server.nix; nixosModules.nextcloud-server = modules/services/nextcloud-server.nix;
nixosModules.pinchflat = modules/services/pinchflat.nix;
nixosModules.vaultwarden = modules/services/vaultwarden.nix; nixosModules.vaultwarden = modules/services/vaultwarden.nix;
packages.manualHtml = pkgs.callPackage ./docs { packages.manualHtml = pkgs.callPackage ./docs {
@ -142,6 +144,7 @@
"services/home-assistant" = ./modules/services/home-assistant.nix; "services/home-assistant" = ./modules/services/home-assistant.nix;
"services/jellyfin" = ./modules/services/jellyfin.nix; "services/jellyfin" = ./modules/services/jellyfin.nix;
"services/nextcloud-server" = ./modules/services/nextcloud-server.nix; "services/nextcloud-server" = ./modules/services/nextcloud-server.nix;
"services/pinchflat" = ./modules/services/pinchflat.nix;
"services/vaultwarden" = ./modules/services/vaultwarden.nix; "services/vaultwarden" = ./modules/services/vaultwarden.nix;
"contracts/backup" = ./modules/contracts/backup/dummyModule.nix; "contracts/backup" = ./modules/contracts/backup/dummyModule.nix;
"contracts/databasebackup" = ./modules/contracts/databasebackup/dummyModule.nix; "contracts/databasebackup" = ./modules/contracts/databasebackup/dummyModule.nix;
@ -257,6 +260,7 @@
// (vm_test "jellyfin" ./test/services/jellyfin.nix) // (vm_test "jellyfin" ./test/services/jellyfin.nix)
// (vm_test "monitoring" ./test/services/monitoring.nix) // (vm_test "monitoring" ./test/services/monitoring.nix)
// (vm_test "nextcloud" ./test/services/nextcloud.nix) // (vm_test "nextcloud" ./test/services/nextcloud.nix)
// (vm_test "pinchflat" ./test/services/pinchflat.nix)
// (vm_test "vaultwarden" ./test/services/vaultwarden.nix) // (vm_test "vaultwarden" ./test/services/vaultwarden.nix)
// (vm_test "authelia" ./test/blocks/authelia.nix) // (vm_test "authelia" ./test/blocks/authelia.nix)

View file

@ -0,0 +1,191 @@
{ config, lib, pkgs, ... }:
let
cfg = config.shb.pinchflat;
inherit (lib) types;
contracts = pkgs.callPackage ../contracts {};
shblib = pkgs.callPackage ../../lib {};
in
{
options.shb.pinchflat = {
enable = lib.mkEnableOption "the Pinchflat service.";
subdomain = lib.mkOption {
type = lib.types.str;
description = "Subdomain under which Pinchflat will be served.";
default = "pinchflat";
};
domain = lib.mkOption {
type = lib.types.str;
description = "domain under which Pinchflat will be served.";
example = "mydomain.com";
};
ssl = lib.mkOption {
description = "Path to SSL files";
type = lib.types.nullOr contracts.ssl.certs;
default = null;
};
port = lib.mkOption {
type = lib.types.port;
description = "Port Pinchflat listens to incoming requests.";
default = 8945;
};
secretKeyBase = lib.mkOption {
description = ''
Used to sign/encrypt cookies and other secrets.
Make sure the secret is at least 64 characters long.
'';
type = types.submodule {
options = contracts.secret.mkRequester {
restartUnits = [ "pinchflat.service" ];
};
};
};
mediaDir = lib.mkOption {
description = "Path where videos are stored.";
type = lib.types.str;
};
timeZone = lib.mkOption {
type = lib.types.oneOf [ lib.types.str shblib.secretFileType ];
description = "Timezone of this instance.";
example = "America/Los_Angeles";
};
ldap = lib.mkOption {
description = ''
Setup LDAP integration.
'';
default = {};
type = types.submodule {
options = {
enable = lib.mkEnableOption "LDAP integration." // {
default = cfg.sso.enable;
};
userGroup = lib.mkOption {
type = types.str;
description = "Group users must belong to be able to login.";
default = "pinchflat_user";
};
};
};
};
sso = lib.mkOption {
description = ''
Setup SSO integration.
'';
default = {};
type = types.submodule {
options = {
enable = lib.mkEnableOption "SSO integration.";
authEndpoint = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "Endpoint to the SSO provider. Leave null to not have SSO configured.";
example = "https://authelia.example.com";
};
authorization_policy = lib.mkOption {
type = types.enum [ "one_factor" "two_factor" ];
description = "Require one factor (password) or two factor (device) authentication.";
default = "one_factor";
};
};
};
};
backup = lib.mkOption {
description = ''
Backup media directory `shb.mediaDir`.
'';
default = {};
type = lib.types.submodule {
options = contracts.backup.mkRequester {
user = "pinchflat";
sourceDirectories = [
cfg.mediaDir
];
sourceDirectoriesText = "[ config.shb.pinchflat.mediaDir ]";
};
};
};
};
config = lib.mkIf cfg.enable {
systemd.tmpfiles.rules = [
"d '/etc/pinchflat' 0750 root root - -"
];
# Pinchflat relies on the global value so for now this is the only way to pass the option in.
time.timeZone = lib.mkDefault cfg.timeZone;
services.pinchflat = {
inherit (cfg) enable port mediaDir;
secretsFile = "/etc/pinchflat/secrets.env";
extraConfig = {
ENABLE_PROMETHEUS = true;
# TZ = "as"; # I consider where you live to be sensible so it should be passed as a secret.
};
};
# This should be using a contract instead of setting the option directly.
shb.lldap = lib.mkIf config.shb.ldap.enable {
ensureGroups = { ${cfg.ldap.userGroup} = {}; };
};
systemd.services.pinchflat-pre = {
script = shblib.replaceSecrets {
userConfig = {
SECRET_KEY_BASE.source = cfg.secretKeyBase.result.path;
# TZ = cfg.secretKeyBase.result.path; # Uncomment when PR is merged.
};
resultPath = "/etc/pinchflat/secrets.env";
generator = shblib.toEnvVar;
};
serviceConfig.Type = "oneshot";
wantedBy = [ "multi-user.target" ];
before = [ "pinchflat.service" ];
requiredBy = [ "pinchflat.service" ];
};
shb.nginx.vhosts = [
{
inherit (cfg) subdomain domain ssl;
inherit (cfg.sso) authEndpoint;
upstream = "http://127.0.0.1:${toString cfg.port}";
autheliaRules = lib.optionals (cfg.sso.enable) [
{
domain = "${cfg.subdomain}.${cfg.domain}";
policy = cfg.sso.authorization_policy;
subject = [ "group:${cfg.ldap.userGroup}" ];
}
];
}
];
services.prometheus.scrapeConfigs = [
{
job_name = "pinchflat";
static_configs = [
{
targets = ["127.0.0.1:${toString cfg.port}"];
labels = {
"hostname" = config.networking.hostName;
"domain" = cfg.domain;
};
}
];
}
];
};
}

View file

@ -0,0 +1,70 @@
# Pinchflat Service {#services-pinchflat}
Defined in [`/modules/services/pinchflat.nix`](@REPO@/modules/services/pinchflat.nix).
This NixOS module is a service that sets up a [Pinchflat](https://github.com/kieraneglin/pinchflat) instance.
Compared to the stock module from nixpkgs,
this one sets up, in a fully declarative manner,
LDAP and SSO integration
and has a nicer option for secrets.
## Usage {#services-pinchflat-usage}
The following snippet assumes a few blocks have been setup already:
- the [secrets block](usage.html#usage-secrets) with SOPS,
- the [`shb.ssl` block](blocks-ssl.html#usage),
- the [`shb.lldap` block](blocks-lldap.html#blocks-lldap-global-setup).
- the [`shb.authelia` block](blocks-authelia.html#blocks-sso-global-setup).
```nix
shb.pinchflat = {
enable = true;
secretKeyBase.result = config.shb.sops.secret."pinchflat/secretKeyBase".result;
timeZone = "Europe/Brussels";
mediaDir = "/srv/pinchflat";
domain = "example.com";
subdomain = "pinchflat";
ssl = config.shb.certs.certs.letsencrypt.${domain};
ldap = {
enable = true;
userGroup = "pinchflat_user";
};
sso = {
enable = true;
authEndpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}";
};
};
shb.sops.secret."pinchflat/secretKeyBase".request = config.shb.pinchflat.secretKeyBase.request;
```
Secrets can be randomly generated with `nix run nixpkgs#openssl -- rand -hex 64`.
## Backup {#services-pinchflat-usage-backup}
Backing up Pinchflat using the [Restic block](blocks-restic.html) is done like so:
```nix
shb.restic.instances."pinchflat" = {
request = config.shb.pinchflat.backup;
settings = {
enable = true;
};
};
```
The name `"pinchflat"` in the `instances` can be anything.
The `config.shb.pinchflat.backup` option provides what directories to backup.
You can define any number of Restic instances to backup Pinchflat multiple times.
## Options Reference {#services-pinchflat-options}
```{=include=} options
id-prefix: services-pinchflat-options-
list-id: selfhostblocks-service-pinchflat-options
source: @OPTIONS_JSON@
```

207
test/services/pinchflat.nix Normal file
View file

@ -0,0 +1,207 @@
{ pkgs, ... }:
let
testLib = pkgs.callPackage ../common.nix {};
commonTestScript = testLib.mkScripts {
hasSSL = { node, ... }: !(isNull node.config.shb.pinchflat.ssl);
waitForServices = { ... }: [
"pinchflat.service"
"nginx.service"
];
waitForPorts = { node, ... }: [
node.config.shb.pinchflat.port
];
};
basic = { config, ... }: {
imports = [
testLib.baseModule
../../modules/blocks/hardcodedsecret.nix
../../modules/blocks/lldap.nix
../../modules/services/pinchflat.nix
];
test = {
subdomain = "p";
};
shb.pinchflat = {
enable = true;
inherit (config.test) subdomain domain;
mediaDir = "/src/pinchflat";
timeZone = "America/Los_Angeles";
secretKeyBase.result = config.shb.hardcodedsecret.secretKeyBase.result;
};
systemd.tmpfiles.rules = [
"d '/src/pinchflat' 0750 pinchflat pinchflat - -"
];
# Needed for gitea-runner-local to be able to ping pinchflat.
networking.hosts = {
"127.0.0.1" = [ "${config.test.subdomain}.${config.test.domain}" ];
};
shb.hardcodedsecret.secretKeyBase = {
request = config.shb.pinchflat.secretKeyBase.request;
settings.content = pkgs.lib.strings.replicate 64 "Z";
};
};
clientLogin = { config, ... }: {
imports = [
testLib.baseModule
testLib.clientLoginModule
];
test = {
subdomain = "p";
};
test.login = {
startUrl = "http://${config.test.fqdn}";
# There is no login without SSO integration.
testLoginWith = [
{ username = null; password = null; nextPageExpect = [
"expect(page.get_by_text('Create a media profile')).to_be_visible()"
]; }
];
};
};
https = { config, ... }: {
shb.pinchflat = {
ssl = config.shb.certs.certs.selfsigned.n;
};
};
ldap = { config, ... }: {
shb.pinchflat = {
ldap = {
enable = true;
userGroup = "user_group";
};
};
};
clientLoginSso = { config, ... }: {
imports = [
testLib.baseModule
testLib.clientLoginModule
];
test = {
subdomain = "p";
};
test.login = {
startUrl = "https://${config.test.fqdn}";
usernameFieldLabelRegex = "Username";
passwordFieldLabelRegex = "Password";
loginButtonNameRegex = "[sS]ign [iI]n";
testLoginWith = [
{ username = "alice"; password = "NotAlicePassword"; nextPageExpect = [
"expect(page.get_by_text(re.compile('[Ii]ncorrect'))).to_be_visible()"
]; }
{ username = "alice"; password = "AlicePassword"; nextPageExpect = [
"expect(page.get_by_text(re.compile('[Ii]ncorrect'))).not_to_be_visible()"
"expect(page.get_by_role('button', name=re.compile('Sign In'))).not_to_be_visible()"
"expect(page.get_by_text('Create a media profile')).to_be_visible()"
]; }
{ username = "bob"; password = "NotBobPassword"; nextPageExpect = [
"expect(page.get_by_text(re.compile('[Ii]ncorrect'))).to_be_visible()"
]; }
{ username = "bob"; password = "BobPassword"; nextPageExpect = [
"expect(page.get_by_text(re.compile('[Ii]ncorrect'))).not_to_be_visible()"
"expect(page.get_by_role('button', name=re.compile('Sign In'))).not_to_be_visible()"
"expect(page.get_by_text('Create a media profile')).to_be_visible()"
]; }
];
};
};
sso = { config, ... }: {
shb.pinchflat = {
sso = {
enable = true;
authEndpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}";
};
};
};
in
{
basic = pkgs.testers.runNixOSTest {
name = "pinchflat_basic";
nodes.client = {
imports = [
clientLogin
];
};
nodes.server = {
imports = [
basic
];
};
testScript = commonTestScript.access;
};
backup = pkgs.testers.runNixOSTest {
name = "pinchflat_backup";
nodes.server = { config, ... }: {
imports = [
basic
(testLib.backup config.shb.pinchflat.backup)
];
};
nodes.client = {};
testScript = commonTestScript.backup;
};
https = pkgs.testers.runNixOSTest {
name = "pinchflat_https";
nodes.client = {
imports = [
clientLogin
];
};
nodes.server = {
imports = [
basic
testLib.certs
https
];
};
testScript = commonTestScript.access;
};
sso = pkgs.testers.runNixOSTest {
name = "pinchflat_sso";
nodes.client = {
imports = [
clientLoginSso
];
};
nodes.server = { config, pkgs, ... }: {
imports = [
basic
testLib.certs
https
testLib.ldap
ldap
(testLib.sso config.shb.certs.certs.selfsigned.n)
sso
];
};
testScript = commonTestScript.access.override {
redirectSSO = true;
};
};
}