bound the forge's SSO source setup and retry it with a growing delay
This commit is contained in:
parent
70b112058a
commit
3b8ab17240
2 changed files with 29 additions and 9 deletions
|
|
@ -113,6 +113,9 @@ let
|
||||||
oneWord = path: builtins.match ".*[[:space:]].*" path == null;
|
oneWord = path: builtins.match ".*[[:space:]].*" path == null;
|
||||||
forwarderCredential = id: "/run/credentials/${forwarderUnit}.service/${id}";
|
forwarderCredential = id: "/run/credentials/${forwarderUnit}.service/${id}";
|
||||||
mintUnit = "forgejo-swarm-controller-account";
|
mintUnit = "forgejo-swarm-controller-account";
|
||||||
|
# `timeout` arguments for the forgejo calls that fetch the issuer's discovery
|
||||||
|
# document; the CLI has no client timeout of its own.
|
||||||
|
ssoCallTimeout = "--kill-after=3 20";
|
||||||
mintCredential = id: "/run/credentials/${mintUnit}.service/${id}";
|
mintCredential = id: "/run/credentials/${mintUnit}.service/${id}";
|
||||||
|
|
||||||
# ROOT_URL forgejo advertises in clone links + outbound URLs.
|
# ROOT_URL forgejo advertises in clone links + outbound URLs.
|
||||||
|
|
@ -897,7 +900,10 @@ in
|
||||||
after = [ "forgejo.service" ];
|
after = [ "forgejo.service" ];
|
||||||
requires = [ "forgejo.service" ];
|
requires = [ "forgejo.service" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
# ../lib/store-retry.nix: a secret that is not there yet, or an
|
||||||
|
# authelia that is not answering, is retried.
|
||||||
|
inherit (storeRetry) startLimitBurst startLimitIntervalSec;
|
||||||
|
serviceConfig = storeRetry.serviceConfig // {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
User = "forgejo";
|
User = "forgejo";
|
||||||
|
|
@ -907,6 +913,14 @@ in
|
||||||
# it, and this unit fails to start until then; that unit starts
|
# it, and this unit fails to start until then; that unit starts
|
||||||
# it again once the file is written.
|
# it again once the file is written.
|
||||||
LoadCredential = [ "oidc-client-secret:${oidcSecretPath}" ];
|
LoadCredential = [ "oidc-client-secret:${oidcSecretPath}" ];
|
||||||
|
# This unit is in the boot wait of a container with a one-minute
|
||||||
|
# start limit. Each registration call is capped at 20 s, so an
|
||||||
|
# authelia that never answers fails the attempt, and the growing
|
||||||
|
# delay below retries it.
|
||||||
|
TimeoutStartSec = 30;
|
||||||
|
RestartSec = 5;
|
||||||
|
RestartSteps = 6;
|
||||||
|
RestartMaxDelaySec = 300;
|
||||||
};
|
};
|
||||||
# `FORGEJO_CUSTOM` (the forgejo-prefixed name, not `GITEA_CUSTOM`)
|
# `FORGEJO_CUSTOM` (the forgejo-prefixed name, not `GITEA_CUSTOM`)
|
||||||
# is how the CLI finds the app.ini upstream's module wrote.
|
# is how the CLI finds the app.ini upstream's module wrote.
|
||||||
|
|
@ -966,12 +980,12 @@ in
|
||||||
id=$(forgejo admin auth list \
|
id=$(forgejo admin auth list \
|
||||||
| grep "[[:space:]]${ssoSourceName}[[:space:]]" \
|
| grep "[[:space:]]${ssoSourceName}[[:space:]]" \
|
||||||
| cut -f1)
|
| cut -f1)
|
||||||
forgejo admin auth update-oauth --id "$id" \
|
timeout ${ssoCallTimeout} forgejo admin auth update-oauth --id "$id" \
|
||||||
--name ${lib.escapeShellArg ssoSourceName} \
|
--name ${lib.escapeShellArg ssoSourceName} \
|
||||||
--secret "$secret" "''${args[@]}"
|
--secret "$secret" "''${args[@]}"
|
||||||
echo "updated OIDC login source ${ssoSourceName} (id $id)"
|
echo "updated OIDC login source ${ssoSourceName} (id $id)"
|
||||||
else
|
else
|
||||||
forgejo admin auth add-oauth \
|
timeout ${ssoCallTimeout} forgejo admin auth add-oauth \
|
||||||
--name ${lib.escapeShellArg ssoSourceName} \
|
--name ${lib.escapeShellArg ssoSourceName} \
|
||||||
--secret "$secret" "''${args[@]}"
|
--secret "$secret" "''${args[@]}"
|
||||||
echo "added OIDC login source ${ssoSourceName}"
|
echo "added OIDC login source ${ssoSourceName}"
|
||||||
|
|
|
||||||
|
|
@ -267,10 +267,6 @@ let
|
||||||
"victoriametrics.service"
|
"victoriametrics.service"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
{
|
|
||||||
why = "known gap: registering the login source makes an outbound HTTPS call to authelia, and the unit has neither a timeout nor a Restart=";
|
|
||||||
units = [ "forgejo-sso-source.service" ];
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
allowedUnstated =
|
allowedUnstated =
|
||||||
key:
|
key:
|
||||||
|
|
@ -1441,7 +1437,7 @@ let
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
# The presence arms for the check above: it reads real units and real
|
# The presence arms for the check above: it reads real units and real
|
||||||
# limits. Each named unit states its budget (30 s, 30 s, 30 s, 20 s, 20 s),
|
# limits. Each named unit states its budget (30 s, 30 s, 30 s, 30 s, 20 s, 20 s),
|
||||||
# so it is found at a limit equal to it and not one second above (the
|
# so it is found at a limit equal to it and not one second above (the
|
||||||
# boundary), and the container limits are the ones the check reads.
|
# boundary), and the container limits are the ones the check reads.
|
||||||
name = "the boot-wait check finds the units that state a budget, at the boundary, and reads each container's own limit";
|
name = "the boot-wait check finds the units that state a budget, at the boundary, and reads each container's own limit";
|
||||||
|
|
@ -1453,8 +1449,11 @@ let
|
||||||
secrets = "authelia-swarm-secrets.service";
|
secrets = "authelia-swarm-secrets.service";
|
||||||
sync = "swarm-matrix-appservice-sync.service";
|
sync = "swarm-matrix-appservice-sync.service";
|
||||||
render = "swarm-matrix-appservice-render.service";
|
render = "swarm-matrix-appservice-render.service";
|
||||||
|
sso = "forgejo-sso-source.service";
|
||||||
in
|
in
|
||||||
lib.elem mint (keys "hive-forge" 30)
|
lib.elem mint (keys "hive-forge" 30)
|
||||||
|
&& lib.elem sso (keys "hive-forge" 30)
|
||||||
|
&& !(lib.elem sso (keys "hive-forge" 31))
|
||||||
&& lib.elem fetch (keys "hive-forge" 30)
|
&& lib.elem fetch (keys "hive-forge" 30)
|
||||||
&& !(lib.elem mint (keys "hive-forge" 31))
|
&& !(lib.elem mint (keys "hive-forge" 31))
|
||||||
&& !(lib.elem fetch (keys "hive-forge" 31))
|
&& !(lib.elem fetch (keys "hive-forge" 31))
|
||||||
|
|
@ -1480,9 +1479,16 @@ let
|
||||||
sc = u.serviceConfig;
|
sc = u.serviceConfig;
|
||||||
in
|
in
|
||||||
sc.Restart == "on-failure" && sc.RestartSteps > 0 && sc.RestartMaxDelaySec > sc.RestartSec;
|
sc.Restart == "on-failure" && sc.RestartSteps > 0 && sc.RestartMaxDelaySec > sc.RestartSec;
|
||||||
|
forge = serviceContainers.hive-forge.config.systemd.services;
|
||||||
authelia = serviceContainers.swarm-authelia.config.systemd.services;
|
authelia = serviceContainers.swarm-authelia.config.systemd.services;
|
||||||
in
|
in
|
||||||
grows serviceContainers.hive-forge.config.systemd.services.forgejo-swarm-controller-account
|
grows forge.forgejo-swarm-controller-account
|
||||||
|
&& grows forge.forgejo-sso-source
|
||||||
|
&& forge.forgejo-sso-source.serviceConfig.TimeoutStartSec == 30
|
||||||
|
# Both registration calls fetch the issuer's discovery document and
|
||||||
|
# run under a client timeout.
|
||||||
|
&& lib.hasInfix "timeout --kill-after=3 20 forgejo admin auth add-oauth" forge.forgejo-sso-source.script
|
||||||
|
&& lib.hasInfix "timeout --kill-after=3 20 forgejo admin auth update-oauth" forge.forgejo-sso-source.script
|
||||||
&& grows authelia.authelia-swarm-secrets
|
&& grows authelia.authelia-swarm-secrets
|
||||||
&& authelia.swarm-authelia-bridge.serviceConfig.TimeoutStartSec == 10;
|
&& authelia.swarm-authelia-bridge.serviceConfig.TimeoutStartSec == 10;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue