142 lines
6.6 KiB
Markdown
142 lines
6.6 KiB
Markdown
# STATUS — phase mailu (backupbot labels for mailu recipe)
|
|
|
|
**Phase plan:** `/srv/cc-ci/cc-ci-plan/plan-phase-mailu-backup.md`
|
|
**Builder:** autonomic-bot / Claude (Builder loop)
|
|
**Started:** 2026-06-11T18:00Z
|
|
|
|
---
|
|
|
|
## Current state
|
|
|
|
**Gate M1: PASS** (Adversary verified @2026-06-11T21:00Z — see REVIEW-mailu.md)
|
|
|
|
**Gate M2: PASS** (Adversary verified @2026-06-11T21:15Z — build #483 L5; all DoD satisfied)
|
|
|
|
## DONE
|
|
|
|
Phase `mailu` complete. M1 PASS @2026-06-11T21:00Z + M2 PASS @2026-06-11T21:15Z.
|
|
|
|
**PR left open for operator merge:**
|
|
https://git.autonomic.zone/recipe-maintainers/mailu/pulls/3
|
|
(branch `add-backupbot-labels`, head `edc0201a79d36bc87696b0f93f1ee88ad7bd10ed`)
|
|
|
|
**Evidence:**
|
|
- Drone build #477 (ADV-mailu-01 fix re-claim): LEVEL 5, all rungs PASS
|
|
- Drone build #483 (Adversary fresh independent re-trigger): LEVEL 5, all rungs PASS
|
|
- Both builds: `test_backup_captures_mailbox`, `test_backup_captures_mail_message`,
|
|
`test_restore_returns_mailbox`, `test_restore_returns_mail_message` — all PASS
|
|
- DEFERRED entry closed; PARITY.md updated; operator summary in this file
|
|
|
|
**What operator does next:** merge PR#3 on `recipe-maintainers/mailu`.
|
|
|
|
---
|
|
|
|
## DoD tracker (M1) — COMPLETE
|
|
|
|
- [x] Data-layout research documented (which volumes hold durable state, justification in PR desc)
|
|
- [x] Recipe-mirror PR open with backupbot v2 labels (admin `/data` + imap `/mail`)
|
|
- **PR#3**: https://git.autonomic.zone/recipe-maintainers/mailu/pulls/3
|
|
- Branch: `add-backupbot-labels`, head commit: `edc0201a79d36bc87696b0f93f1ee88ad7bd10ed`
|
|
- Version bump: `3.0.1+2024.06.52` → `3.0.2+2024.06.52`
|
|
- Adds `deploy.labels: {backupbot.backup: "true", backupbot.backup.path: "/data"}` to `admin`
|
|
- Adds `deploy.labels: {backupbot.backup: "true", backupbot.backup.path: "/mail"}` to `imap`
|
|
- [x] cc-ci: `tests/mailu/ops.py` — pre_backup seeds account + injects mail message; pre_restore wipes both sqlite record AND Maildir
|
|
- [x] cc-ci: `tests/mailu/test_backup.py` — two tests: mailbox + mail message present at backup time
|
|
- [x] cc-ci: `tests/mailu/test_restore.py` — two tests: mailbox + mail message restored after restore
|
|
- [x] cc-ci: `tests/mailu/PARITY.md` updated (P4 COVERED with dual-volume evidence)
|
|
- [x] Drone build #477: LEVEL 5 PASS at PR head — all rungs including backup/restore on both volumes
|
|
- `test_backup_captures_mailbox` PASS — SQLite `/data` covered
|
|
- `test_backup_captures_mail_message` PASS — Maildir `/mail` covered
|
|
- `test_restore_returns_mailbox` PASS — SQLite `/data` restored
|
|
- `test_restore_returns_mail_message` PASS — Maildir `/mail` restored
|
|
- `clean_teardown: true`, `no_secret_leak: true`
|
|
- [x] Before/after: BEFORE = L4 (backup intentional-skip); AFTER = L5 (earned)
|
|
- [x] M1 Adversary PASS @2026-06-11T21:00Z; ADV-mailu-01 closed
|
|
|
|
## DoD tracker (M2) — IN PROGRESS
|
|
|
|
- [x] DEFERRED entry closed (DEFERRED.md — mailu entry marked CLOSED @2026-06-11 with PR+run pointers)
|
|
- [x] Levels reconciled (PARITY.md updated; before=L4-skip, after=L5-earned, proven in builds #473/#477)
|
|
- [x] Operator summary written (this STATUS-mailu.md — see below)
|
|
- [ ] Fresh Adversary cold pass (independent re-trigger at PR#3 head, restore integrity re-checked)
|
|
- [ ] REVIEW-mailu.md shows M2 PASS (within 24h of M1)
|
|
|
|
---
|
|
|
|
## Verification recipe (for Adversary M2 check)
|
|
|
|
```bash
|
|
# 1. Verify PR#3 is still open and unmerged, head commit unchanged
|
|
GITEA_PASSWORD=$(grep GITEA_PASSWORD /srv/cc-ci/.testenv | cut -d= -f2-)
|
|
curl -s "https://git.autonomic.zone/api/v1/repos/recipe-maintainers/mailu/pulls/3" \
|
|
-u "autonomic-bot:${GITEA_PASSWORD}" | python3 -c "
|
|
import sys,json; pr=json.load(sys.stdin)
|
|
print('state:', pr['state'])
|
|
print('head sha:', pr['head']['sha'])
|
|
print('merged:', pr.get('merged', False))
|
|
"
|
|
# Expected: state=open, head sha=edc0201a79d36bc87696b0f93f1ee88ad7bd10ed, merged=False
|
|
|
|
# 2. Re-trigger via !testme on PR#3 (Adversary does this independently)
|
|
# Expected: new drone build reaches LEVEL 5, all backup/restore tests PASS
|
|
|
|
# 3. Verify DEFERRED.md mailu entry is closed
|
|
grep -A3 "2026-05-29 — mailu" /srv/cc-ci/cc-ci-adv/machine-docs/DEFERRED.md
|
|
# Expected: [x] CLOSED @2026-06-11 with PR#3 + build #477 pointer
|
|
|
|
# 4. Verify PARITY.md updated with full dual-volume coverage
|
|
cat /srv/cc-ci/cc-ci-adv/tests/mailu/PARITY.md | grep -A20 "Backup data-integrity"
|
|
# Expected: mentions both /data (SQLite) and /mail (Maildir), both volumes seeded+wiped+verified
|
|
|
|
# 5. Confirm levels: before=L4, after=L5
|
|
# BEFORE: git.autonomic.zone/recipe-maintainers/mailu main — no backupbot labels → backup_capable=False → skip → L4
|
|
# AFTER: PR#3 head edc0201a79d3 — backupbot labels present → backup_capable=True → L5 (all rungs earned)
|
|
```
|
|
|
|
---
|
|
|
|
## Operator summary (for handoff)
|
|
|
|
### What this phase delivered
|
|
|
|
**PR#3 on `git.autonomic.zone/recipe-maintainers/mailu`** (branch `add-backupbot-labels`,
|
|
head `edc0201a79d36bc87696b0f93f1ee88ad7bd10ed`) — **open, awaiting operator merge.**
|
|
|
|
**What the PR adds:**
|
|
- Backupbot v2 labels on `admin` service: `backupbot.backup: "true"` + `backupbot.backup.path: "/data"`
|
|
— backs up the SQLite database at `/data` (all accounts, mailboxes, domains, DKIM config)
|
|
- Backupbot v2 labels on `imap` service: `backupbot.backup: "true"` + `backupbot.backup.path: "/mail"`
|
|
— backs up the Maildir at `/mail` (all stored messages for all users)
|
|
- Version bump: `3.0.1+2024.06.52` → `3.0.2+2024.06.52` (recipe version convention)
|
|
- No other compose changes; minimal diff
|
|
|
|
**What CI proved at PR head (drone build #477):**
|
|
- Install ✅ — fresh deploy of mailu at PR version
|
|
- Upgrade ✅ — previous published version → PR head, reconverges
|
|
- Backup ✅ — creates a mailbox + injects a real mail message; backup snapshot taken; both present at backup time
|
|
- Restore ✅ — wipes both the sqlite account record AND the Maildir; restore brings back both the account AND the stored message
|
|
- Functional ✅ — health check, mail flow (send/receive via postfix→dovecot), mailbox create+read
|
|
- Lint ✅ — abra recipe lint passes
|
|
- Clean teardown, no secret leak
|
|
|
|
**Before/after:**
|
|
- BEFORE (main, no labels): `backup_capable=False` → backup rung = intentional skip → max **L4**
|
|
- AFTER (PR#3 head): `backup_capable=True` (auto-detected from backupbot labels) → backup rung earned → **L5**
|
|
|
|
**To act:** merge PR#3 on `recipe-maintainers/mailu`. After merge, mailu will earn L5 on main
|
|
(`!testme` against main should hit L5 once the recipe is published with the new version).
|
|
|
|
No cc-ci config changes are needed post-merge — the harness auto-detects `backup_capable` from the labels.
|
|
|
|
---
|
|
|
|
## Blocked items
|
|
|
|
(none)
|
|
|
|
---
|
|
|
|
## DONE
|
|
|
|
Not yet. Written here only when M1+M2 Adversary PASS appear in REVIEW-mailu.md.
|