Skip to content

feat(incus/proxmox): tag managed containers and filter sync by default#76

Merged
pofallon merged 2 commits into
mainfrom
013-managed-instance-tags
Jul 22, 2026
Merged

feat(incus/proxmox): tag managed containers and filter sync by default#76
pofallon merged 2 commits into
mainfrom
013-managed-instance-tags

Conversation

@pofallon

Copy link
Copy Markdown
Contributor

What & why

remo's four providers split into two mental models for sync: AWS/Hetzner
filter on a provider-native marker (tag:remo=true / label_selector=remo) and
only touch remo-created instances, while Incus/Proxmox marked nothing and
imported every container on the host. This closes that gap.

Incus/Proxmox containers remo creates are now marked at provision time, and
sync filters on that marker by default, with an explicit --all opt-out.

Implements spec 013-managed-instance-tags (FR-001…FR-013, SC-001…SC-006).

Behavior

  • create / update apply a fixed, provider-native marker host-side
    (Incus user.remo=true config key; Proxmox remo guest tag). Idempotent;
    Proxmox preserves existing tags via a tag-set union. A marking failure warns
    but never fails the command (FR-005).
  • sync (default) registers only marked containers and names any skipped
    unmarked ones with both remedies (--all, update <name>).
  • sync --all restores the pre-feature "adopt everything" behavior and flags
    the adopted-unmarked count.
  • sync stays read-only; one bulk marker query per provider (FR-013).
  • No change to AWS/Hetzner, the registry line format, or the connect path.

Design note

The marker is applied host-side in the Python provider layer, not Ansible,
because update's dev-tools playbook connects to the container's IP, not the
hypervisor host — only the provider layer holds a host/node SSH context at both
create and update time.

Follow-up

Proxmox host access remains root SSH (pct/conf parsing). Migrating that to the
Proxmox REST API is tracked in #75 — that would also expose tags as structured
data, retiring the conf-parsing this PR hardened.

Tests

New unit suites for both providers (marker apply/read, create/update wiring,
filtered sync, --all, FR-010 read-only, FR-013 bounded queries, and a
regression test for snapshot-section tag shadowing). Full suite green locally
(1125 passed); ruff + mypy clean.

🤖 Generated with Claude Code

pofallon and others added 2 commits July 22, 2026 16:45
Mark remo-created Incus/Proxmox containers with a fixed provider-native
marker (Incus user.remo=true config key; Proxmox `remo` guest tag) at
provision time, and make `sync` filter on it by default — bringing the two
hypervisor providers in line with AWS (tag:remo=true) and Hetzner
(label_selector=remo).

- create/update apply the marker host-side (idempotent; Proxmox preserves
  existing tags via a tag-set union); failure warns but never fails the command
- sync registers only marked containers by default and names any skipped ones
  with both remedies (--all, `update <name>`); --all restores the pre-feature
  adopt-everything behavior and flags adopted-unmarked counts
- sync stays read-only and uses a single bulk marker query per provider
- no change to AWS/Hetzner, the registry line format, or the connect path

Implements spec 013-managed-instance-tags (FR-001..FR-013, SC-001..SC-006).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HAPB5GA4NVUgKFsVFVJDxN
Address code-review findings on feature 013:

- _read_tags_by_vmid dumped every LXC conf and grepped `^tags:`, which also
  matched snapshot-section tag lines; dict last-wins could let an old
  snapshot's tags shadow the live tags and mis-classify a marked container
  (silently dropping it from a default sync). Read only the current-config
  tags — the `tags:` line above the first `[snapshot]` section — with the
  section logic in Python so it is unit-tested.
- Add a regression test for snapshot-section tag shadowing.
- Replace a vacuous incus `--all` assertion (a literal-newline substring that
  could never match) with a real check on the adopted-unmarked summary.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HAPB5GA4NVUgKFsVFVJDxN
@pofallon
pofallon merged commit bd45b0c into main Jul 22, 2026
11 of 14 checks passed
@pofallon
pofallon deleted the 013-managed-instance-tags branch July 22, 2026 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant