-
Notifications
You must be signed in to change notification settings - Fork 0
fix(decdn_node): make the /metrics readiness gate advisory (no false-fail) #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| --- | ||
| # Converge the decdn_node role against the stub in late-bind mode with a tiny | ||
| # readiness window. The advisory /metrics probe MUST time out and WARN without | ||
| # failing — so this play reaching the end (and the idempotence re-run) is itself | ||
| # the core assertion of the fix. verify.yml then confirms the running-but-no- | ||
| # metrics end state. Chain/contract knobs mirror the default scenario's | ||
| # well-formed placeholders (the role's fail-loud asserts still run against them). | ||
| - name: Converge | ||
| hosts: all | ||
| become: true | ||
| vars: | ||
| # Reuse the default scenario's stub binary rather than duplicating it. | ||
| stub_bin: "{{ lookup('ansible.builtin.env', 'MOLECULE_PROJECT_DIRECTORY') }}/molecule/default/files/decdn-node-stub" | ||
| decdn_node_install_method: manual | ||
| decdn_node_manual_bin_src: "{{ stub_bin }}" | ||
| decdn_cli_manual_bin_src: "{{ stub_bin }}" | ||
| decdn_node_version: "0.0.0-molecule-stub" | ||
| decdn_rpc_url: "https://rpc.example.invalid/" | ||
| decdn_chain_id: 421614 | ||
| decdn_region: "US" | ||
| decdn_payment_channel_address: "0x1111111111111111111111111111111111111111" | ||
| decdn_capacity_bond_address: "0x2222222222222222222222222222222222222222" | ||
| decdn_slash_judge_address: "0x3333333333333333333333333333333333333333" | ||
| decdn_cache_origin_kind: "http" | ||
| decdn_cache_origin_url: "https://origin.example.invalid/" | ||
| # Tiny probe window (~2s) so the advisory timeout is exercised fast. The stub | ||
| # never binds metrics in this scenario, so any window times out — this just | ||
| # keeps the scenario quick. | ||
| decdn_readiness_retries: 2 | ||
| decdn_readiness_delay: 1 | ||
| roles: | ||
| - role: decdn_node |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| --- | ||
| # Regression scenario for the ADVISORY /metrics readiness probe. Runs the stub | ||
| # daemon in its "late bind" mode (it stays alive but never binds metrics — see | ||
| # molecule/default/files/decdn-node-stub, gated on /etc/decdn/stub-no-metrics), | ||
| # with a deliberately tiny readiness window. It proves the fix: the role's probe | ||
| # WARNS (does not fail) on timeout, the deploy still succeeds, and the hard | ||
| # service-state gate confirms the unit is `running`. Reuses the default | ||
| # scenario's stub binary rather than duplicating it. | ||
| # | ||
| # `baseline` is NOT exercised here (same rationale as the default scenario: | ||
| # host-level hardening is real-host-only — see molecule/default/molecule.yml). | ||
| dependency: | ||
| name: galaxy | ||
| options: | ||
| requirements-file: ../../requirements.yml | ||
| driver: | ||
| name: docker | ||
| platforms: | ||
| - name: decdn-node-slow-readiness | ||
| # Same digest-pinned image as the default scenario (repo convention). Re-resolve | ||
| # both together to bump. | ||
| image: geerlingguy/docker-debian12-ansible@sha256:4553092be2c00b1ffe580927b9ff03f3c3a0df32b7dd693a3eb02efb6c2b77b7 | ||
| pre_build_image: true | ||
| command: /usr/lib/systemd/systemd | ||
| privileged: true | ||
| cgroupns_mode: host | ||
| volumes: | ||
| - /sys/fs/cgroup:/sys/fs/cgroup:rw | ||
| provisioner: | ||
| name: ansible | ||
| env: | ||
| ANSIBLE_ROLES_PATH: "${MOLECULE_PROJECT_DIRECTORY}/roles" | ||
| ANSIBLE_COLLECTIONS_PATH: "${MOLECULE_PROJECT_DIRECTORY}/collections" | ||
| verifier: | ||
| name: ansible | ||
| scenario: | ||
| test_sequence: | ||
| - dependency | ||
| - create | ||
| - prepare | ||
| - converge | ||
| - idempotence | ||
| - verify | ||
| - destroy |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| --- | ||
| # Same operator-keystore staging as the default scenario (the role's pre-start | ||
| # gate needs keystore + node.secret + password to exist), PLUS the marker that | ||
| # puts the stub daemon into "late bind" mode so it never binds /metrics — which | ||
| # is what makes the role's advisory readiness probe time out. | ||
| - name: Prepare | ||
| hosts: all | ||
| become: true | ||
| vars: | ||
| decdn_home: /var/lib/decdn | ||
| decdn_etc: /etc/decdn | ||
| tasks: | ||
| - name: Ensure data + config directories exist | ||
| ansible.builtin.file: | ||
| path: "{{ item }}" | ||
| state: directory | ||
| mode: "0755" | ||
| loop: | ||
| - "{{ decdn_home }}" | ||
| - "{{ decdn_etc }}" | ||
|
|
||
| # Staged at 0644 (looser than target); the role locks them to 0600. | ||
| - name: Stage a placeholder eth keystore | ||
| ansible.builtin.copy: | ||
| dest: "{{ decdn_home }}/keystore.json" | ||
| content: "{{ '{}' }}\n" | ||
| mode: "0644" | ||
|
|
||
| - name: Stage a placeholder keystore password file | ||
| ansible.builtin.copy: | ||
| dest: "{{ decdn_etc }}/keystore.password" | ||
| content: "molecule-placeholder\n" | ||
| mode: "0644" | ||
|
|
||
| - name: Stage a placeholder node identity | ||
| ansible.builtin.copy: | ||
| dest: "{{ decdn_home }}/node.secret" | ||
| content: "molecule-placeholder-node-secret\n" | ||
| mode: "0644" | ||
|
|
||
| # The stub reads this marker (NO_METRICS_MARKER in decdn-node-stub) and, when | ||
| # present, blocks forever WITHOUT binding metrics — simulating a healthy node | ||
| # whose metrics listener binds late. That drives the advisory-timeout path. | ||
| - name: Put the stub daemon into late-bind (no-metrics) mode | ||
| ansible.builtin.copy: | ||
| dest: "{{ decdn_etc }}/stub-no-metrics" | ||
| content: "1\n" | ||
| mode: "0644" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| --- | ||
| # The core assertion of this scenario is IMPLICIT: molecule only reaches `verify` | ||
| # if `converge` (and the idempotence re-run) succeeded — i.e. the advisory | ||
| # /metrics probe timed out WITHOUT failing the deploy. This play nails down the | ||
| # rest of that end state: the unit is running (the hard service-state gate still | ||
| # passed) even though metrics never bound (proving the timeout path was actually | ||
| # taken, not silently short-circuited by a metrics socket that came up anyway). | ||
| - name: Verify | ||
| hosts: all | ||
| become: true | ||
| tasks: | ||
| - name: Confirm the stub really ran in late-bind (no-metrics) mode | ||
| ansible.builtin.stat: | ||
| path: /etc/decdn/stub-no-metrics | ||
| register: no_metrics_marker | ||
|
|
||
| - name: Collect listening TCP sockets | ||
| ansible.builtin.command: | ||
| cmd: ss -ltn | ||
| register: listeners | ||
| changed_when: false | ||
|
|
||
| - name: Gather service facts | ||
| ansible.builtin.service_facts: | ||
|
|
||
| - name: Assert the deploy survived a metrics-probe timeout with the unit running | ||
| ansible.builtin.assert: | ||
| that: | ||
| # The marker is present => the stub was in late-bind mode, so the probe | ||
| # genuinely timed out rather than passing against a bound socket. | ||
| - no_metrics_marker.stat.exists | ||
| # Metrics never bound — the timeout path is what we exercised. | ||
| - "'127.0.0.1:9090' not in listeners.stdout" | ||
| - "'0.0.0.0:9090' not in listeners.stdout" | ||
| - "'[::]:9090' not in listeners.stdout" | ||
| - "'*:9090' not in listeners.stdout" | ||
| # The load-bearing liveness gate still holds: the unit is running. | ||
| - >- | ||
| 'decdn-node.service' in ansible_facts.services | ||
| and ansible_facts.services['decdn-node.service'].state == 'running' | ||
| fail_msg: >- | ||
| Expected a running decdn-node with NO metrics socket (advisory-timeout | ||
| path). Sockets: {{ listeners.stdout }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.