Skip to content

Commit 27c9edd

Browse files
authored
chore: using domain-qualified finalizers (#6023)
* chore: using domain-qualified finalizers Signed-off-by: Roger Torrentsgenerós <rogert@spotify.com> * test: adding test, fixing others Signed-off-by: Roger Torrentsgenerós <rogert@spotify.com> * chore: use flyte.org/finalizer instead Signed-off-by: Roger Torrentsgenerós <rogert@spotify.com> --------- Signed-off-by: Roger Torrentsgenerós <rogert@spotify.com>
1 parent fd9a378 commit 27c9edd

File tree

13 files changed

+124
-168
lines changed

13 files changed

+124
-168
lines changed

flyteadmin/go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ require (
108108
github.com/go-openapi/jsonpointer v0.19.6 // indirect
109109
github.com/go-openapi/jsonreference v0.20.2 // indirect
110110
github.com/go-openapi/swag v0.22.3 // indirect
111+
github.com/go-redis/redis v6.15.7+incompatible // indirect
111112
github.com/go-sql-driver/mysql v1.6.0 // indirect
112113
github.com/go-test/deep v1.0.7 // indirect
113114
github.com/goccy/go-json v0.10.2 // indirect
@@ -155,6 +156,7 @@ require (
155156
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
156157
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
157158
github.com/ncw/swift v1.0.53 // indirect
159+
github.com/nxadm/tail v1.4.11 // indirect
158160
github.com/ory/go-acc v0.2.6 // indirect
159161
github.com/ory/go-convenience v0.1.0 // indirect
160162
github.com/ory/viper v1.7.5 // indirect
@@ -201,6 +203,7 @@ require (
201203
golang.org/x/term v0.27.0 // indirect
202204
golang.org/x/text v0.21.0 // indirect
203205
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
206+
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
204207
google.golang.org/appengine v1.6.8 // indirect
205208
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect
206209
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
@@ -214,6 +217,7 @@ require (
214217
gopkg.in/yaml.v2 v2.4.0 // indirect
215218
gopkg.in/yaml.v3 v3.0.1 // indirect
216219
k8s.io/apiextensions-apiserver v0.28.4 // indirect
220+
k8s.io/component-base v0.28.4 // indirect
217221
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
218222
sigs.k8s.io/yaml v1.3.0 // indirect
219223
)

flyteadmin/go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,8 @@ github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+
340340
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
341341
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
342342
github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8=
343+
github.com/go-redis/redis v6.15.7+incompatible h1:3skhDh95XQMpnqeqNftPkQD9jL9e5e36z/1SUm6dy1U=
344+
github.com/go-redis/redis v6.15.7+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
343345
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
344346
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
345347
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
@@ -1013,6 +1015,8 @@ github.com/ncw/swift v1.0.53/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/
10131015
github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
10141016
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
10151017
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U=
1018+
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
1019+
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
10161020
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
10171021
github.com/oleiade/reflections v1.0.0/go.mod h1:RbATFBbKYkVdqmSFtx13Bb/tVhR0lgOBXunWTZKeL4w=
10181022
github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM=
@@ -1024,6 +1028,7 @@ github.com/onsi/ginkgo v1.9.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
10241028
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
10251029
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
10261030
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
1031+
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
10271032
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
10281033
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
10291034
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
@@ -1971,6 +1976,7 @@ gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76
19711976
gopkg.in/square/go-jose.v2 v2.5.2-0.20210529014059-a5c7eec3c614/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
19721977
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
19731978
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
1979+
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
19741980
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
19751981
gopkg.in/validator.v2 v2.0.0-20180514200540-135c24b11c19/go.mod h1:o4V0GXN9/CAmCsvJ0oXYZvrZOe7syiDZSN1GWGZTGzc=
19761982
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=

flyteadmin/pkg/workflowengine/impl/prepare_execution.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import (
44
"github.com/golang/protobuf/proto"
55
"google.golang.org/grpc/codes"
66
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
78

89
"github.com/flyteorg/flyte/flyteadmin/pkg/errors"
910
"github.com/flyteorg/flyte/flyteadmin/pkg/workflowengine/interfaces"
1011
"github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/admin"
1112
"github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core"
1213
"github.com/flyteorg/flyte/flytepropeller/pkg/apis/flyteworkflow/v1alpha1"
14+
"github.com/flyteorg/flyte/flytepropeller/pkg/controller"
1315
)
1416

1517
func addMapValues(overrides map[string]string, defaultValues map[string]string) map[string]string {
@@ -130,7 +132,7 @@ func PrepareFlyteWorkflow(data interfaces.ExecutionData, flyteWorkflow *v1alpha1
130132
flyteWorkflow.AcceptedAt = &acceptAtWrapper
131133

132134
// Add finalizer
133-
flyteWorkflow.Finalizers = append(flyteWorkflow.Finalizers, "flyte-finalizer")
135+
_ = controllerutil.AddFinalizer(flyteWorkflow, controller.Finalizer)
134136

135137
// add permissions from auth and security context. Adding permissions from auth would be removed once all clients
136138
// have migrated over to security context

flyteadmin/pkg/workflowengine/impl/prepare_execution_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/admin"
1515
"github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core"
1616
"github.com/flyteorg/flyte/flytepropeller/pkg/apis/flyteworkflow/v1alpha1"
17+
"github.com/flyteorg/flyte/flytepropeller/pkg/controller"
1718
)
1819

1920
const testRole = "role"
@@ -254,5 +255,5 @@ func TestPrepareFlyteWorkflow(t *testing.T) {
254255
OutputLocationPrefix: "s3://bucket/key",
255256
},
256257
})
257-
assert.Equal(t, flyteWorkflow.Finalizers, []string{"flyte-finalizer"})
258+
assert.Equal(t, flyteWorkflow.Finalizers, []string{controller.Finalizer})
258259
}

flyteplugins/go/tasks/plugins/array/k8s/subtask.go

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1414
k8stypes "k8s.io/apimachinery/pkg/types"
1515
"sigs.k8s.io/controller-runtime/pkg/client"
16+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
1617

1718
"github.com/flyteorg/flyte/flyteplugins/go/tasks/errors"
1819
pluginsCore "github.com/flyteorg/flyte/flyteplugins/go/tasks/pluginmachinery/core"
@@ -30,8 +31,11 @@ const (
3031
ErrBuildPodTemplate stdErrors.ErrorCode = "POD_TEMPLATE_FAILED"
3132
ErrReplaceCmdTemplate stdErrors.ErrorCode = "CMD_TEMPLATE_FAILED"
3233
FlyteK8sArrayIndexVarName string = "FLYTE_K8S_ARRAY_INDEX"
33-
finalizer string = "flyte/array"
34-
JobIndexVarName string = "BATCH_JOB_ARRAY_INDEX_VAR_NAME"
34+
finalizer string = "flyte.org/finalizer-array"
35+
// Old non-domain-qualified finalizer for backwards compatibility
36+
// This should eventually be removed
37+
oldFinalizer string = "flyte/array"
38+
JobIndexVarName string = "BATCH_JOB_ARRAY_INDEX_VAR_NAME"
3539
)
3640

3741
var (
@@ -69,8 +73,7 @@ func addMetadata(stCtx SubTaskExecutionContext, cfg *Config, k8sPluginCfg *confi
6973
}
7074

7175
if k8sPluginCfg.InjectFinalizer {
72-
f := append(pod.GetFinalizers(), finalizer)
73-
pod.SetFinalizers(f)
76+
_ = controllerutil.AddFinalizer(pod, finalizer)
7477
}
7578

7679
if len(cfg.DefaultScheduler) > 0 {
@@ -134,25 +137,28 @@ func abortSubtask(ctx context.Context, stCtx SubTaskExecutionContext, cfg *Confi
134137
}
135138

136139
if err != nil && !isK8sObjectNotExists(err) {
137-
logger.Warningf(ctx, "Failed to clear finalizers for Resource with name: %v/%v. Error: %v",
140+
logger.Warningf(ctx, "Failed to clear finalizer for Resource with name: %v/%v. Error: %v",
138141
resourceToFinalize.GetNamespace(), resourceToFinalize.GetName(), err)
139142
return err
140143
}
141144

142145
return nil
143146
}
144147

145-
// clearFinalizers removes finalizers (if they exist) from the k8s resource
146-
func clearFinalizers(ctx context.Context, o client.Object, kubeClient pluginsCore.KubeClient) error {
147-
if len(o.GetFinalizers()) > 0 {
148-
o.SetFinalizers([]string{})
148+
// clearFinalizer removes the Flyte finalizer (if it exists) from the k8s resource
149+
func clearFinalizer(ctx context.Context, o client.Object, kubeClient pluginsCore.KubeClient) error {
150+
// Checking for the old finalizer too for backwards compatibility. This should eventually be removed
151+
// Go does short-circuiting so we have to make sure both are removed
152+
finalizerRemoved := controllerutil.RemoveFinalizer(o, finalizer)
153+
oldFinalizerRemoved := controllerutil.RemoveFinalizer(o, oldFinalizer)
154+
if finalizerRemoved || oldFinalizerRemoved {
149155
err := kubeClient.GetClient().Update(ctx, o)
150156
if err != nil && !isK8sObjectNotExists(err) {
151-
logger.Warningf(ctx, "Failed to clear finalizers for Resource with name: %v/%v. Error: %v", o.GetNamespace(), o.GetName(), err)
157+
logger.Warningf(ctx, "Failed to clear finalizer for Resource with name: %v/%v. Error: %v", o.GetNamespace(), o.GetName(), err)
152158
return err
153159
}
154160
} else {
155-
logger.Debugf(ctx, "Finalizers are already empty for Resource with name: %v/%v", o.GetNamespace(), o.GetName())
161+
logger.Debugf(ctx, "Finalizer is already cleared for Resource with name: %v/%v", o.GetNamespace(), o.GetName())
156162
}
157163
return nil
158164
}
@@ -211,7 +217,7 @@ func launchSubtask(ctx context.Context, stCtx SubTaskExecutionContext, cfg *Conf
211217
}
212218

213219
// finalizeSubtask performs operations to complete the k8s pod defined by the SubTaskExecutionContext
214-
// and Config. These may include removing finalizers and deleting the k8s resource.
220+
// and Config. These may include removing finalizer and deleting the k8s resource.
215221
func finalizeSubtask(ctx context.Context, stCtx SubTaskExecutionContext, cfg *Config, kubeClient pluginsCore.KubeClient) error {
216222
errs := stdErrors.ErrorCollection{}
217223
var pod *v1.Pod
@@ -231,10 +237,10 @@ func finalizeSubtask(ctx context.Context, stCtx SubTaskExecutionContext, cfg *Co
231237
nsName = k8stypes.NamespacedName{Namespace: pod.GetNamespace(), Name: pod.GetName()}
232238
}
233239

234-
// In InjectFinalizer is on, it means we may have added the finalizers when we launched this resource. Attempt to
235-
// clear them to allow the object to be deleted/garbage collected. If InjectFinalizer was turned on (through config)
240+
// In InjectFinalizer is on, it means we may have added the finalizer when we launched this resource. Attempt to
241+
// clear it to allow the object to be deleted/garbage collected. If InjectFinalizer was turned on (through config)
236242
// after the resource was created, we will not find any finalizers to clear and the object may have already been
237-
// deleted at this point. Therefore, account for these cases and do not consider them errors.
243+
// deleted at this point. Therefore, account for these cases and do not consider the errors.
238244
if k8sPluginCfg.InjectFinalizer {
239245
// Attempt to get resource from informer cache, if not found, retrieve it from API server.
240246
if err := kubeClient.GetClient().Get(ctx, nsName, pod); err != nil {
@@ -250,7 +256,7 @@ func finalizeSubtask(ctx context.Context, stCtx SubTaskExecutionContext, cfg *Co
250256
// This must happen after sending admin event. It's safe against partial failures because if the event failed, we will
251257
// simply retry in the next round. If the event succeeded but this failed, we will try again the next round to send
252258
// the same event (idempotent) and then come here again...
253-
err := clearFinalizers(ctx, pod, kubeClient)
259+
err := clearFinalizer(ctx, pod, kubeClient)
254260
if err != nil {
255261
errs.Append(err)
256262
}
@@ -308,10 +314,10 @@ func getSubtaskPhaseInfo(ctx context.Context, stCtx SubTaskExecutionContext, cfg
308314
return pluginsCore.PhaseInfoUndefined, err
309315
}
310316

311-
if !phaseInfo.Phase().IsTerminal() && o.GetDeletionTimestamp() != nil {
317+
if !phaseInfo.Phase().IsTerminal() && !o.GetDeletionTimestamp().IsZero() {
312318
// If the object has been deleted, that is, it has a deletion timestamp, but is not in a terminal state, we should
313319
// mark the task as a retryable failure. We've seen this happen when a kubelet disappears - all pods running on
314-
// the node are marked with a deletionTimestamp, but our finalizers prevent the pod from being deleted.
320+
// the node are marked with a deletionTimestamp, but our finalizer prevents the pod from being deleted.
315321
// This can also happen when a user deletes a Pod directly.
316322
failureReason := fmt.Sprintf("object [%s] terminated in the background, manually", nsName.String())
317323
return pluginsCore.PhaseInfoSystemRetryableFailure("UnexpectedObjectDeletion", failureReason, nil), nil

flytepropeller/pkg/controller/controller.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ import (
6161
)
6262

6363
const (
64+
// Finalizer is the global and domain-qualified Flyte finalizer
65+
Finalizer = "flyte.org/finalizer"
66+
// OldFinalizer is the old non-domain-qualified finalizer, kept for backwards compatibility
67+
// This should eventually be removed
68+
OldFinalizer = "flyte-finalizer"
6469
resourceLevelMonitorCycleDuration = 5 * time.Second
6570
missing = "missing"
6671
podDefaultNamespace = "flyte"

flytepropeller/pkg/controller/finalizer.go

Lines changed: 0 additions & 36 deletions
This file was deleted.

flytepropeller/pkg/controller/finalizer_test.go

Lines changed: 0 additions & 70 deletions
This file was deleted.

flytepropeller/pkg/controller/handler.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/prometheus/client_golang/prometheus"
1111
"go.opentelemetry.io/otel/trace"
12+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
1213

1314
"github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/admin"
1415
"github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core"
@@ -103,7 +104,7 @@ func (p *Propeller) TryMutateWorkflow(ctx context.Context, originalW *v1alpha1.F
103104
ctx = contextutils.WithResourceVersion(ctx, mutableW.GetResourceVersion())
104105

105106
maxRetries := uint32(p.cfg.MaxWorkflowRetries) // #nosec G115
106-
if IsDeleted(mutableW) || (mutableW.Status.FailedAttempts > maxRetries) {
107+
if !mutableW.GetDeletionTimestamp().IsZero() || mutableW.Status.FailedAttempts > maxRetries {
107108
var err error
108109
func() {
109110
defer func() {
@@ -125,7 +126,7 @@ func (p *Propeller) TryMutateWorkflow(ctx context.Context, originalW *v1alpha1.F
125126

126127
if !mutableW.GetExecutionStatus().IsTerminated() {
127128
var err error
128-
SetFinalizerIfEmpty(mutableW, FinalizerKey)
129+
_ = controllerutil.AddFinalizer(mutableW, Finalizer)
129130
SetDefinitionVersionIfEmpty(mutableW, v1alpha1.LatestWorkflowDefinitionVersion)
130131

131132
func() {
@@ -210,7 +211,9 @@ func (p *Propeller) Handle(ctx context.Context, namespace, name string) error {
210211
}
211212

212213
if w.GetExecutionStatus().IsTerminated() {
213-
if HasCompletedLabel(w) && !HasFinalizer(w) {
214+
// Checking for the old finalizer for backwards compatibility
215+
// This should be eventually removed
216+
if HasCompletedLabel(w) && !controllerutil.ContainsFinalizer(w, Finalizer) && !controllerutil.ContainsFinalizer(w, OldFinalizer) {
214217
logger.Debugf(ctx, "Workflow is terminated.")
215218
// This workflow had previously completed, let us ignore it
216219
return nil
@@ -325,7 +328,9 @@ func (p *Propeller) streak(ctx context.Context, w *v1alpha1.FlyteWorkflow, wfClo
325328
// If the end result is a terminated workflow, we remove the labels
326329
// We add a completed label so that we can avoid polling for this workflow
327330
SetCompletedLabel(mutatedWf, time.Now())
328-
ResetFinalizers(mutatedWf)
331+
_ = controllerutil.RemoveFinalizer(mutatedWf, Finalizer)
332+
// Backwards compatibility. This should eventually be removed
333+
_ = controllerutil.RemoveFinalizer(mutatedWf, OldFinalizer)
329334
}
330335
}
331336

@@ -387,7 +392,9 @@ func (p *Propeller) streak(ctx context.Context, w *v1alpha1.FlyteWorkflow, wfClo
387392
mutableW := w.DeepCopy()
388393
// catch potential indefinite update loop
389394
if mutatedWf.GetExecutionStatus().IsTerminated() {
390-
ResetFinalizers(mutableW)
395+
_ = controllerutil.RemoveFinalizer(mutableW, Finalizer)
396+
// Backwards compatibility. This should eventually be removed
397+
_ = controllerutil.RemoveFinalizer(mutableW, OldFinalizer)
391398
SetDefinitionVersionIfEmpty(mutableW, v1alpha1.LatestWorkflowDefinitionVersion)
392399
SetCompletedLabel(mutableW, time.Now())
393400
msg := fmt.Sprintf("Workflow size has breached threshold. Finalized with status: %v", mutatedWf.GetExecutionStatus().GetPhase())

0 commit comments

Comments
 (0)