Skip to content

Commit

Permalink
chore: Change solver to decide which tasks to use
Browse files Browse the repository at this point in the history
- This redesign of the solver moves complexity about deciding which
  tasks to use from the applier/destroyer into the solver. This makes
  the solver more of a solver and less of a "do what your told"-er.
- One major difference is that the InvAddTask is now skipped if there
  are no objects to be applied. This makes logic sense because the
  inventory doesn't need to be expanded.
- This change unblocks unification of graph dependency resolution
  using both the apploy objects and prune objects, which will help
  distinguish between external dependencies and dependencies being
  accidentally deleted.
  • Loading branch information
karlkfi committed Feb 24, 2022
1 parent cb75cc8 commit c5b965f
Show file tree
Hide file tree
Showing 5 changed files with 518 additions and 241 deletions.
51 changes: 26 additions & 25 deletions pkg/apply/applier.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,25 +127,6 @@ func (a *Applier) Run(ctx context.Context, invInfo inventory.Info, objects objec

// Fetch the queue (channel) of tasks that should be executed.
klog.V(4).Infoln("applier building task queue...")
taskBuilder := &solver.TaskQueueBuilder{
Pruner: a.pruner,
DynamicClient: a.client,
OpenAPIGetter: a.openAPIGetter,
InfoHelper: a.infoHelper,
Mapper: a.mapper,
InvClient: a.invClient,
Destroy: false,
Collector: vCollector,
}
opts := solver.Options{
ServerSideOptions: options.ServerSideOptions,
ReconcileTimeout: options.ReconcileTimeout,
Prune: !options.NoPrune,
DryRunStrategy: options.DryRunStrategy,
PrunePropagationPolicy: options.PrunePropagationPolicy,
PruneTimeout: options.PruneTimeout,
InventoryPolicy: options.InventoryPolicy,
}
// Build list of apply validation filters.
applyFilters := []filter.ValidationFilter{
filter.InventoryPolicyApplyFilter{
Expand All @@ -155,7 +136,6 @@ func (a *Applier) Run(ctx context.Context, invInfo inventory.Info, objects objec
InvPolicy: options.InventoryPolicy,
},
}

// Build list of prune validation filters.
pruneFilters := []filter.ValidationFilter{
filter.PreventRemoveFilter{},
Expand All @@ -176,14 +156,35 @@ func (a *Applier) Run(ctx context.Context, invInfo inventory.Info, objects objec
ResourceCache: resourceCache,
},
}
taskBuilder := &solver.TaskQueueBuilder{
Pruner: a.pruner,
DynamicClient: a.client,
OpenAPIGetter: a.openAPIGetter,
InfoHelper: a.infoHelper,
Mapper: a.mapper,
InvClient: a.invClient,
Collector: vCollector,
ApplyFilters: applyFilters,
ApplyMutators: applyMutators,
PruneFilters: pruneFilters,
}
opts := solver.Options{
ServerSideOptions: options.ServerSideOptions,
ReconcileTimeout: options.ReconcileTimeout,
Destroy: false,
Prune: !options.NoPrune,
DryRunStrategy: options.DryRunStrategy,
PrunePropagationPolicy: options.PrunePropagationPolicy,
PruneTimeout: options.PruneTimeout,
InventoryPolicy: options.InventoryPolicy,
}

// Build the ordered set of tasks to execute.
taskQueue := taskBuilder.
AppendInvAddTask(invInfo, applyObjs, options.DryRunStrategy).
AppendApplyWaitTasks(applyObjs, applyFilters, applyMutators, opts).
AppendPruneWaitTasks(pruneObjs, pruneFilters, opts).
AppendInvSetTask(invInfo, options.DryRunStrategy).
Build()
WithApplyObjects(applyObjs).
WithPruneObjects(pruneObjs).
WithInventory(invInfo).
Build(opts)

klog.V(4).Infof("validation errors: %d", len(vCollector.Errors))
klog.V(4).Infof("invalid objects: %d", len(vCollector.InvalidIds))
Expand Down
48 changes: 0 additions & 48 deletions pkg/apply/applier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -674,22 +674,6 @@ func TestApplier(t *testing.T) {
EventType: event.InitType,
InitEvent: &testutil.ExpInitEvent{},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
GroupName: "inventory-add-0",
Action: event.InventoryAction,
Type: event.Started,
},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
GroupName: "inventory-add-0",
Action: event.InventoryAction,
Type: event.Finished,
},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
Expand Down Expand Up @@ -953,22 +937,6 @@ func TestApplier(t *testing.T) {
EventType: event.InitType,
InitEvent: &testutil.ExpInitEvent{},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
GroupName: "inventory-add-0",
Action: event.InventoryAction,
Type: event.Started,
},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
GroupName: "inventory-add-0",
Action: event.InventoryAction,
Type: event.Finished,
},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
Expand Down Expand Up @@ -1092,22 +1060,6 @@ func TestApplier(t *testing.T) {
EventType: event.InitType,
InitEvent: &testutil.ExpInitEvent{},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
GroupName: "inventory-add-0",
Action: event.InventoryAction,
Type: event.Started,
},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
GroupName: "inventory-add-0",
Action: event.InventoryAction,
Type: event.Finished,
},
},
{
EventType: event.ActionGroupType,
ActionGroupEvent: &testutil.ExpActionGroupEvent{
Expand Down
30 changes: 16 additions & 14 deletions pkg/apply/destroyer.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,15 @@ func setDestroyerDefaults(o *DestroyerOptions) {
// Run performs the destroy step. Passes the inventory object. This
// happens asynchronously on progress and any errors are reported
// back on the event channel.
func (d *Destroyer) Run(ctx context.Context, inv inventory.Info, options DestroyerOptions) <-chan event.Event {
func (d *Destroyer) Run(ctx context.Context, invInfo inventory.Info, options DestroyerOptions) <-chan event.Event {
eventChannel := make(chan event.Event)
setDestroyerDefaults(&options)
go func() {
defer close(eventChannel)
// Retrieve the objects to be deleted from the cluster. Second parameter is empty
// because no local objects returns all inventory objects for deletion.
emptyLocalObjs := object.UnstructuredSet{}
deleteObjs, err := d.pruner.GetPruneObjs(inv, emptyLocalObjs, prune.Options{
deleteObjs, err := d.pruner.GetPruneObjs(invInfo, emptyLocalObjs, prune.Options{
DryRunStrategy: options.DryRunStrategy,
})
if err != nil {
Expand Down Expand Up @@ -135,35 +135,37 @@ func (d *Destroyer) Run(ctx context.Context, inv inventory.Info, options Destroy
handleError(eventChannel, err)
return
}
deleteFilters := []filter.ValidationFilter{
filter.PreventRemoveFilter{},
filter.InventoryPolicyFilter{
Inv: invInfo,
InvPolicy: options.InventoryPolicy,
},
}
taskBuilder := &solver.TaskQueueBuilder{
Pruner: d.pruner,
DynamicClient: dynamicClient,
OpenAPIGetter: d.factory.OpenAPIGetter(),
InfoHelper: info.NewHelper(mapper, d.factory.UnstructuredClientForMapping),
Mapper: mapper,
InvClient: d.invClient,
Destroy: true,
Collector: vCollector,
PruneFilters: deleteFilters,
}
opts := solver.Options{
Destroy: true,
Prune: true,
PruneTimeout: options.DeleteTimeout,
DryRunStrategy: options.DryRunStrategy,
PrunePropagationPolicy: options.DeletePropagationPolicy,
}
deleteFilters := []filter.ValidationFilter{
filter.PreventRemoveFilter{},
filter.InventoryPolicyFilter{
Inv: inv,
InvPolicy: options.InventoryPolicy,
},
PruneTimeout: options.DeleteTimeout,
InventoryPolicy: options.InventoryPolicy,
}

// Build the ordered set of tasks to execute.
taskQueue := taskBuilder.
AppendPruneWaitTasks(deleteObjs, deleteFilters, opts).
AppendDeleteInvTask(inv, options.DryRunStrategy).
Build()
WithPruneObjects(deleteObjs).
WithInventory(invInfo).
Build(opts)

klog.V(4).Infof("validation errors: %d", len(vCollector.Errors))
klog.V(4).Infof("invalid objects: %d", len(vCollector.InvalidIds))
Expand Down
Loading

0 comments on commit c5b965f

Please sign in to comment.