1
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-06-24 18:16:21 +03:00
nixpkgs/nixos/modules/services/web-apps/opencloud.nix

256 lines
7.5 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
inherit (lib) types;
cfg = config.services.opencloud;
defaultUser = "opencloud";
defaultGroup = defaultUser;
settingsFormat = pkgs.formats.yaml { };
in
{
options = {
services.opencloud = {
enable = lib.mkEnableOption "OpenCloud";
package = lib.mkPackageOption pkgs "opencloud" { };
webPackage = lib.mkPackageOption pkgs [ "opencloud" "web" ] { };
idpWebPackage = lib.mkPackageOption pkgs [ "opencloud" "idp-web" ] { };
user = lib.mkOption {
type = types.str;
default = defaultUser;
example = "mycloud";
description = ''
The user to run OpenCloud as.
By default, a user named `${defaultUser}` will be created whose home
directory is [](#opt-services.opencloud.stateDir).
'';
};
group = lib.mkOption {
type = types.str;
default = defaultGroup;
example = "mycloud";
description = ''
The group to run OpenCloud under.
By default, a group named `${defaultGroup}` will be created.
'';
};
address = lib.mkOption {
type = types.str;
default = "127.0.0.1";
description = "Web server bind address.";
};
port = lib.mkOption {
type = types.port;
default = 9200;
description = "Web server port.";
};
url = lib.mkOption {
type = types.str;
default = "https://localhost:9200";
example = "https://cloud.example.com";
description = "Web interface root public URL, including scheme and port (if non-default).";
};
stateDir = lib.mkOption {
default = "/var/lib/opencloud";
type = types.str;
description = "OpenCloud data directory.";
};
settings = lib.mkOption {
type = lib.types.attrsOf settingsFormat.type;
default = { };
description = ''
Additional YAML configuration for OpenCloud services.
Every item in this attrset will be mapped to a .yaml file in /etc/opencloud.
The possible config options are currently not well documented, see source code:
https://github.com/opencloud-eu/opencloud/blob/main/pkg/config/config.go
'';
example = {
proxy = {
auto_provision_accounts = true;
oidc.rewrite_well_known = true;
role_assignment = {
driver = "oidc";
oidc_role_mapper.role_claim = "opencloud_roles";
};
};
web.web.config.oidc.scope = "openid profile email opencloud_roles";
};
};
environmentFile = lib.mkOption {
type = types.nullOr types.path;
default = null;
example = "/run/keys/opencloud.env";
description = ''
An environment file as defined in {manpage}`systemd.exec(5)`.
Use this to inject secrets, e.g. database or auth credentials out of band.
Configuration provided here will override `settings` and `environment`.
'';
};
environment = lib.mkOption {
type = types.attrsOf types.str;
default = {
OC_INSECURE = "true";
};
description = ''
Extra environment variables to set for the service.
Use this to set configuration that may affect multiple microservices.
Set `OC_INSECURE = "false"` if you want OpenCloud to terminate TLS.
Configuration provided here will override `settings`.
'';
example = {
OC_INSECURE = "false";
OC_LOG_LEVEL = "error";
};
};
};
};
config = lib.mkIf cfg.enable {
users.users.${defaultUser} = lib.mkIf (cfg.user == defaultUser) {
group = cfg.group;
home = cfg.stateDir;
isSystemUser = true;
createHome = true;
description = "OpenCloud daemon user";
};
users.groups = lib.mkIf (cfg.group == defaultGroup) { ${defaultGroup} = { }; };
systemd = {
services =
let
environment = {
PROXY_HTTP_ADDR = "${cfg.address}:${toString cfg.port}";
OC_URL = cfg.url;
OC_BASE_DATA_PATH = cfg.stateDir;
WEB_ASSET_CORE_PATH = "${cfg.webPackage}";
IDP_ASSET_PATH = "${cfg.idpWebPackage}/assets";
OC_CONFIG_DIR = "/etc/opencloud";
} // cfg.environment;
commonServiceConfig = {
EnvironmentFile = lib.optional (cfg.environmentFile != null) cfg.environmentFile;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateTmp = true;
PrivateDevices = true;
ProtectSystem = "strict";
ProtectHome = true;
ProtectControlGroups = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectKernelLogs = true;
RestrictAddressFamilies = [
"AF_UNIX"
"AF_INET"
"AF_INET6"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
LockPersonality = true;
SystemCallArchitectures = "native";
};
in
{
opencloud-init-config = lib.mkIf (cfg.settings.opencloud or { } == { }) {
description = "Provision initial OpenCloud config";
before = [ "opencloud.service" ];
wantedBy = [ "multi-user.target" ];
inherit environment;
serviceConfig = {
Type = "oneshot";
ReadWritePaths = [ "/etc/opencloud" ];
} // commonServiceConfig;
path = [ cfg.package ];
script = ''
set -x
config="''${OC_CONFIG_DIR}/opencloud.yaml"
if [ ! -e "$config" ]; then
echo "Provisioning initial OpenCloud config..."
opencloud init --insecure "''${OC_INSECURE:false}" --config-path "''${OC_CONFIG_DIR}"
chown ${cfg.user}:${cfg.group} "$config"
fi
'';
};
opencloud = {
description = "OpenCloud - a secure and private way to store, access, and share your files";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
inherit environment;
serviceConfig = {
Type = "simple";
ExecStart = "${lib.getExe cfg.package} server";
WorkingDirectory = cfg.stateDir;
User = cfg.user;
Group = cfg.group;
Restart = "always";
ReadWritePaths = [ cfg.stateDir ];
} // commonServiceConfig;
restartTriggers = lib.mapAttrsToList (
name: _: config.environment.etc."opencloud/${name}.yaml".source
) cfg.settings;
};
};
};
systemd.tmpfiles.settings."10-opencloud" = {
${cfg.stateDir}.d = {
inherit (cfg) user group;
mode = "0750";
};
"${cfg.stateDir}/idm".d = {
inherit (cfg) user group;
mode = "0750";
};
};
environment.etc =
(lib.mapAttrs' (name: value: {
name = "opencloud/${name}.yaml";
value.source = settingsFormat.generate "${name}.yaml" value;
}) cfg.settings)
// {
# ensure /etc/opencloud gets created, so we can provision the config
"opencloud/.keep".text = "";
};
};
meta = {
doc = ./opencloud.md;
maintainers = with lib.maintainers; [
christoph-heiss
k900
];
};
}