Skip to content

Commit 599f034

Browse files
thirasclaude
andcommitted
fix(decdn_node): create the fs cache-origin directory for kind: fs
When `decdn_cache_origin_kind: fs`, the role rendered `[cache.origin] path = {{ decdn_cache_origin_path }}` into node.toml but never created that directory. The daemon's `FilesystemOrigin::new` fails fast if the base path is missing or is not a directory, and the unit is `Restart=always`/`RestartSec=5`, so a `kind: fs` deploy that didn't pre-create the dir out-of-band crash-looped on every (re)start. Add a `when: kind == fs` task that creates `decdn_cache_origin_path` (owner decdn:decdn, mode 0755) right after the existing data/cache/config dir task, making a `kind: fs` deploy self-contained. The sharded blob files under it ({path}/{hex[0..2]}/{hex}) are content, not config, and stay an operator concern — only the base dir is role-managed. Test coverage: switch the molecule `default` scenario from an http origin to an fs origin so the new task actually runs, and assert in verify.yml that the dir exists as decdn:decdn/0755 plus a node.toml [cache.origin] content check. http-origin template coverage is retained by the generate-keystore and slow-readiness scenarios. Closes #28 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 589b9b1 commit 599f034

3 files changed

Lines changed: 46 additions & 2 deletions

File tree

‎ansible/molecule/default/converge.yml‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@
2222
decdn_payment_channel_address: "0x1111111111111111111111111111111111111111"
2323
decdn_capacity_bond_address: "0x2222222222222222222222222222222222222222"
2424
decdn_slash_judge_address: "0x3333333333333333333333333333333333333333"
25-
decdn_cache_origin_kind: "http"
26-
decdn_cache_origin_url: "https://origin.example.invalid/"
25+
# fs origin: exercises the role's "create the fs cache-origin base dir" task
26+
# (#28) — /var/lib/decdn/origin does not pre-exist, so the run genuinely creates
27+
# it (verify.yml asserts owner/group/mode). Keep in sync with verify.yml.
28+
decdn_cache_origin_kind: "fs"
29+
decdn_cache_origin_path: "/var/lib/decdn/origin"
2730
# Exercise baseline's named-sudo-users feature (see pre_tasks below). Throwaway
2831
# keys, generated for this test only — public keys, not credentials. Two users
2932
# on purpose: `alice.smith` has a '.' (so the sudoers.d filename-sanitize maps it

‎ansible/molecule/default/verify.yml‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,35 @@
9090
if bad:
9191
print("node.toml content mismatch (got, want):", bad, file=sys.stderr)
9292
sys.exit(1)
93+
# [cache.origin] is a nested table (3 levels), so check it separately from
94+
# the flat two-level `want` lookups above. Mirrors converge.yml's fs origin.
95+
origin = d.get("cache", {}).get("origin", {})
96+
if origin.get("kind") != "fs" or origin.get("path") != "/var/lib/decdn/origin":
97+
print("node.toml [cache.origin] mismatch (got):", origin, file=sys.stderr)
98+
sys.exit(1)
9399
94100
- name: Assert node.toml is valid TOML and renders the expected content
95101
ansible.builtin.command:
96102
cmd: python3 /root/molecule-assert-node-toml.py
97103
changed_when: false
98104

105+
# The role must CREATE the fs origin base dir (converge sets kind: fs) — the
106+
# daemon's FilesystemOrigin::new crash-loops if it is missing (#28). This dir
107+
# does not pre-exist, so its presence + ownership proves the role's task ran.
108+
- name: Stat the fs cache-origin base directory
109+
ansible.builtin.stat:
110+
path: /var/lib/decdn/origin
111+
register: decdn_origin_dir
112+
113+
- name: Assert the fs cache-origin dir exists (decdn:decdn, 0755, directory)
114+
ansible.builtin.assert:
115+
that:
116+
- decdn_origin_dir.stat.exists and decdn_origin_dir.stat.isdir
117+
- decdn_origin_dir.stat.pw_name == 'decdn'
118+
- decdn_origin_dir.stat.gr_name == 'decdn'
119+
- decdn_origin_dir.stat.mode == '0755'
120+
fail_msg: "fs cache-origin dir missing / not a dir / wrong owner / wrong mode"
121+
99122
- name: Validate the systemd unit
100123
ansible.builtin.command:
101124
cmd: systemd-analyze verify /etc/systemd/system/decdn-node.service

‎ansible/roles/decdn_node/tasks/main.yml‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,24 @@
205205
loop_control:
206206
label: "{{ item.path }}"
207207

208+
# For a filesystem pull-through origin (kind: fs), the daemon's FilesystemOrigin::new
209+
# fails fast if the base path is missing or is not a directory — a crash-loop on every
210+
# (re)start. Create it here so a kind: fs deploy is self-contained. The sharded blob
211+
# files under it ({path}/{hex[0..2]}/{hex}) are content, not config, and stay an
212+
# operator concern — only the base dir is role-managed. 0755 (looser than the 0700
213+
# data dirs above) because pull-through origin blobs are public CDN content, not
214+
# secrets, and an operator may populate the tree out-of-band as a different user.
215+
- name: Ensure the fs cache-origin base directory exists (kind == fs)
216+
ansible.builtin.file:
217+
path: "{{ decdn_cache_origin_path }}"
218+
state: directory
219+
owner: "{{ decdn_user }}"
220+
group: "{{ decdn_group }}"
221+
mode: "0755"
222+
when:
223+
- decdn_cache_origin_kind == "fs"
224+
- decdn_cache_origin_path | length > 0
225+
208226
# --- Install the binaries -----------------------------------------------------
209227
- name: Install decdn-node + decdn CLI
210228
ansible.builtin.import_tasks: install.yml

0 commit comments

Comments
 (0)