Only launch ejabberd if env is available

This commit is contained in:
niten 2023-10-15 21:10:05 -07:00
parent c629223e85
commit 356c452d66

View File

@ -6,7 +6,8 @@ let
host-secrets = config.fudo.secrets.host-secrets.${hostname}; host-secrets = config.fudo.secrets.host-secrets.${hostname};
siteOpts = { ... }: with types; { siteOpts = { ... }:
with types; {
options = { options = {
enableACME = mkOption { enableACME = mkOption {
type = bool; type = bool;
@ -28,24 +29,22 @@ let
config-dir = dirOf cfg.config-file; config-dir = dirOf cfg.config-file;
concatMapAttrs = f: attrs: concatMapAttrs = f: attrs: foldr (a: b: a // b) { } (mapAttrs f attrs);
foldr (a: b: a // b) {} (mapAttrs f attrs);
concatMapAttrsToList = f: attr: concatMapAttrsToList = f: attr:
concatMap (i: i) (attrValues (mapAttrs f attr)); concatMap (i: i) (attrValues (mapAttrs f attr));
host-domains = config.fudo.acme.host-domains.${hostname}; host-domains = config.fudo.acme.host-domains.${hostname};
hostCerts = host: let hostCerts = host:
cert-copy = host-domains.${host}.local-copies.ejabberd; let cert-copy = host-domains.${host}.local-copies.ejabberd;
in [ in [
cert-copy.certificate cert-copy.certificate
cert-copy.private-key cert-copy.private-key
# cert-copy.full-certificate # cert-copy.full-certificate
]; ];
hostCertService = host: hostCertService = host: host-domains.${host}.local-copies.ejabberd.service;
host-domains.${host}.local-copies.ejabberd.service;
config-file-template = let config-file-template = let
jabber-config = { jabber-config = {
@ -60,8 +59,7 @@ let
acl.admin = { acl.admin = {
user = concatMap user = concatMap
(admin: map (site: "${admin}@${site}") (admin: map (site: "${admin}@${site}") (attrNames cfg.sites))
(attrNames cfg.sites))
cfg.admins; cfg.admins;
}; };
@ -77,35 +75,28 @@ let
starttls = true; starttls = true;
starttls_required = true; starttls_required = true;
}; };
in in if (cfg.listen-ips != null) then
if (cfg.listen-ips != null) then map (ip: { ip = ip; } // common) cfg.listen-ips
map (ip: { ip = ip; } // common) else
cfg.listen-ips [ common ];
else [ common ];
certfiles = concatMapAttrsToList certfiles = concatMapAttrsToList (site: siteOpts:
(site: siteOpts: if (siteOpts.enableACME) then (hostCerts siteOpts.hostname) else [ ])
if (siteOpts.enableACME) then
(hostCerts siteOpts.hostname)
else [])
cfg.sites; cfg.sites;
host_config = host_config = mapAttrs (site: siteOpts: siteOpts.site-config) cfg.sites;
mapAttrs (site: siteOpts: siteOpts.site-config)
cfg.sites;
}; };
config-file = builtins.toJSON jabber-config; config-file = builtins.toJSON jabber-config;
in pkgs.lib.text.format-json-file in pkgs.lib.text.format-json-file
(pkgs.writeText "ejabberd.config.yml.template" config-file); (pkgs.writeText "ejabberd.config.yml.template" config-file);
enter-secrets = template: secrets: target: let enter-secrets = template: secrets: target:
secret-swappers = map let
(secret: "sed s/${secret}/\$${secret}/g") secret-swappers = map (secret: "sed s/${secret}/\$${secret}/g") secrets;
secrets;
swapper = concatStringsSep " | " secret-swappers; swapper = concatStringsSep " | " secret-swappers;
in pkgs.writeShellScript "ejabberd-generate-config.sh" '' in pkgs.writeShellScript "ejabberd-generate-config.sh" ''
[ -f \$${target} ] && rm -f ${target} [ -f \$''${target} ] && rm -f ${target}
echo "Copying from ${template} to ${target}" echo "Copying from ${template} to ${target}"
touch ${target} touch ${target}
chmod go-rwx ${target} chmod go-rwx ${target}
@ -160,7 +151,8 @@ in {
secret-files = mkOption { secret-files = mkOption {
type = attrsOf str; type = attrsOf str;
description = "Map of secret-name to file. File contents will be subbed for the name in the config."; description =
"Map of secret-name to file. File contents will be subbed for the name in the config.";
default = { }; default = { };
}; };
@ -195,21 +187,14 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
users = { users = {
users.${cfg.user} = { users.${cfg.user} = { isSystemUser = true; };
isSystemUser = true;
groups.${cfg.group} = { members = [ cfg.user ]; };
}; };
groups.${cfg.group} = { networking.firewall = { allowedTCPPorts = [ 5222 5223 5269 8010 ]; };
members = [ cfg.user ];
};
};
networking.firewall = { fudo = let host-fqdn = config.instance.host-fqdn;
allowedTCPPorts = [ 5222 5223 5269 8010 ];
};
fudo = let
host-fqdn = config.instance.host-fqdn;
in { in {
acme.host-domains.${hostname} = mapAttrs' (site: siteOpts: acme.host-domains.${hostname} = mapAttrs' (site: siteOpts:
nameValuePair siteOpts.hostname { nameValuePair siteOpts.hostname {
@ -238,8 +223,7 @@ in {
services = { services = {
ejabberd = { ejabberd = {
wants = wants = map hostCertService
map hostCertService
(mapAttrsToList (_: siteOpts: siteOpts.hostname) cfg.sites); (mapAttrsToList (_: siteOpts: siteOpts.hostname) cfg.sites);
requires = [ "ejabberd-config-generator.service" ]; requires = [ "ejabberd-config-generator.service" ];
environment = cfg.environment; environment = cfg.environment;
@ -247,19 +231,24 @@ in {
ejabberd-config-generator = let ejabberd-config-generator = let
config-generator = config-generator =
enter-secrets config-file-template (attrNames cfg.secret-files) cfg.config-file; enter-secrets config-file-template (attrNames cfg.secret-files)
cfg.config-file;
in { in {
description = "Generate ejabberd config file containing passwords."; description = "Generate ejabberd config file containing passwords.";
serviceConfig = { serviceConfig = {
User = cfg.user; User = cfg.user;
ExecStart = "${config-generator}"; ExecStart = "${config-generator}";
ExecStartPost = pkgs.writeShellScript "protect-ejabberd-config.sh" '' ExecStartPost =
pkgs.writeShellScript "protect-ejabberd-config.sh" ''
chown ${cfg.user}:${cfg.group} ${cfg.config-file} chown ${cfg.user}:${cfg.group} ${cfg.config-file}
chmod 0400 ${cfg.config-file} chmod 0400 ${cfg.config-file}
''; '';
EnvironmentFile = host-secrets.ejabberd-password-env.target-file; EnvironmentFile = host-secrets.ejabberd-password-env.target-file;
}; };
unitConfig.ConditionPathExists =
[ host-secrets.ejabberd-password-env.target-file ];
requires = [ host-secrets.ejabberd-password-env.service ]; requires = [ host-secrets.ejabberd-password-env.service ];
after = [ host-secrets.ejabberd-password-env.service ];
}; };
}; };
}; };