|
120 | 120 | # If the TimeoutStartSec is not infinity, it can cause the service to fail, because the readiness probe is considered part of the startup. |
121 | 121 | serviceConfig.TimeoutStartSec = lib.mkForce "infinity"; |
122 | 122 |
|
123 | | - # We replace the ExecStart with a script that runs the readiness probe in the background, and the original service command in the foreground. |
124 | | - serviceConfig.ExecStart = |
| 123 | + # We add a ExecStartPost with a script that runs the readiness probe |
| 124 | + serviceConfig.ExecStartPost = |
125 | 125 | let |
126 | 126 | scriptPath = lib.makeBinPath ( |
127 | 127 | [ |
|
133 | 133 | ++ (serviceConfig.path or [ ]) |
134 | 134 | ); |
135 | 135 | in |
136 | | - lib.mkForce ( |
137 | 136 | pkgs.writeShellScript "${mainServiceName}-readiness-check" '' |
138 | 137 | #!${pkgs.runtimeShell} |
139 | 138 | set -o nounset |
140 | 139 | export PATH="${scriptPath}:$PATH" |
141 | 140 |
|
142 | | - check() { |
143 | | - echo "Health check: starting background readiness probe for ${mainServiceName}." |
144 | | - sleep ${toString probeCfg.initialDelay} |
145 | | - retryCount=${toString probeCfg.retryCount} |
146 | | - while true; do |
147 | | - if (timeout ${toString probeCfg.timeout}s ${probeCfg.command} &> /dev/null); then |
148 | | - echo "Health check: probe successful. Notifying systemd that the service is ready." |
149 | | - systemd-notify --ready --status="${probeCfg.statusReadyMessage}" |
150 | | - return 0 |
151 | | - else |
152 | | - echo "Health check: probe not successful. Notifying systemd that the service is still waiting. Retrying in ${toString probeCfg.interval} seconds..." |
153 | | - systemd-notify --status="${probeCfg.statusWaitingMessage}" |
154 | | - if [[ ''${retryCount} -ne -1 ]]; then |
155 | | - retryCount=$((retryCount - 1)) |
156 | | - if [[ ''${retryCount} -le 0 ]]; then |
157 | | - echo "Health check: probe failed after maximum retries. Exiting." |
158 | | - exit 1 |
159 | | - fi |
| 141 | + echo "Health check: starting background readiness probe for ${mainServiceName}." |
| 142 | + sleep ${toString probeCfg.initialDelay} |
| 143 | + retryCount=${toString probeCfg.retryCount} |
| 144 | + while true; do |
| 145 | + if (timeout ${toString probeCfg.timeout}s ${probeCfg.command} &> /dev/null); then |
| 146 | + echo "Health check: probe successful. Notifying systemd that the service is ready." |
| 147 | + systemd-notify --ready --status="${probeCfg.statusReadyMessage}" |
| 148 | + exit 0 |
| 149 | + else |
| 150 | + echo "Health check: probe not successful. Notifying systemd that the service is still waiting. Retrying in ${toString probeCfg.interval} seconds..." |
| 151 | + systemd-notify --status="${probeCfg.statusWaitingMessage}" |
| 152 | + if [[ ''${retryCount} -ne -1 ]]; then |
| 153 | + retryCount=$((retryCount - 1)) |
| 154 | + if [[ ''${retryCount} -le 0 ]]; then |
| 155 | + echo "Health check: probe failed after maximum retries. Exiting." |
| 156 | + exit 1 |
160 | 157 | fi |
161 | 158 | fi |
162 | | - sleep ${toString probeCfg.interval} |
163 | | - done |
164 | | - } |
165 | | -
|
166 | | - if [[ -n "''${NOTIFY_SOCKET:-}" ]]; then |
167 | | - check & |
168 | | - else |
169 | | - echo "Health check: NOTIFY_SOCKET not set. Cannot run readiness probe." >&2 |
170 | | - exit 1 |
171 | | - fi |
172 | | -
|
173 | | - ${cfg.exec} |
174 | | - '' |
175 | | - ); |
| 159 | + fi |
| 160 | + sleep ${toString probeCfg.interval} |
| 161 | + done |
| 162 | + ''; |
176 | 163 | } |
177 | 164 | )) |
178 | 165 | ) servicesWithHealthcheck; |
|
246 | 233 | description = "Additional programs to add to the PATH for health checks."; |
247 | 234 | }; |
248 | 235 |
|
249 | | - # The main command for the service, required when readiness-probe is on. |
250 | | - exec = lib.mkOption { |
251 | | - type = lib.types.str; |
252 | | - description = '' |
253 | | - The actual command to run for the service. |
254 | | - This MUST be used instead of `script` or `serviceConfig.ExecStart` |
255 | | - when `readiness-probe.enable` is true. |
256 | | - ''; |
257 | | - }; |
258 | | - |
259 | 236 | # The new readiness probe that uses the notify pattern. |
260 | 237 | readiness-probe = lib.mkOption { |
261 | 238 | type = lib.types.submodule readinessProbeOptions; |
|
0 commit comments