fix(O1): scaffold docker_host role so make lint passes on main
playbooks/site.yml imports the docker_host role, but it didn't exist, so ansible-lint's syntax-check failed on a clean checkout — breaking CLAUDE.md's "main must always work" / "Never skip lint" (top open finding O1 from the 2026-06-11 review). Scaffold docker_host as a proper placeholder via the prescribed mechanism (make new-role): filled meta/main.yml + README, an honest no-task tasks/main.yml documenting planned scope (Docker engine + Compose, daemon hardening, nftables.d container rules per ADR-004/020), and the standard molecule scenario. This preserves site.yml's full-standard-state intent rather than dropping the play. Update STATUS.md (docker_host moves from "Not in git" to "scaffolded, no tasks") and the role/playbook READMEs to match. make lint: 0 failures, 0 warnings; check-tags OK. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1da117d65b
commit
03d33f83dd
12 changed files with 118 additions and 9 deletions
|
|
@ -35,14 +35,14 @@ _Last reviewed: 2026-06-11._
|
|||
| Thing | State |
|
||||
|---|---|
|
||||
| `roles/base/` | **Partially built.** The `firewall` concern is implemented (nftables: catalog-driven default-deny + east-west allowlist + auto-rollback apply; ADR-020) with pytest + Molecule render/syntax tests. Other concerns (SSH hardening, fail2ban, auditd, packages, users) are **not** built yet, so `make deploy PLAYBOOK=site` has no real content to apply (the make target itself now works — see "Real and working today"). |
|
||||
| `roles/docker_host/` | Not in git. Same. |
|
||||
| `roles/docker_host/` | **Scaffolded, no tasks.** In git (meta/README/molecule filled), wired into `playbooks/site.yml` so the standard state is expressed end-to-end and `make lint` covers it, but it has no tasks yet — applying it is a no-op. Planned scope (Docker engine + Compose, daemon hardening, `nftables.d` container rules) in ADR-004/ADR-020. |
|
||||
| `inventories/*/hosts.yml` | Structured stubs with empty host maps (`hosts: {}`); regenerated by `make tf-inventory` once Terraform has hosts |
|
||||
| `inventories/production/group_vars/{docker_hosts,proxmox_hosts}/` | Empty dirs |
|
||||
|
||||
So `make deploy PLAYBOOK=site` has no real content to apply — `base` is only partially
|
||||
built (its `firewall` concern only) and the `docker_host` role does not exist yet. (The
|
||||
`make check`/`deploy` machinery itself now works — first proven by applying `dev_env` via
|
||||
`playbooks/workstation.yml`.)
|
||||
built (its `firewall` concern only) and the `docker_host` role is scaffolded but has no
|
||||
tasks yet. (The `make check`/`deploy` machinery itself now works — first proven by
|
||||
applying `dev_env` via `playbooks/workstation.yml`.)
|
||||
|
||||
## Designed but not built
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Top-level orchestration playbooks. No inline vars — configuration comes from
|
|||
|
||||
- `site.yml` — full standard state: applies `base` to all hosts and `docker_host`
|
||||
to docker hosts. **Note:** `base` is only partially built (its `firewall` concern)
|
||||
and `docker_host` does not exist yet, so this is incomplete — see `STATUS.md`.
|
||||
and `docker_host` is scaffolded with no tasks yet, so this is incomplete — see `STATUS.md`.
|
||||
- `workstation.yml` — applies the `dev_env` role (interactive developer environment)
|
||||
to the `control` group; built and applied to `ubongo` (see `STATUS.md`).
|
||||
- `bootstrap.yml` — first-run setup for a host that may not have Python yet;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
---
|
||||
# site.yml — apply full standard state to all hosts
|
||||
# Run via: make deploy PLAYBOOK=site
|
||||
# NOTE: `base` is only partially built (its `firewall` concern; see STATUS.md) and the
|
||||
# `docker_host` role does not exist yet, so this playbook applies base's firewall but is
|
||||
# incomplete until `docker_host` is created.
|
||||
# NOTE: `base` is only partially built (its `firewall` concern; see STATUS.md) and
|
||||
# `docker_host` is scaffolded but has no tasks yet, so this playbook applies base's
|
||||
# firewall but is otherwise incomplete until those roles gain content.
|
||||
|
||||
- name: Apply base configuration to all hosts
|
||||
hosts: all
|
||||
|
|
|
|||
|
|
@ -10,6 +10,6 @@ Each role must have: a `molecule/default/` scenario (Debian 13), a populated
|
|||
|
||||
Current state: `base` is **partially built** — its `firewall` concern (nftables) is
|
||||
implemented and tested; the other concerns (SSH hardening, fail2ban, auditd, packages,
|
||||
users) are not yet built. `docker_host` does **not exist yet**. `dev_env` (interactive
|
||||
users) are not yet built. `docker_host` is **scaffolded but has no tasks yet**. `dev_env` (interactive
|
||||
developer environment) is built and applied. See `STATUS.md` for the authoritative
|
||||
breakdown.
|
||||
|
|
|
|||
34
roles/docker_host/README.md
Normal file
34
roles/docker_host/README.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# docker_host
|
||||
|
||||
Docker engine + Compose runtime applied to every host in the `docker_hosts` group.
|
||||
Provides the container platform that the per-service roles (one service = one role,
|
||||
ADR-004) deploy their Compose stacks onto.
|
||||
|
||||
> **Status: scaffolded, not yet implemented.** This role has no tasks yet — applying it
|
||||
> is a no-op. It is wired into `playbooks/site.yml` so the full standard state is
|
||||
> expressed end-to-end, and so `make lint` covers it. See `STATUS.md`.
|
||||
|
||||
## Planned scope
|
||||
|
||||
- Install Docker engine + the Compose plugin, version-pinned (ADR-011).
|
||||
- Daemon hardening: `iptables: false` (the host `base` firewall owns nftables, ADR-020),
|
||||
log driver, `live-restore`, user-namespace remapping where practical (ADR-002).
|
||||
- Render container forward/NAT rules into `/etc/nftables.d/*.nft` — the include hook the
|
||||
`base` role's ruleset exposes (see `roles/base/README.md`).
|
||||
- Provide the runtime the service roles deploy their Compose files onto.
|
||||
|
||||
## Variables
|
||||
|
||||
None yet. Placeholders will use the `docker_host__*` namespace (CLAUDE.md convention).
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
- hosts: docker_hosts
|
||||
become: true
|
||||
roles:
|
||||
- role: docker_host
|
||||
tags: [docker_host]
|
||||
```
|
||||
|
||||
See ADR-004 (`docs/decisions/004-docker-model.md`) for the Docker & Compose model.
|
||||
1
roles/docker_host/defaults/main.yml
Normal file
1
roles/docker_host/defaults/main.yml
Normal file
|
|
@ -0,0 +1 @@
|
|||
---
|
||||
1
roles/docker_host/handlers/main.yml
Normal file
1
roles/docker_host/handlers/main.yml
Normal file
|
|
@ -0,0 +1 @@
|
|||
---
|
||||
11
roles/docker_host/meta/main.yml
Normal file
11
roles/docker_host/meta/main.yml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
galaxy_info:
|
||||
author: sjat
|
||||
description: Docker engine + Compose runtime for boma docker_hosts (Debian 13).
|
||||
license: MIT
|
||||
min_ansible_version: "2.17"
|
||||
platforms:
|
||||
- name: Debian
|
||||
versions:
|
||||
- trixie
|
||||
dependencies: []
|
||||
7
roles/docker_host/molecule/default/converge.yml
Normal file
7
roles/docker_host/molecule/default/converge.yml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
roles:
|
||||
- role: docker_host
|
||||
31
roles/docker_host/molecule/default/molecule.yml
Normal file
31
roles/docker_host/molecule/default/molecule.yml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
dependency:
|
||||
name: galaxy
|
||||
options:
|
||||
requirements-file: ../../requirements.yml
|
||||
|
||||
driver:
|
||||
name: docker
|
||||
|
||||
platforms:
|
||||
- name: instance
|
||||
# Project-owned image built from .docker/molecule-debian13/Dockerfile
|
||||
# and hosted in the Forgejo container registry.
|
||||
# Build/push with: make molecule-image / make molecule-image-push
|
||||
image: forgejo.nyumbani.baobab.band/sjat/molecule-debian13:latest
|
||||
pre_build_image: true
|
||||
privileged: true # required for systemd
|
||||
cgroupns_mode: host
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:rw
|
||||
command: /lib/systemd/systemd
|
||||
|
||||
provisioner:
|
||||
name: ansible
|
||||
inventory:
|
||||
host_vars:
|
||||
instance:
|
||||
ansible_user: root
|
||||
|
||||
verifier:
|
||||
name: ansible
|
||||
11
roles/docker_host/molecule/default/verify.yml
Normal file
11
roles/docker_host/molecule/default/verify.yml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
- name: Verify
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
tasks:
|
||||
- name: Add verification tasks here
|
||||
ansible.builtin.assert:
|
||||
that: true
|
||||
msg: "Replace this with real assertions"
|
||||
tags: [verify]
|
||||
13
roles/docker_host/tasks/main.yml
Normal file
13
roles/docker_host/tasks/main.yml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
# docker_host — Docker engine + Compose runtime for hosts in the docker_hosts group.
|
||||
#
|
||||
# SCAFFOLDED, NOT YET IMPLEMENTED. This role is referenced by playbooks/site.yml so the
|
||||
# full standard state is expressed end-to-end, but it has no tasks yet — applying it is a
|
||||
# no-op. See STATUS.md ("Scaffolded but empty") and ADR-004 (Docker & Compose model).
|
||||
#
|
||||
# Planned scope (ADR-002/004/020):
|
||||
# - install Docker engine + compose plugin (version-pinned, per ADR-011)
|
||||
# - daemon hardening: iptables:false (host nftables owns the firewall, ADR-020),
|
||||
# log-driver, live-restore, userns where practical
|
||||
# - render container forward/NAT rules into /etc/nftables.d/*.nft (the base-role hook)
|
||||
# - deploy per-service Compose stacks from the service roles (one service = one role)
|
||||
Loading…
Add table
Reference in a new issue