diff --git a/api/v1alpha1/types.go b/api/v1alpha1/types.go index b40b95e..5e1ada6 100644 --- a/api/v1alpha1/types.go +++ b/api/v1alpha1/types.go @@ -160,7 +160,10 @@ type WorkflowList struct { // WorkflowStep defines how to execute a workflow step. type WorkflowStep struct { WorkflowStepBase `json:",inline"` - SubSteps []WorkflowStepBase `json:"subSteps,omitempty"` + // Mode is only valid for sub steps, it defines the mode of the sub steps + // +nullable + Mode WorkflowMode `json:"mode,omitempty"` + SubSteps []WorkflowStepBase `json:"subSteps,omitempty"` } // WorkflowStepMeta contains the meta data of a workflow step diff --git a/charts/vela-workflow/crds/core.oam.dev_workflowruns.yaml b/charts/vela-workflow/crds/core.oam.dev_workflowruns.yaml index 22cb174..2222af0 100644 --- a/charts/vela-workflow/crds/core.oam.dev_workflowruns.yaml +++ b/charts/vela-workflow/crds/core.oam.dev_workflowruns.yaml @@ -96,6 +96,11 @@ spec: alias: type: string type: object + mode: + description: Mode is only valid for sub steps, it defines + the mode of the sub steps + nullable: true + type: string name: description: Name is the unique name of the workflow step. type: string diff --git a/charts/vela-workflow/crds/core.oam.dev_workflows.yaml b/charts/vela-workflow/crds/core.oam.dev_workflows.yaml index d0c2b3d..af83752 100644 --- a/charts/vela-workflow/crds/core.oam.dev_workflows.yaml +++ b/charts/vela-workflow/crds/core.oam.dev_workflows.yaml @@ -75,6 +75,11 @@ spec: alias: type: string type: object + mode: + description: Mode is only valid for sub steps, it defines the mode + of the sub steps + nullable: true + type: string name: description: Name is the unique name of the workflow step. type: string diff --git a/controllers/workflow_test.go b/controllers/workflow_test.go index 5ecb925..0bc7250 100644 --- a/controllers/workflow_test.go +++ b/controllers/workflow_test.go @@ -875,6 +875,80 @@ var _ = Describe("Test Workflow", func() { })) }) + It("test workflow run with mode in step groups", func() { + wr := wrTemplate.DeepCopy() + wr.Name = "wr-group-mode" + wr.Spec.WorkflowSpec.Steps = []v1alpha1.WorkflowStep{ + { + WorkflowStepBase: v1alpha1.WorkflowStepBase{ + Name: "step1", + Type: "test-apply", + Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)}, + }, + }, + { + WorkflowStepBase: v1alpha1.WorkflowStepBase{ + Name: "group", + Type: "step-group", + }, + Mode: v1alpha1.WorkflowModeStep, + SubSteps: []v1alpha1.WorkflowStepBase{ + { + Name: "step2", + Type: "test-apply", + Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)}, + }, + { + Name: "step3", + Type: "test-apply", + Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)}, + }, + }, + }, + } + wr.Spec.Mode = &v1alpha1.WorkflowExecuteMode{ + Steps: v1alpha1.WorkflowModeDAG, + } + + Expect(k8sClient.Create(context.Background(), wr)).Should(BeNil()) + wrKey := types.NamespacedName{Namespace: wr.Namespace, Name: wr.Name} + + tryReconcile(reconciler, wr.Name, wr.Namespace) + + expDeployment := &appsv1.Deployment{} + step3Key := types.NamespacedName{Namespace: wr.Namespace, Name: "step3"} + Expect(k8sClient.Get(ctx, step3Key, expDeployment)).Should(utils.NotFoundMatcher{}) + + checkRun := &v1alpha1.WorkflowRun{} + Expect(k8sClient.Get(ctx, wrKey, checkRun)).Should(BeNil()) + step1Key := types.NamespacedName{Namespace: wr.Namespace, Name: "step1"} + Expect(k8sClient.Get(ctx, step1Key, expDeployment)).Should(BeNil()) + expDeployment.Status.Replicas = 1 + expDeployment.Status.ReadyReplicas = 1 + Expect(k8sClient.Status().Update(ctx, expDeployment)).Should(BeNil()) + step2Key := types.NamespacedName{Namespace: wr.Namespace, Name: "step2"} + Expect(k8sClient.Get(ctx, step2Key, expDeployment)).Should(BeNil()) + expDeployment.Status.Replicas = 1 + expDeployment.Status.ReadyReplicas = 1 + Expect(k8sClient.Status().Update(ctx, expDeployment)).Should(BeNil()) + + tryReconcile(reconciler, wr.Name, wr.Namespace) + + Expect(k8sClient.Get(ctx, step3Key, expDeployment)).Should(BeNil()) + expDeployment.Status.Replicas = 1 + expDeployment.Status.ReadyReplicas = 1 + Expect(k8sClient.Status().Update(ctx, expDeployment)).Should(BeNil()) + + tryReconcile(reconciler, wr.Name, wr.Namespace) + + Expect(k8sClient.Get(ctx, wrKey, checkRun)).Should(BeNil()) + Expect(checkRun.Status.Phase).Should(BeEquivalentTo(v1alpha1.WorkflowStateSucceeded)) + Expect(checkRun.Status.Mode).Should(BeEquivalentTo(v1alpha1.WorkflowExecuteMode{ + Steps: v1alpha1.WorkflowModeDAG, + SubSteps: v1alpha1.WorkflowModeDAG, + })) + }) + It("test sub steps", func() { wr := wrTemplate.DeepCopy() wr.Name = "wr-substeps" diff --git a/go.mod b/go.mod index 8d91d17..fde5e0c 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( github.com/onsi/gomega v1.20.2 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.12.2 + github.com/prometheus/common v0.32.1 github.com/robfig/cron/v3 v3.0.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.0 @@ -172,7 +173,6 @@ require ( github.com/pjbgf/sha1cd v0.2.3 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect github.com/rivo/uniseg v0.4.2 // indirect github.com/sergi/go-diff v1.1.0 // indirect diff --git a/pkg/generator/generator.go b/pkg/generator/generator.go index 9af173b..63e9a96 100644 --- a/pkg/generator/generator.go +++ b/pkg/generator/generator.go @@ -201,6 +201,9 @@ func generateTaskRunner(ctx context.Context, if instance.Mode != nil { options.SubStepExecuteMode = instance.Mode.SubSteps } + if step.Mode != "" { + options.SubStepExecuteMode = step.Mode + } } genTask, err := taskDiscover.GetTaskGenerator(ctx, step.Type)