elway: add tier 1 + tier 2 idempotency
Tier 1 — pre-step skip conditions: when: <remote shell expr> skip unless expr exits 0 creates: <remote path> skip if path already exists removes: <remote path> skip if path is already absent Any of the three saying "skip" marks the step `skipped` and moves on. Evaluated under bash -c on the remote so `!`, `[[`, pipes etc. behave consistently regardless of the default remote shell. Tier 2 — post-step change detection: changed_when: <remote shell expr> Evaluated after a successful step. Exit 0 → step counts as `changed` (default). Exit != 0 → `ok` (ran, nothing actually different). Without this field, successful steps default to `changed`, matching Ansible's shell/command defaults. Useful on verify steps: `changed_when: "false"` reports them as `ok` since they only attest. Status model moved from pass/fail to four states: ok / changed / failed / skipped Summary reports each count; overall outcome is CHANGED if any step changed, OK if none did, FAILED on any non-skipped failure. Rerunnable smoke: playbooks/elway-smoke.yaml now proves it. On a clean target the cold run reports 4 changed, 3 ok. Rerunning with the same vars reports 2 skipped / 2 changed (upload + log-record have no idempotency hooks and are always `changed`). Overriding --var greeting=... re-runs the gated step exactly as intended. Doc block at the top of the script updated with the new schema fields and state machine.
This commit is contained in:
+27
-11
@@ -1,20 +1,29 @@
|
||||
# elway's own smoke-test playbook. Exercises: vars (inline + CLI override),
|
||||
# multi-step flow, upload with mode, stop-on-error semantics, verify phase.
|
||||
# Target: any Linux host reachable over ssh that has /tmp and curl.
|
||||
# elway's own smoke-test playbook. Exercises:
|
||||
# - vars (inline default + CLI override)
|
||||
# - multi-step flow
|
||||
# - upload with mode
|
||||
# - tier 1 idempotency: `creates:` skip
|
||||
# - tier 2 idempotency: `changed_when:` to report ok vs changed
|
||||
# - verify phase that tolerates already-set-up state
|
||||
#
|
||||
# Rerunnable: second run should show mostly `ok`/`skipped`, proving
|
||||
# idempotency is wired correctly.
|
||||
|
||||
vars:
|
||||
scratch_dir: /tmp/elway-smoke
|
||||
greeting: hello from elway
|
||||
|
||||
steps:
|
||||
- name: Clean any prior scratch dir
|
||||
shell: rm -rf {{ scratch_dir }}
|
||||
|
||||
- name: Create scratch dir
|
||||
shell: mkdir -p {{ scratch_dir }}
|
||||
creates: "{{ scratch_dir }}"
|
||||
|
||||
- name: Drop a greeting file
|
||||
shell: echo "{{ greeting }}" > {{ scratch_dir }}/greeting.txt
|
||||
# Skip the echo entirely if the file already contains exactly this line.
|
||||
# `when:` gates BEFORE running; `changed_when:` decides ok-vs-changed AFTER.
|
||||
# For "is the new state already the desired state?", `when:` is correct.
|
||||
when: "! grep -qxF '{{ greeting }}' {{ scratch_dir }}/greeting.txt 2>/dev/null"
|
||||
|
||||
- name: Upload this playbook into the scratch dir
|
||||
upload:
|
||||
@@ -22,12 +31,19 @@ steps:
|
||||
dest: "{{ scratch_dir }}/uploaded.yaml"
|
||||
mode: "0644"
|
||||
|
||||
- name: Record that we ran (a step with no idempotency hooks — always `changed`)
|
||||
shell: date -Iseconds > {{ scratch_dir }}/last-run.txt
|
||||
|
||||
verify:
|
||||
- name: Greeting file has the expected content
|
||||
shell: grep -q "{{ greeting }}" {{ scratch_dir }}/greeting.txt
|
||||
shell: grep -qxF "{{ greeting }}" {{ scratch_dir }}/greeting.txt
|
||||
# Verify steps don't actually "change" anything — they only attest.
|
||||
changed_when: "false"
|
||||
|
||||
- name: Uploaded file is a non-empty yaml
|
||||
shell: test -s {{ scratch_dir }}/uploaded.yaml && head -1 {{ scratch_dir }}/uploaded.yaml
|
||||
- name: Uploaded yaml is non-empty
|
||||
shell: test -s {{ scratch_dir }}/uploaded.yaml
|
||||
changed_when: "false"
|
||||
|
||||
- name: Scratch dir exists and is listable
|
||||
shell: ls -la {{ scratch_dir }}
|
||||
- name: last-run.txt exists
|
||||
shell: test -s {{ scratch_dir }}/last-run.txt
|
||||
changed_when: "false"
|
||||
|
||||
Reference in New Issue
Block a user