Feat: support mark stage in gc when workflow failed (#5882)

Signed-off-by: Somefive <yd219913@alibaba-inc.com>
This commit is contained in:
Somefive
2023-04-20 14:05:45 +08:00
committed by GitHub
parent 351cb83f15
commit 106b7b3670
8 changed files with 70 additions and 3 deletions

View File

@@ -31,6 +31,9 @@ type GarbageCollectPolicySpec struct {
// outdated resources will be kept until resourcetracker be deleted manually
KeepLegacyResource bool `json:"keepLegacyResource,omitempty"`
// ContinueOnFailure if is set, continue to execute gc when the workflow fails, by default gc will be executed only after the workflow succeeds
ContinueOnFailure bool `json:"continueOnFailure,omitempty"`
// Order defines the order of garbage collect
Order GarbageCollectOrder `json:"order,omitempty"`

View File

@@ -36,6 +36,8 @@ spec:
parameter: {
// +usage=If is set, outdated versioned resourcetracker will not be recycled automatically, outdated resources will be kept until resourcetracker be deleted manually
keepLegacyResource: *false | bool
// +usage=If is set, continue to execute gc when the workflow fails, by default gc will be executed only after the workflow succeeds
continueOnFailure: *false | bool
// +usage=Specify the list of rules to control gc strategy at resource level, if one resource is controlled by multiple rules, first rule will be used
rules?: [...#GarbageCollectPolicyRule]
}

View File

@@ -36,6 +36,8 @@ spec:
parameter: {
// +usage=If is set, outdated versioned resourcetracker will not be recycled automatically, outdated resources will be kept until resourcetracker be deleted manually
keepLegacyResource: *false | bool
// +usage=If is set, continue to execute gc when the workflow fails, by default gc will be executed only after the workflow succeeds
continueOnFailure: *false | bool
// +usage=Specify the list of rules to control gc strategy at resource level, if one resource is controlled by multiple rules, first rule will be used
rules?: [...#GarbageCollectPolicyRule]
}

View File

@@ -315,7 +315,7 @@ func (r *Reconciler) gcResourceTrackers(logCtx monitorContext.Context, handler *
if !gcOutdated {
options = append(options, resourcekeeper.DisableMarkStageGCOption{}, resourcekeeper.DisableGCComponentRevisionOption{}, resourcekeeper.DisableLegacyGCOption{})
}
finished, waiting, err := handler.resourceKeeper.GarbageCollect(logCtx, options...)
finished, waiting, err := handler.resourceKeeper.GarbageCollect(resourcekeeper.WithPhase(logCtx, phase), options...)
if err != nil {
logCtx.Error(err, "Failed to gc resourcetrackers")
cond := condition.Deleting()

View File

@@ -0,0 +1,38 @@
/*
Copyright 2023 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package resourcekeeper
import (
"context"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
)
type contextKey int
const contextPhaseKey contextKey = iota
// WithPhase inject phase into context
func WithPhase(ctx context.Context, phase common.ApplicationPhase) context.Context {
return context.WithValue(ctx, contextPhaseKey, phase)
}
// PhaseFrom extract phase from context
func PhaseFrom(ctx context.Context) common.ApplicationPhase {
phase, _ := ctx.Value(contextPhaseKey).(common.ApplicationPhase)
return phase
}

View File

@@ -25,6 +25,7 @@ import (
"github.com/crossplane/crossplane-runtime/pkg/meta"
"github.com/hashicorp/go-version"
"github.com/kubevela/pkg/util/slices"
"github.com/pkg/errors"
appsv1 "k8s.io/api/apps/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
@@ -33,6 +34,7 @@ import (
utilfeature "k8s.io/apiserver/pkg/util/feature"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/pkg/auth"
@@ -104,6 +106,10 @@ func newGCConfig(options ...GCOption) *gcConfig {
//
// For one single application, the deletion will follow Mark -> Finalize -> Sweep
func (h *resourceKeeper) GarbageCollect(ctx context.Context, options ...GCOption) (finished bool, waiting []v1beta1.ManagedResource, err error) {
return h.garbageCollect(ctx, h.buildGCConfig(ctx, options...))
}
func (h *resourceKeeper) buildGCConfig(ctx context.Context, options ...GCOption) *gcConfig {
if h.garbageCollectPolicy != nil {
if h.garbageCollectPolicy.KeepLegacyResource {
options = append(options, PassiveGCOption{})
@@ -113,9 +119,14 @@ func (h *resourceKeeper) GarbageCollect(ctx context.Context, options ...GCOption
options = append(options, DependencyGCOption{})
default:
}
if h.garbageCollectPolicy.ContinueOnFailure && PhaseFrom(ctx) == common.ApplicationWorkflowFailed {
options = slices.Filter(options, func(opt GCOption) bool {
_, ok := opt.(DisableMarkStageGCOption)
return !ok
})
}
}
cfg := newGCConfig(options...)
return h.garbageCollect(ctx, cfg)
return newGCConfig(options...)
}
func (h *resourceKeeper) garbageCollect(ctx context.Context, cfg *gcConfig) (finished bool, waiting []v1beta1.ManagedResource, err error) {

View File

@@ -339,3 +339,12 @@ func TestCheckDependentComponent(t *testing.T) {
r.Equal(gcHandler.checkDependentComponent(mr), tc.result)
}
}
func TestEnableMarkStageGCOnWorkflowFailure(t *testing.T) {
h := &resourceKeeper{garbageCollectPolicy: &v1alpha1.GarbageCollectPolicySpec{ContinueOnFailure: true}}
options := []GCOption{DisableMarkStageGCOption{}}
cfg := h.buildGCConfig(context.Background(), options...)
require.True(t, cfg.disableMark)
cfg = h.buildGCConfig(WithPhase(context.Background(), apicommon.ApplicationWorkflowFailed), options...)
require.False(t, cfg.disableMark)
}

View File

@@ -32,6 +32,8 @@ template: {
parameter: {
// +usage=If is set, outdated versioned resourcetracker will not be recycled automatically, outdated resources will be kept until resourcetracker be deleted manually
keepLegacyResource: *false | bool
// +usage=If is set, continue to execute gc when the workflow fails, by default gc will be executed only after the workflow succeeds
continueOnFailure: *false | bool
// +usage=Specify the list of rules to control gc strategy at resource level, if one resource is controlled by multiple rules, first rule will be used
rules?: [...#GarbageCollectPolicyRule]
}