cli-utils/pkg/apply/taskrunner/context.go

136 lines
3.8 KiB
Go

// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package taskrunner
import (
"strings"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"sigs.k8s.io/cli-utils/pkg/apply/event"
"sigs.k8s.io/cli-utils/pkg/object"
)
// NewTaskContext returns a new TaskContext
func NewTaskContext(eventChannel chan event.Event) *TaskContext {
return &TaskContext{
taskChannel: make(chan TaskResult),
eventChannel: eventChannel,
appliedResources: make(map[object.ObjMetadata]applyInfo),
failedResources: make(map[object.ObjMetadata]struct{}),
pruneFailures: make(map[object.ObjMetadata]struct{}),
}
}
// TaskContext defines a context that is passed between all
// the tasks that is in a taskqueue.
type TaskContext struct {
taskChannel chan TaskResult
eventChannel chan event.Event
appliedResources map[object.ObjMetadata]applyInfo
// failedResources records the IDs of resources that are failed during applying.
failedResources map[object.ObjMetadata]struct{}
// pruneFailures records the IDs of resources that are failed during pruning.
pruneFailures map[object.ObjMetadata]struct{}
}
func (tc *TaskContext) TaskChannel() chan TaskResult {
return tc.taskChannel
}
func (tc *TaskContext) EventChannel() chan event.Event {
return tc.eventChannel
}
// ResourceApplied updates the context with information about the
// resource identified by the provided id. Currently, we keep information
// about the generation of the resource after the apply operation completed.
func (tc *TaskContext) ResourceApplied(id object.ObjMetadata, uid types.UID, gen int64) {
tc.appliedResources[id] = applyInfo{
generation: gen,
uid: uid,
}
}
// ResourceUID looks up the UID of the given resource
func (tc *TaskContext) ResourceUID(id object.ObjMetadata) (types.UID, bool) {
ai, found := tc.appliedResources[id]
if !found {
return "", false
}
return ai.uid, true
}
// AppliedResources returns all the objects (as ObjMetadata) that
// were added as applied resources to the TaskContext.
func (tc *TaskContext) AppliedResources() []object.ObjMetadata {
all := make([]object.ObjMetadata, 0, len(tc.appliedResources))
for r := range tc.appliedResources {
all = append(all, r)
}
return all
}
// AllResourceUIDs returns a set with the UIDs of all the resources in the
// context.
func (tc *TaskContext) AllResourceUIDs() sets.String {
uids := sets.NewString()
for _, ai := range tc.appliedResources {
uid := strings.TrimSpace(string(ai.uid))
if uid != "" {
uids.Insert(uid)
}
}
return uids
}
// ResourceGeneration looks up the generation of the given resource
// after it was applied.
func (tc *TaskContext) ResourceGeneration(id object.ObjMetadata) (int64, bool) {
ai, found := tc.appliedResources[id]
if !found {
return 0, false
}
return ai.generation, true
}
func (tc *TaskContext) ResourceFailed(id object.ObjMetadata) bool {
_, found := tc.failedResources[id]
return found
}
func (tc *TaskContext) CaptureResourceFailure(id object.ObjMetadata) {
tc.failedResources[id] = struct{}{}
}
func (tc *TaskContext) CapturePruneFailure(id object.ObjMetadata) {
tc.pruneFailures[id] = struct{}{}
}
func (tc *TaskContext) PruneFailures() []object.ObjMetadata {
failures := make([]object.ObjMetadata, 0, len(tc.pruneFailures))
for f := range tc.pruneFailures {
failures = append(failures, f)
}
return failures
}
// applyInfo captures information about resources that have been
// applied. This is captured in the TaskContext so other tasks
// running later might use this information.
type applyInfo struct {
// generation captures the "version" of the resource after it
// has been applied. Generation is a monotonically increasing number
// that the APIServer increases every time the desired state of a
// resource changes.
generation int64
// uid captures the uid of the resource that has been applied.
uid types.UID
}