Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,9 +57,11 @@ let | |
default = ""; | ||
example = "systemctl reload nginx.service"; | ||
description = '' | ||
Commands to run after certificates are re-issued. Typically | ||
Commands to run after new certificates go live. Typically | ||
the web server and other servers using certificates need to | ||
be reloaded. | ||
Executed in the same directory with the new certificate. | ||
''; | ||
}; | ||
|
||
|
@@ -77,6 +79,27 @@ let | |
''; | ||
}; | ||
|
||
activationDelay = mkOption { | ||
type = types.nullOr types.str; | ||
default = null; | ||
description = '' | ||
Systemd time span expression to delay copying new certificates to main | ||
state directory. See <citerefentry><refentrytitle>systemd.time</refentrytitle> | ||
<manvolnum>7</manvolnum></citerefentry>. | ||
''; | ||
}; | ||
|
||
preDelay = mkOption { | ||
type = types.lines; | ||
default = ""; | ||
description = '' | ||
Commands to run after certificates are re-issued but before they are | ||
activated. Typically the new certificate is published to DNS. | ||
Executed in the same directory with the new certificate. | ||
''; | ||
}; | ||
|
||
extraDomains = mkOption { | ||
type = types.attrsOf (types.nullOr types.str); | ||
default = {}; | ||
|
@@ -186,14 +209,14 @@ in | |
certToServices = cert: data: | ||
let | ||
domain = if data.domain != null then data.domain else cert; | ||
cpath = "${cfg.directory}/${cert}"; | ||
cpath = lpath + optionalString (data.activationDelay != null) ".staging"; | ||
lpath = "${cfg.directory}/${cert}"; | ||
rights = if data.allowKeysForGroup then "750" else "700"; | ||
cmdline = [ "-v" "-d" domain "--default_root" data.webroot "--valid_min" cfg.validMin ] | ||
++ optionals (data.email != null) [ "--email" data.email ] | ||
++ concatMap (p: [ "-f" p ]) data.plugins | ||
++ concatLists (mapAttrsToList (name: root: [ "-d" (if root == null then name else "${name}:${root}")]) data.extraDomains) | ||
++ (if cfg.production then [] | ||
else ["--server" "https://acme-staging.api.letsencrypt.org/directory"]); | ||
++ optionals (!cfg.production) ["--server" "https://acme-staging.api.letsencrypt.org/directory"]; | ||
acmeService = { | ||
description = "Renew ACME Certificate for ${cert}"; | ||
after = [ "network.target" "network-online.target" ]; | ||
|
@@ -206,7 +229,7 @@ in | |
Group = data.group; | ||
PrivateTmp = true; | ||
}; | ||
path = [ pkgs.simp_le ]; | ||
path = with pkgs; [ simp_le systemd ]; | ||
preStart = '' | ||
mkdir -p '${cfg.directory}' | ||
chown 'root:root' '${cfg.directory}' | ||
|
@@ -229,15 +252,36 @@ in | |
exit "$EXITCODE" | ||
''; | ||
postStop = '' | ||
cd '${cpath}' | ||
if [ -e /tmp/lastExitCode ] && [ "$(cat /tmp/lastExitCode)" = "0" ]; then | ||
echo "Executing postRun hook..." | ||
${data.postRun} | ||
${if data.activationDelay != null then '' | ||
${data.preDelay} | ||
if [ -d '${lpath}' ]; then | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
gkleen
Contributor
|
||
systemd-run --no-block --on-active='${data.activationDelay}' --unit acme-setlive-${cert}.service | ||
else | ||
systemctl --wait start acme-setlive-${cert}.service | ||
fi | ||
'' else data.postRun} | ||
fi | ||
''; | ||
|
||
before = [ "acme-certificates.target" ]; | ||
wantedBy = [ "acme-certificates.target" ]; | ||
}; | ||
delayService = { | ||
description = "Set certificate for ${cert} live"; | ||
path = with pkgs; [ rsync ]; | ||
serviceConfig = { | ||
Type = "oneshot"; | ||
}; | ||
script = '' | ||
rsync -a --delete-after '${cpath}/' '${lpath}' | ||
''; | ||
postStop = data.postRun; | ||
}; | ||
selfsignedService = { | ||
description = "Create preliminary self-signed certificate for ${cert}"; | ||
preStart = '' | ||
|
@@ -297,11 +341,8 @@ in | |
}; | ||
in ( | ||
[ { name = "acme-${cert}"; value = acmeService; } ] | ||
++ | ||
(if cfg.preliminarySelfsigned | ||
then [ { name = "acme-selfsigned-${cert}"; value = selfsignedService; } ] | ||
else [] | ||
) | ||
++ optional cfg.preliminarySelfsigned { name = "acme-selfsigned-${cert}"; value = selfsignedService; } | ||
++ optional (data.activationDelay != null) { name = "acme-setlive-${cert}"; value = delayService; } | ||
); | ||
servicesAttr = listToAttrs services; | ||
injectServiceDep = { | ||
|
Hey @pngwjpgh I have a question about this piece of code. I'm currently refactoring the
acme
module, and was wondering why we only have an activationDelay when thelpath
does exist? Doesn't this mean there is no delay at all the first time you request the cert? I don't want to break expected behaviour, but it's not clear to me what the expected behaviour should be. Why is this conditional check being done here?