From 8be7ba212bcdf27a6d69c76ddfa106f297df6cea Mon Sep 17 00:00:00 2001 From: Amritanshu Date: Fri, 16 Oct 2026 11:29:34 +0530 Subject: [PATCH] Wait for the Nextcloud unit to leave `activating` before checking is-active The first real run of this play stopped at "Verify Nextcloud is running": fatal: [emily]: FAILED! => {"cmd": ["systemctl", "--user", "is-active", "nextcloud.service"], "rc": 3, "stdout": "activating"} Nothing was wrong with the container. `systemctl start` returns while the unit is still `activating` -- the start job completes before conmon has signalled readiness -- and `is-active` exits 3 for that state, so checking once reports a healthy start as a failure. Every other app role here checks is-active only after a wait that already tolerates startup (postgres waits on pg_isready, valkey on valkey-cli ping, bitwarden on its healthcheck); Nextcloud is the one where the check comes first, because its readiness gates are the expensive ones. The wait retries only through the transition. A unit that is `failed` or `inactive` is not going to become `active` by waiting, so that fails immediately with the state in the message rather than five minutes later. What genuinely needs patience -- the entrypoint rsyncing code and running `occ upgrade` before Apache answers -- is the readiness gate that follows, which already has the richer rescue. --- nextcloud/roles/nextcloud/tasks/main.yaml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/nextcloud/roles/nextcloud/tasks/main.yaml b/nextcloud/roles/nextcloud/tasks/main.yaml index 64add15..14cc50c 100644 --- a/nextcloud/roles/nextcloud/tasks/main.yaml +++ b/nextcloud/roles/nextcloud/tasks/main.yaml @@ -90,9 +90,26 @@ # Quadlet honours [Install] WantedBy= when it generates the unit, so # `systemctl --user enable` is neither needed nor possible on a generated unit. -- name: Verify Nextcloud is running +# +# This waits rather than checking once. `systemctl start` returns while the unit +# is still `activating`: the start job is done before conmon has signalled +# readiness, and `is-active` exits 3 for `activating` — so a single check reports +# a healthy start as a failure. That is exactly what happened on this play's +# first real run, which stopped here with `stdout: "activating"`. +# +# It retries only through that transition. A unit that is `failed` or `inactive` +# is not going to become `active` by waiting, so it fails immediately with the +# state in the message instead of five minutes later. The case that genuinely +# needs patience — the app answering yet — is the readiness gate below, which has +# the richer rescue. +- name: Wait for the Nextcloud unit to become active ansible.builtin.command: "systemctl --user is-active {{ unit_name }}" register: nextcloud_active + until: >- + nextcloud_active.stdout == 'active' + or nextcloud_active.stdout not in ['activating', 'reloading'] + retries: 60 + delay: 5 changed_when: false failed_when: nextcloud_active.stdout != 'active'