1package out
2
3import (
4 "context"
5
6 "github.com/bnema/gordon/internal/domain"
7)
8
9// PruneProtectionStore builds the coherent protection snapshot prune
10// plans against. The implementation must read every durable fact in one
11// transaction so no candidate is judged against facts from a different
12// moment, and must report unreadable state as an inventory gap instead
13// of returning an empty (apparently unprotected) snapshot.
14type PruneProtectionStore interface {
15 // ProtectionSnapshot returns every durable fact that protects prune
16 // candidates, including desired and active app state, recovery
17 // inhibitions, staged/committed apply intents, unfinished
18 // operations, and ownership records.
19 ProtectionSnapshot(ctx context.Context) (*domain.PruneProtectionSnapshot, error)
20}
21
22// PruneRuntime inventories runtime resources and deletes exactly the
23// planned targets. It is deliberately not part of ContainerRuntime:
24// prune needs enriched inventory and exact, non-force deletion, and no
25// other use case may reach an implicit runtime-wide prune.
26type PruneRuntime interface {
27 // InventoryRuntime returns one coherent read of runtime images,
28 // container image usage (running and stopped), and volumes with
29 // labels and usage. A failure to inspect part of the runtime is
30 // reported as an inventory gap, never as absence.
31 InventoryRuntime(ctx context.Context) (*domain.RuntimeInventory, error)
32
33 // RemoveImageExact removes exactly the named runtime image ID with
34 // force=false. It never removes images selected by a filter.
35 RemoveImageExact(ctx context.Context, ref domain.RuntimeImageRef) error
36
37 // RemoveVolumeExact removes exactly the named runtime volume with
38 // force=false. It never removes volumes selected by a filter.
39 RemoveVolumeExact(ctx context.Context, ref domain.RuntimeVolumeRef) error
40}
41
42// GCBarrier serializes resource acquisition and its durable protection
43// publication against destructive garbage collection.
44//
45// A shared lease must be held from the moment a deploy, start, restart,
46// remove, recovery, or restore path selects or acquires a runtime
47// resource until that resource's protection is durably published
48// (journal step, ACTIVE state, ownership record). An exclusive lease
49// covers prune's snapshot read, planning, and deletion.
50//
51// Lock order is fixed and documented so the two never deadlock:
52// GC barrier → per-app coordinator → registry mutation lock → short
53// bbolt transaction.
54type GCBarrier interface {
55 // AcquireShared blocks until no exclusive lease is held, then
56 // returns a lease the caller must release. It returns ctx.Err()
57 // when ctx is done or when shutdown happens first.
58 AcquireShared(ctx context.Context) (GCLease, error)
59 // AcquireExclusive blocks until no lease of either kind is held,
60 // then returns a lease the caller must release. It returns ctx.Err()
61 // when ctx is done or when shutdown happens first.
62 AcquireExclusive(ctx context.Context) (GCLease, error)
63}
64
65// GCLease is one held GC barrier lease. Release is idempotent; callers
66// should still defer exactly one Release per acquired lease.
67type GCLease interface {
68 Release()
69}