Implement shared-root takeover policy

This commit is contained in:
2026-06-18 15:27:50 +00:00
parent c02106987f
commit 11d1eabe2a
7 changed files with 386 additions and 44 deletions

View File

@@ -148,7 +148,7 @@ func executeSharedRoot(ctx context.Context, req Request, plan Plan) error {
return err
}
}
if plan.Action == ActionReplaceOlder && plan.Reconciliation.Mode == config.ReconciliationModeReplace {
if plan.Action == ActionReplaceTakeover || (plan.Action == ActionReplaceOlder && plan.Reconciliation.Mode == config.ReconciliationModeReplace) {
if err := req.DestinationBackend.DeleteManagedOutputs(ctx, req.DestinationBundlePath, sharedRootOutputPaths(plan.OwnerOutputsToDelete), storage.DeleteOptions{IgnoreMissing: true, PruneEmptyDirs: true}); err != nil {
return err
}
@@ -158,7 +158,7 @@ func executeSharedRoot(ctx context.Context, req Request, plan Plan) error {
newOutputs := make([]Output, 0, len(plan.Outputs))
cleanup := func() {
outputs := writtenOutputs
if plan.Reconciliation.Mode == config.ReconciliationModeMerge {
if plan.Action == ActionReplaceOlder && plan.Reconciliation.Mode == config.ReconciliationModeMerge {
outputs = newOutputs
}
_ = req.DestinationBackend.DeleteManagedOutputs(ctx, req.DestinationBundlePath, ManagedOutputPaths(outputs), storage.DeleteOptions{IgnoreMissing: true, PruneEmptyDirs: true})
@@ -257,6 +257,11 @@ func outputManagedBySharedRootPlan(output Output, plan Plan) bool {
return true
}
}
for _, existing := range plan.TakenOverOwnerOutputs {
if existing.Path == output.DestinationPath {
return true
}
}
return false
}
@@ -283,6 +288,7 @@ func sharedRootStateForPlan(req Request, plan Plan, now time.Time) (state.Shared
scope = state.CurrentOwnerScope(req.PipelineID, req.DestinationID)
}
base := sharedRootBaseState(req, plan, now)
base = removeTakenOverSharedRootOutputs(base, plan.TakenOverOwnerOutputs)
owner := state.OwnerRecord{
Scope: scope,
Reconciliation: state.ReconciliationPolicy{Mode: plan.Reconciliation.Mode},
@@ -319,6 +325,22 @@ func sharedRootBaseState(req Request, plan Plan, now time.Time) state.SharedRoot
return newSharedRootState(req, now)
}
func removeTakenOverSharedRootOutputs(sharedRoot state.SharedRootState, takenOver []state.SharedRootOutputFile) state.SharedRootState {
if len(takenOver) == 0 {
return sharedRoot
}
paths := sharedRootOutputPathSet(takenOver)
next := sharedRoot
next.Outputs = make([]state.SharedRootOutputFile, 0, len(sharedRoot.Outputs))
for _, output := range sharedRoot.Outputs {
if _, remove := paths[output.Path]; remove {
continue
}
next.Outputs = append(next.Outputs, output)
}
return next
}
func newSharedRootState(req Request, now time.Time) state.SharedRootState {
return state.SharedRootState{
SchemaVersion: state.SharedRootSchemaVersion,