2023-09-30 10:58:24 +00:00
|
|
|
{ config, pkgs, lib, ... }:
|
2023-03-18 11:00:49 +00:00
|
|
|
let
|
2023-09-30 10:58:24 +00:00
|
|
|
cfg = config.services.lenticular-cloud;
|
|
|
|
python = pkgs.python3;
|
2023-12-17 13:47:38 +00:00
|
|
|
format = pkgs.formats.json {};
|
|
|
|
types = lib.types;
|
2023-12-23 01:41:26 +00:00
|
|
|
config_oauth_secret = "${cfg.settings.DATA_FOLDER}/lenticular_oauth_secret.toml";
|
2023-12-24 10:10:19 +00:00
|
|
|
python_env = python.withPackages (ps: with ps; [ lenticular-cloud gevent setuptools ]);
|
2023-03-18 11:00:49 +00:00
|
|
|
in
|
|
|
|
{
|
|
|
|
options = with lib.options; {
|
2023-10-20 07:58:32 +00:00
|
|
|
services.lenticular-cloud = {
|
2023-03-18 11:00:49 +00:00
|
|
|
enable = mkEnableOption "lenticluar service enable";
|
2023-10-09 19:58:44 +00:00
|
|
|
domain = mkOption {
|
2023-11-13 14:15:39 +00:00
|
|
|
type = lib.types.str;
|
|
|
|
example = "example.com";
|
|
|
|
};
|
2023-12-17 13:47:38 +00:00
|
|
|
username = mkOption {
|
|
|
|
type = lib.types.str;
|
|
|
|
description = mdDoc "user to run the service";
|
2023-12-17 14:31:19 +00:00
|
|
|
default = "lenticular_cloud";
|
2023-12-17 13:47:38 +00:00
|
|
|
};
|
2023-11-13 14:15:39 +00:00
|
|
|
service_domain = mkOption {
|
2023-10-09 19:58:44 +00:00
|
|
|
type = lib.types.str;
|
|
|
|
example = "account.example.com";
|
|
|
|
};
|
|
|
|
settings = mkOption {
|
2023-12-17 13:47:38 +00:00
|
|
|
description = mdDoc ''
|
|
|
|
Lenticular cloud settings
|
|
|
|
'';
|
2023-10-09 19:58:44 +00:00
|
|
|
|
2023-12-17 13:47:38 +00:00
|
|
|
default = { };
|
|
|
|
|
|
|
|
type = types.submodule {
|
|
|
|
freeformType = format.type;
|
|
|
|
options = {
|
|
|
|
DOMAIN = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
description = mdDoc "Top level Domain of the service";
|
|
|
|
default = cfg.domain;
|
|
|
|
};
|
|
|
|
PUBLIC_URL = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
description = mdDoc "public service url";
|
|
|
|
default = "https://${cfg.service_domain}";
|
|
|
|
};
|
2023-12-24 10:09:41 +00:00
|
|
|
ADMINS = mkOption {
|
|
|
|
type = types.listOf types.str;
|
|
|
|
description = mdDoc "list of admin users";
|
|
|
|
example = [ "tuxcoder" ];
|
|
|
|
};
|
2023-12-17 13:47:38 +00:00
|
|
|
DATA_FOLDER = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "/var/lib/${cfg.username}";
|
|
|
|
};
|
|
|
|
PKI_PATH = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "${cfg.settings.DATA_FOLDER}/pki";
|
|
|
|
};
|
|
|
|
SQLALCHEMY_DATABASE_URI = mkOption {
|
|
|
|
type = types.str;
|
2023-12-17 14:31:19 +00:00
|
|
|
default = "postgresql://${cfg.username}@/${cfg.username}?host=/run/postgresql";
|
2023-12-17 13:47:38 +00:00
|
|
|
};
|
|
|
|
HYDRA_ADMIN_URL = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "https://${config.services.ory-hydra.admin_domain}";
|
|
|
|
};
|
|
|
|
HYDRA_PUBLIC_URL = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "https://${config.services.ory-hydra.public_domain}";
|
2023-12-25 23:24:28 +00:00
|
|
|
};
|
|
|
|
LENTICULAR_CLOUD_SERVICES = mkOption {
|
|
|
|
type = types.attrsOf (types.submodule {
|
|
|
|
options = {
|
|
|
|
app_token = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "enables the app token function for this service";
|
|
|
|
};
|
|
|
|
href = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
example = "https://service.example.com";
|
|
|
|
description = "Link to the hosted service";
|
|
|
|
};
|
|
|
|
icon = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
example = "https://service.example.com/favicon.png";
|
|
|
|
description = "Link to an icon of the service";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
});
|
|
|
|
default = {};
|
|
|
|
};
|
2023-12-17 13:47:38 +00:00
|
|
|
};
|
|
|
|
};
|
2023-10-09 19:58:44 +00:00
|
|
|
};
|
2023-03-18 11:00:49 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
config = {
|
2023-09-30 10:58:24 +00:00
|
|
|
environment.systemPackages = [ pkgs.lenticular-cloud ];
|
|
|
|
|
|
|
|
nixpkgs.overlays = [
|
|
|
|
(import ./overlay.nix)
|
|
|
|
];
|
2023-03-18 11:00:49 +00:00
|
|
|
|
|
|
|
users = {
|
2023-12-17 14:31:19 +00:00
|
|
|
groups."${cfg.username}" = {
|
2023-03-18 11:00:49 +00:00
|
|
|
};
|
2023-12-17 14:31:19 +00:00
|
|
|
users."${cfg.username}" = {
|
2023-03-18 11:00:49 +00:00
|
|
|
createHome = true;
|
2023-12-17 14:31:19 +00:00
|
|
|
home = "/var/lib/${cfg.username}";
|
2023-03-18 11:00:49 +00:00
|
|
|
description = "web server";
|
|
|
|
extraGroups = [
|
2023-10-09 19:58:44 +00:00
|
|
|
# "ory-hydra"
|
2023-03-18 11:00:49 +00:00
|
|
|
];
|
2023-12-17 14:31:19 +00:00
|
|
|
group = cfg.username;
|
2023-03-18 11:00:49 +00:00
|
|
|
isSystemUser = true;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2023-10-09 19:58:44 +00:00
|
|
|
services.postgresql = {
|
|
|
|
enable = true;
|
2023-12-17 14:31:19 +00:00
|
|
|
ensureDatabases = [ cfg.username ];
|
2023-10-09 19:58:44 +00:00
|
|
|
ensureUsers = [
|
|
|
|
{
|
2023-12-17 14:31:19 +00:00
|
|
|
name = cfg.username;
|
2023-12-17 13:47:38 +00:00
|
|
|
ensureDBOwnership = true;
|
2023-10-09 19:58:44 +00:00
|
|
|
}
|
|
|
|
];
|
2023-12-17 13:47:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
services.ory-hydra.settings = {
|
|
|
|
urls = {
|
|
|
|
login = "${cfg.settings.PUBLIC_URL}/auth/login";
|
|
|
|
logout = "${cfg.settings.PUBLIC_URL}/auth/logout";
|
|
|
|
consent = "${cfg.settings.PUBLIC_URL}/auth/consent";
|
|
|
|
error = "${cfg.settings.PUBLIC_URL}/auth/error";
|
|
|
|
};
|
2023-10-09 19:58:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
services.nginx.enable = true;
|
2023-11-13 14:15:39 +00:00
|
|
|
services.nginx.virtualHosts."${cfg.service_domain}" = {
|
2023-10-09 19:58:44 +00:00
|
|
|
addSSL = true;
|
|
|
|
enableACME = true;
|
2023-11-13 14:15:39 +00:00
|
|
|
serverName = cfg.service_domain;
|
2023-10-09 19:58:44 +00:00
|
|
|
locations."/" = {
|
|
|
|
recommendedProxySettings = true;
|
2023-12-17 14:31:19 +00:00
|
|
|
proxyPass = "http://unix:/run/${cfg.username}/web.sock";
|
2023-10-09 19:58:44 +00:00
|
|
|
};
|
|
|
|
};
|
2023-12-17 14:31:19 +00:00
|
|
|
users.users.nginx.extraGroups = [ cfg.username ];
|
2023-10-09 19:58:44 +00:00
|
|
|
|
2023-03-18 11:00:49 +00:00
|
|
|
systemd.services.lenticular-cloud = {
|
|
|
|
description = "lenticular account";
|
|
|
|
after = [ "network.target" ];
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
2023-10-20 07:58:32 +00:00
|
|
|
requires = [ "ory-hydra.service" "postgresql.service" ];
|
2023-09-30 10:58:24 +00:00
|
|
|
enable = cfg.enable;
|
2023-03-18 11:00:49 +00:00
|
|
|
|
|
|
|
environment = let
|
2023-12-23 01:41:26 +00:00
|
|
|
config_file = format.generate "lenticular-cloud.json" cfg.settings;
|
2023-03-18 11:00:49 +00:00
|
|
|
in {
|
2023-10-09 19:58:44 +00:00
|
|
|
# CONFIG_FILE = "/etc/lenticular_cloud/production.conf";
|
2023-12-23 01:41:26 +00:00
|
|
|
CONFIG_FILE = "${config_file}:${config_oauth_secret}";
|
2023-03-18 11:00:49 +00:00
|
|
|
};
|
2023-10-09 19:58:44 +00:00
|
|
|
preStart = ''
|
2023-12-23 01:41:26 +00:00
|
|
|
if [[ ! -e "${config_oauth_secret}" ]]; then
|
|
|
|
SECRET_KEY=`${pkgs.openssl}/bin/openssl rand --hex 16`
|
|
|
|
echo 'OAUTH_SECRET="$${SECRET_KEY}"' > ${config_oauth_secret}
|
|
|
|
echo "oauth secreted generated"
|
|
|
|
fi
|
2023-10-09 19:58:44 +00:00
|
|
|
${pkgs.lenticular-cloud}/bin/lenticular_cloud-cli db_upgrade
|
|
|
|
'';
|
2023-03-18 11:00:49 +00:00
|
|
|
|
|
|
|
serviceConfig = {
|
|
|
|
Type = "simple";
|
2023-12-17 14:31:19 +00:00
|
|
|
WorkingDirectory = cfg.settings.DATA_FOLDER;
|
|
|
|
User = cfg.username;
|
2023-12-24 10:10:19 +00:00
|
|
|
ExecStart = ''${python_env}/bin/gunicorn lenticular_cloud.wsgi --name lenticular_cloud \
|
2023-12-23 01:41:26 +00:00
|
|
|
--workers 2 --log-level=info \
|
2023-12-17 14:31:19 +00:00
|
|
|
--bind=unix:/run/${cfg.username}/web.sock \
|
2023-03-18 11:00:49 +00:00
|
|
|
-k gevent'';
|
|
|
|
Restart = "on-failure";
|
2023-12-17 14:31:19 +00:00
|
|
|
RuntimeDirectory = cfg.username;
|
2023-03-18 11:00:49 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
}
|