mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-18 03:56:36 +00:00
Fix: refactor workflow and fix some e2e tests (#2272)
* Fix: add e2e plugin test back * Fix: e2e rollout test and try change port to 37081 * Fix: add rollout plan test back * Refactor: change the workflow state machine and add workflow succeed state * Refactor: refine definition controller and fix e2e of app revision * Refactor: unlock all the normal cases * Fix: add helm schematic logic back into workflow
This commit is contained in:
@@ -82,7 +82,7 @@ jobs:
|
||||
|
||||
- name: Wait for e2e preparation ready
|
||||
run: |
|
||||
timeout 60 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:38081/api/components)" != "200" ]]; do sleep 5; done' || false
|
||||
timeout 60 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:37081/api/components)" != "200" ]]; do sleep 5; done' || false
|
||||
|
||||
- name: Run api e2e tests
|
||||
run: make e2e-api-test
|
||||
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
|
||||
- name: Wait for e2e preparation ready
|
||||
run: |
|
||||
timeout 60 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:38081/api/components)" != "200" ]]; do sleep 5; done' || false
|
||||
timeout 60 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:37081/api/components)" != "200" ]]; do sleep 5; done' || false
|
||||
|
||||
- name: Run api e2e tests
|
||||
run: make e2e-api-test
|
||||
|
||||
@@ -95,8 +95,8 @@ compress:
|
||||
)
|
||||
|
||||
# Run against the configured Kubernetes cluster in ~/.kube/config
|
||||
run: fmt vet
|
||||
go run ./cmd/core/main.go
|
||||
run:
|
||||
go run ./cmd/core/main.go --application-revision-limit 5
|
||||
|
||||
# Run go fmt against code
|
||||
fmt: goimports installcue
|
||||
@@ -316,5 +316,5 @@ endif
|
||||
check-license-header:
|
||||
./hack/licence/header-check.sh
|
||||
|
||||
check-install-def:
|
||||
def-install:
|
||||
./hack/utils/installdefinition.sh
|
||||
|
||||
@@ -163,18 +163,38 @@ type ApplicationPhase string
|
||||
const (
|
||||
// ApplicationRollingOut means the app is in the middle of rolling out
|
||||
ApplicationRollingOut ApplicationPhase = "rollingOut"
|
||||
// ApplicationStarting means the app is preparing for reconcile
|
||||
ApplicationStarting ApplicationPhase = "starting"
|
||||
// ApplicationRendering means the app is rendering
|
||||
ApplicationRendering ApplicationPhase = "rendering"
|
||||
// ApplicationPolicyGenerating means the app is generating policies
|
||||
ApplicationPolicyGenerating ApplicationPhase = "generatingPolicy"
|
||||
// ApplicationRunningWorkflow means the app is running workflow
|
||||
ApplicationRunningWorkflow ApplicationPhase = "runningWorkflow"
|
||||
// ApplicationWorkflowSuspending means the app's workflow is suspending
|
||||
ApplicationWorkflowSuspending ApplicationPhase = "workflowSuspending"
|
||||
// ApplicationWorkflowTerminated means the app's workflow is terminated
|
||||
ApplicationWorkflowTerminated ApplicationPhase = "workflowTerminated"
|
||||
// ApplicationWorkflowFinished means the app's workflow is finished
|
||||
ApplicationWorkflowFinished ApplicationPhase = "workflowFinished"
|
||||
// ApplicationRunning means the app finished rendering and applied result to the cluster
|
||||
ApplicationRunning ApplicationPhase = "running"
|
||||
// ApplicationHealthChecking means the app finished rendering and applied result to the cluster, but still unhealthy
|
||||
ApplicationHealthChecking ApplicationPhase = "healthChecking"
|
||||
// ApplicationUnhealthy means the app finished rendering and applied result to the cluster, but still unhealthy
|
||||
ApplicationUnhealthy ApplicationPhase = "unhealthy"
|
||||
)
|
||||
|
||||
// WorkflowState is a string that mark the workflow state
|
||||
type WorkflowState string
|
||||
|
||||
const (
|
||||
// WorkflowStateTerminated means workflow is terminated manually, and it won't be started unless the spec changed.
|
||||
WorkflowStateTerminated WorkflowState = "terminated"
|
||||
// WorkflowStateSuspended means workflow is suspended manually, and it can be resumed.
|
||||
WorkflowStateSuspended WorkflowState = "suspended"
|
||||
// WorkflowStateFinished means workflow is running successfully, all steps finished.
|
||||
WorkflowStateFinished WorkflowState = "finished"
|
||||
// WorkflowStateExecuting means workflow is still running or waiting some steps.
|
||||
WorkflowStateExecuting WorkflowState = "executing"
|
||||
)
|
||||
|
||||
// ApplicationComponentStatus record the health status of App component
|
||||
@@ -272,11 +292,13 @@ type AppStatus struct {
|
||||
|
||||
// WorkflowStatus record the status of workflow
|
||||
type WorkflowStatus struct {
|
||||
AppRevision string `json:"appRevision,omitempty"`
|
||||
Mode WorkflowMode `json:"mode"`
|
||||
Suspend bool `json:"suspend"`
|
||||
Terminated bool `json:"terminated"`
|
||||
ContextBackend *corev1.ObjectReference `json:"contextBackend"`
|
||||
AppRevision string `json:"appRevision,omitempty"`
|
||||
Mode WorkflowMode `json:"mode"`
|
||||
|
||||
Suspend bool `json:"suspend"`
|
||||
Terminated bool `json:"terminated"`
|
||||
|
||||
ContextBackend *corev1.ObjectReference `json:"contextBackend,omitempty"`
|
||||
Steps []WorkflowStepStatus `json:"steps,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
+8
-7
@@ -38,13 +38,14 @@ const (
|
||||
|
||||
// event message for Application
|
||||
const (
|
||||
MessageParsed = "Parsed successfully"
|
||||
MessageRendered = "Rendered successfully"
|
||||
MessageRevisioned = "Revisioned successfully"
|
||||
MessageApplied = "Applied successfully"
|
||||
MessageHealthCheck = "Health checked healthy"
|
||||
MessageDeployed = "Deployed successfully"
|
||||
MessageRollout = "Rollout successfully"
|
||||
MessageParsed = "Parsed successfully"
|
||||
MessageRendered = "Rendered successfully"
|
||||
MessageRevisioned = "Revisioned successfully"
|
||||
MessageApplied = "Applied successfully"
|
||||
MessageWorkflowFinished = "Workflow finished"
|
||||
MessageHealthCheck = "Health checked healthy"
|
||||
MessageDeployed = "Deployed successfully"
|
||||
MessageRollout = "Rollout successfully"
|
||||
|
||||
MessageFailedParse = "fail to parse application, err: %v"
|
||||
MessageFailedRender = "fail to render application, err: %v"
|
||||
|
||||
@@ -1041,7 +1041,6 @@ spec:
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
- contextBackend
|
||||
- mode
|
||||
- suspend
|
||||
- terminated
|
||||
@@ -3115,7 +3114,6 @@ spec:
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
- contextBackend
|
||||
- mode
|
||||
- suspend
|
||||
- terminated
|
||||
|
||||
@@ -709,7 +709,6 @@ spec:
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
- contextBackend
|
||||
- mode
|
||||
- suspend
|
||||
- terminated
|
||||
@@ -1493,7 +1492,6 @@ spec:
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
- contextBackend
|
||||
- mode
|
||||
- suspend
|
||||
- terminated
|
||||
|
||||
@@ -1152,7 +1152,6 @@ spec:
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
- contextBackend
|
||||
- mode
|
||||
- suspend
|
||||
- terminated
|
||||
|
||||
@@ -41,9 +41,9 @@ spec:
|
||||
|
||||
echo "Waiting application is ready..."
|
||||
|
||||
echo "waiting for application being Applied"
|
||||
kubectl -n vela-system wait --for=condition=Applied applications.core.oam.dev helm-test-vela-app --timeout=3m
|
||||
echo "application being Applied"
|
||||
echo "waiting for application being Ready"
|
||||
kubectl -n vela-system wait --for=condition=Ready applications.core.oam.dev helm-test-vela-app --timeout=3m
|
||||
echo "application is Ready"
|
||||
|
||||
# wait for deploy being created
|
||||
echo "waiting for deployment being available"
|
||||
|
||||
@@ -82,7 +82,7 @@ make core-install
|
||||
To ensure you have created vela-system namespace and install definitions of necessary module.
|
||||
you can run the command:
|
||||
```shell script
|
||||
make check-install-def
|
||||
make def-install
|
||||
```
|
||||
|
||||
And then run locally:
|
||||
|
||||
@@ -122,6 +122,7 @@ var _ = BeforeSuite(func(done Done) {
|
||||
|
||||
var _ = AfterSuite(func() {
|
||||
By("delete application and definitions")
|
||||
|
||||
Expect(k8sClient.Delete(ctx, &app)).Should(BeNil())
|
||||
Expect(k8sClient.Delete(ctx, &testCdDef)).Should(BeNil())
|
||||
Expect(k8sClient.Delete(ctx, &testCdDefWithHelm)).Should(BeNil())
|
||||
@@ -131,4 +132,8 @@ var _ = AfterSuite(func() {
|
||||
Expect(k8sClient.Delete(ctx, &testTdDefWithKube)).Should(BeNil())
|
||||
Expect(k8sClient.Delete(ctx, &testShowCdDef)).Should(BeNil())
|
||||
Expect(k8sClient.Delete(ctx, &testShowTdDef)).Should(BeNil())
|
||||
|
||||
_ = os.RemoveAll("definitions/")
|
||||
_ = os.Remove("dry-run-app.yaml")
|
||||
_ = os.Remove("live-diff-app.yaml")
|
||||
})
|
||||
|
||||
+42
-14
@@ -35,7 +35,7 @@ var _ = Describe("Test Kubectl Plugin", func() {
|
||||
componentDefName := "test-webservice"
|
||||
traitDefName := "test-ingress"
|
||||
|
||||
PContext("Test kubectl vela dry-run", func() {
|
||||
Context("Test kubectl vela dry-run", func() {
|
||||
It("Test dry-run application use definitions which applied to the cluster", func() {
|
||||
By("check definitions which application used whether applied to the cluster")
|
||||
var cd v1beta1.ComponentDefinition
|
||||
@@ -65,7 +65,7 @@ var _ = Describe("Test Kubectl Plugin", func() {
|
||||
})
|
||||
})
|
||||
|
||||
PContext("Test kubectl vela live-diff", func() {
|
||||
Context("Test kubectl vela live-diff", func() {
|
||||
applicationName := "test-vela-app"
|
||||
|
||||
It("Test live-diff application use definition which applied to the cluster", func() {
|
||||
@@ -90,6 +90,12 @@ var _ = Describe("Test Kubectl Plugin", func() {
|
||||
return err
|
||||
}, 5*time.Second).Should(BeNil())
|
||||
|
||||
Eventually(func() bool {
|
||||
var tempApp v1beta1.Application
|
||||
_ = k8sClient.Get(ctx, client.ObjectKey{Namespace: "default", Name: app.Name}, &tempApp)
|
||||
return tempApp.Status.LatestRevision != nil
|
||||
}, 20*time.Second).Should(BeTrue())
|
||||
|
||||
By("live-diff application")
|
||||
err := os.WriteFile("live-diff-app.yaml", []byte(newApplication), 0644)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@@ -99,13 +105,19 @@ var _ = Describe("Test Kubectl Plugin", func() {
|
||||
})
|
||||
|
||||
It("Test dry-run application use definitions in local", func() {
|
||||
Eventually(func() bool {
|
||||
var tempApp v1beta1.Application
|
||||
_ = k8sClient.Get(ctx, client.ObjectKey{Namespace: "default", Name: app.Name}, &tempApp)
|
||||
return tempApp.Status.LatestRevision != nil
|
||||
}, 20*time.Second).Should(BeTrue())
|
||||
|
||||
output, err := e2e.Exec("kubectl-vela live-diff -f live-diff-app.yaml -d definitions")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).Should(ContainSubstring(livediffResult))
|
||||
})
|
||||
})
|
||||
|
||||
PContext("Test kubectl vela show", func() {
|
||||
Context("Test kubectl vela show", func() {
|
||||
It("Test show componentDefinition reference", func() {
|
||||
cdName := "test-show-task"
|
||||
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s", cdName))
|
||||
@@ -161,7 +173,7 @@ var _ = Describe("Test Kubectl Plugin", func() {
|
||||
})
|
||||
})
|
||||
|
||||
PContext("Test kubectl vela comp discover", func() {
|
||||
Context("Test kubectl vela comp discover", func() {
|
||||
It("Test list components in local registry", func() {
|
||||
output, err := e2e.Exec("kubectl-vela comp --discover --url=" + testRegistryPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@@ -169,7 +181,7 @@ var _ = Describe("Test Kubectl Plugin", func() {
|
||||
Expect(output).Should(ContainSubstring("fake-workload"))
|
||||
})
|
||||
})
|
||||
PContext("Test kubectl vela trait discover", func() {
|
||||
Context("Test kubectl vela trait discover", func() {
|
||||
It("Test list traits in local registry", func() {
|
||||
output, err := e2e.Exec("kubectl-vela trait --discover --url=" + testRegistryPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@@ -177,7 +189,7 @@ var _ = Describe("Test Kubectl Plugin", func() {
|
||||
Expect(output).Should(ContainSubstring("dynamic-sa"))
|
||||
})
|
||||
})
|
||||
PContext("Test kubectl vela comp and trait install", func() {
|
||||
Context("Test kubectl vela comp and trait install", func() {
|
||||
It("Test install a sample component", func() {
|
||||
output, err := e2e.Exec("kubectl-vela comp get cloneset --url=" + testRegistryPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@@ -189,7 +201,7 @@ var _ = Describe("Test Kubectl Plugin", func() {
|
||||
Expect(output).Should(ContainSubstring("Successfully install trait: init-container"))
|
||||
})
|
||||
})
|
||||
PContext("Test kubectl vela list installed comp and trait", func() {
|
||||
Context("Test kubectl vela list installed comp and trait", func() {
|
||||
It("Test list installed component", func() {
|
||||
output, err := e2e.Exec("kubectl-vela comp --url=" + testRegistryPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@@ -201,7 +213,7 @@ var _ = Describe("Test Kubectl Plugin", func() {
|
||||
Expect(output).Should(ContainSubstring("init-container"))
|
||||
})
|
||||
})
|
||||
PContext("Test uninstall vela trait", func() {
|
||||
Context("Test uninstall vela trait", func() {
|
||||
It("Clean the sample component", func() {
|
||||
cmd := exec.Command("kubectl", "delete", "componentDefinition", "cloneset", "-n", "vela-system")
|
||||
output, err := cmd.Output()
|
||||
@@ -696,10 +708,12 @@ var dryRunResult = `---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
app.oam.dev/appRevision: ""
|
||||
app.oam.dev/component: express-server
|
||||
app.oam.dev/name: test-vela-app
|
||||
app.oam.dev/resourceType: WORKLOAD
|
||||
workload.oam.dev/type: test-webservice
|
||||
name: express-server
|
||||
namespace: default
|
||||
@@ -722,10 +736,12 @@ spec:
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
app.oam.dev/appRevision: ""
|
||||
app.oam.dev/component: express-server
|
||||
app.oam.dev/name: test-vela-app
|
||||
app.oam.dev/resourceType: TRAIT
|
||||
trait.oam.dev/resource: service
|
||||
trait.oam.dev/type: test-ingress
|
||||
name: express-server
|
||||
@@ -741,10 +757,12 @@ spec:
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
app.oam.dev/appRevision: ""
|
||||
app.oam.dev/component: express-server
|
||||
app.oam.dev/name: test-vela-app
|
||||
app.oam.dev/resourceType: TRAIT
|
||||
trait.oam.dev/resource: ingress
|
||||
trait.oam.dev/type: test-ingress
|
||||
name: express-server
|
||||
@@ -760,8 +778,6 @@ spec:
|
||||
path: /
|
||||
|
||||
---
|
||||
|
||||
|
||||
`
|
||||
|
||||
var livediffResult = `---
|
||||
@@ -770,8 +786,6 @@ var livediffResult = `---
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
- annotations:
|
||||
- oam.dev/kubevela-version: UNKNOWN
|
||||
creationTimestamp: null
|
||||
- finalizers:
|
||||
- - app.oam.dev/resource-tracker-finalizer
|
||||
@@ -810,11 +824,15 @@ var livediffResult = `---
|
||||
- apiVersion: apps/v1
|
||||
- kind: Deployment
|
||||
- metadata:
|
||||
- annotations: {}
|
||||
- labels:
|
||||
- app.oam.dev/appRevision: ""
|
||||
- app.oam.dev/component: express-server
|
||||
- app.oam.dev/name: test-vela-app
|
||||
- app.oam.dev/resourceType: WORKLOAD
|
||||
- workload.oam.dev/type: test-webservice
|
||||
- name: express-server
|
||||
- namespace: default
|
||||
- spec:
|
||||
- selector:
|
||||
- matchLabels:
|
||||
@@ -836,13 +854,16 @@ var livediffResult = `---
|
||||
- apiVersion: v1
|
||||
- kind: Service
|
||||
- metadata:
|
||||
- annotations: {}
|
||||
- labels:
|
||||
- app.oam.dev/appRevision: ""
|
||||
- app.oam.dev/component: express-server
|
||||
- app.oam.dev/name: test-vela-app
|
||||
- app.oam.dev/resourceType: TRAIT
|
||||
- trait.oam.dev/resource: service
|
||||
- trait.oam.dev/type: test-ingress
|
||||
- name: express-server
|
||||
- namespace: default
|
||||
- spec:
|
||||
- ports:
|
||||
- - port: 80
|
||||
@@ -856,13 +877,16 @@ var livediffResult = `---
|
||||
- apiVersion: networking.k8s.io/v1beta1
|
||||
- kind: Ingress
|
||||
- metadata:
|
||||
- annotations: {}
|
||||
- labels:
|
||||
- app.oam.dev/appRevision: ""
|
||||
- app.oam.dev/component: express-server
|
||||
- app.oam.dev/name: test-vela-app
|
||||
- app.oam.dev/resourceType: TRAIT
|
||||
- trait.oam.dev/resource: ingress
|
||||
- trait.oam.dev/type: test-ingress
|
||||
- name: express-server
|
||||
- namespace: default
|
||||
- spec:
|
||||
- rules:
|
||||
- - host: testsvc.example.com
|
||||
@@ -879,10 +903,12 @@ var livediffResult = `---
|
||||
+ apiVersion: apps/v1
|
||||
+ kind: Deployment
|
||||
+ metadata:
|
||||
+ annotations: {}
|
||||
+ labels:
|
||||
+ app.oam.dev/appRevision: ""
|
||||
+ app.oam.dev/component: new-express-server
|
||||
+ app.oam.dev/name: test-vela-app
|
||||
+ app.oam.dev/resourceType: WORKLOAD
|
||||
+ workload.oam.dev/type: test-webservice
|
||||
+ name: new-express-server
|
||||
+ namespace: default
|
||||
@@ -912,10 +938,12 @@ var livediffResult = `---
|
||||
+ apiVersion: v1
|
||||
+ kind: Service
|
||||
+ metadata:
|
||||
+ annotations: {}
|
||||
+ labels:
|
||||
+ app.oam.dev/appRevision: ""
|
||||
+ app.oam.dev/component: new-express-server
|
||||
+ app.oam.dev/name: test-vela-app
|
||||
+ app.oam.dev/resourceType: TRAIT
|
||||
+ trait.oam.dev/resource: service
|
||||
+ trait.oam.dev/type: test-ingress
|
||||
+ name: new-express-server
|
||||
@@ -933,10 +961,12 @@ var livediffResult = `---
|
||||
+ apiVersion: networking.k8s.io/v1beta1
|
||||
+ kind: Ingress
|
||||
+ metadata:
|
||||
+ annotations: {}
|
||||
+ labels:
|
||||
+ app.oam.dev/appRevision: ""
|
||||
+ app.oam.dev/component: new-express-server
|
||||
+ app.oam.dev/name: test-vela-app
|
||||
+ app.oam.dev/resourceType: TRAIT
|
||||
+ trait.oam.dev/resource: ingress
|
||||
+ trait.oam.dev/type: test-ingress
|
||||
+ name: new-express-server
|
||||
@@ -950,8 +980,6 @@ var livediffResult = `---
|
||||
+ serviceName: new-express-server
|
||||
+ servicePort: 8080
|
||||
+ path: /
|
||||
|
||||
|
||||
`
|
||||
|
||||
var testShowComponentDef = `
|
||||
|
||||
@@ -21,6 +21,12 @@ function check_install() {
|
||||
rm $file
|
||||
mv $file".bak" $file
|
||||
done
|
||||
|
||||
cd -
|
||||
}
|
||||
|
||||
check_install
|
||||
|
||||
DEF_PATH="charts/vela-core/templates/definitions"
|
||||
|
||||
check_install
|
||||
@@ -1041,7 +1041,6 @@ spec:
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
- contextBackend
|
||||
- mode
|
||||
- suspend
|
||||
- terminated
|
||||
@@ -3115,7 +3114,6 @@ spec:
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
- contextBackend
|
||||
- mode
|
||||
- suspend
|
||||
- terminated
|
||||
|
||||
@@ -954,7 +954,6 @@ spec:
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
- contextBackend
|
||||
- mode
|
||||
- suspend
|
||||
- terminated
|
||||
@@ -2003,7 +2002,6 @@ spec:
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
- contextBackend
|
||||
- mode
|
||||
- suspend
|
||||
- terminated
|
||||
|
||||
@@ -1152,7 +1152,6 @@ spec:
|
||||
terminated:
|
||||
type: boolean
|
||||
required:
|
||||
- contextBackend
|
||||
- mode
|
||||
- suspend
|
||||
- terminated
|
||||
|
||||
@@ -353,9 +353,9 @@ func (af *Appfile) assembleWorkload(wl *unstructured.Unstructured, compName stri
|
||||
// use component name as workload name
|
||||
// override the name set in render phase if exist
|
||||
wl.SetName(compName)
|
||||
af.setNamespace(wl)
|
||||
af.setWorkloadLabels(wl, labels)
|
||||
af.filterAndSetAnnotations(wl)
|
||||
af.setNamespace(wl)
|
||||
}
|
||||
|
||||
/* NOTE a workload has these possible labels
|
||||
@@ -785,6 +785,7 @@ func generateComponentFromHelmModule(wl *Workload, appName, revision, ns string)
|
||||
ExternalRevision: wl.ExternalRevision,
|
||||
StandardWorkload: &unstructured.Unstructured{},
|
||||
}
|
||||
|
||||
if wl.FullTemplate.Reference.Type != types.AutoDetectWorkloadDefinition {
|
||||
compManifest, err = generateComponentFromCUEModule(wl, appName, revision, ns)
|
||||
if err != nil {
|
||||
|
||||
@@ -36,6 +36,11 @@ var (
|
||||
DefaultIntervalDuration = &metav1.Duration{Duration: 5 * time.Minute}
|
||||
)
|
||||
|
||||
// ConstructHelmReleaseName will format helm release name in a fixed way
|
||||
func ConstructHelmReleaseName(appName, compName string) string {
|
||||
return appName + "-" + compName
|
||||
}
|
||||
|
||||
// RenderHelmReleaseAndHelmRepo constructs HelmRelease and HelmRepository in unstructured format
|
||||
func RenderHelmReleaseAndHelmRepo(helmSpec *common.Helm, compName, appName, ns string, values map[string]interface{}) (*unstructured.Unstructured, *unstructured.Unstructured, error) {
|
||||
releaseSpec, repoSpec, err := decodeHelmSpec(helmSpec)
|
||||
@@ -57,7 +62,7 @@ func RenderHelmReleaseAndHelmRepo(helmSpec *common.Helm, compName, appName, ns s
|
||||
}
|
||||
|
||||
// construct unstructured HelmRelease object
|
||||
rlsName := fmt.Sprintf("%s-%s", appName, compName)
|
||||
rlsName := ConstructHelmReleaseName(appName, compName)
|
||||
helmRelease := commonutil.GenerateUnstructuredObj(rlsName, ns, helmapi.HelmReleaseGVK)
|
||||
|
||||
// construct HelmRelease chart values
|
||||
|
||||
@@ -260,7 +260,7 @@ func (p *Parser) makeWorkload(ctx context.Context, name, typ string, capType typ
|
||||
}
|
||||
|
||||
func (p *Parser) makeWorkloadFromRevision(name, typ string, capType types.CapType, props runtime.RawExtension, appRev *v1beta1.ApplicationRevision) (*Workload, error) {
|
||||
templ, err := LoadTemplateFromRevision(typ, capType, appRev)
|
||||
templ, err := LoadTemplateFromRevision(typ, capType, appRev, p.dm)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "fetch component/policy type of %s from revision", name)
|
||||
}
|
||||
@@ -373,7 +373,7 @@ func (p *Parser) parseTrait(ctx context.Context, name string, properties map[str
|
||||
}
|
||||
|
||||
func (p *Parser) parseTraitFromRevision(name string, properties map[string]interface{}, appRev *v1beta1.ApplicationRevision) (*Trait, error) {
|
||||
templ, err := LoadTemplateFromRevision(name, types.TypeTrait, appRev)
|
||||
templ, err := LoadTemplateFromRevision(name, types.TypeTrait, appRev, p.dm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+14
-1
@@ -149,7 +149,7 @@ func LoadTemplate(ctx context.Context, dm discoverymapper.DiscoveryMapper, cli c
|
||||
}
|
||||
|
||||
// LoadTemplateFromRevision will load Definition template from app revision
|
||||
func LoadTemplateFromRevision(capName string, capType types.CapType, apprev *v1beta1.ApplicationRevision) (*Template, error) {
|
||||
func LoadTemplateFromRevision(capName string, capType types.CapType, apprev *v1beta1.ApplicationRevision, dm discoverymapper.DiscoveryMapper) (*Template, error) {
|
||||
if apprev == nil {
|
||||
return nil, errors.Errorf("fail to find template for %s as app revision is empty", capName)
|
||||
}
|
||||
@@ -165,6 +165,19 @@ func LoadTemplateFromRevision(capName string, capType types.CapType, apprev *v1b
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gvk, err := oamutil.GetGVKFromDefinition(dm, wd.Spec.Reference)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "Get GVK from workload definition [%s]", capName)
|
||||
}
|
||||
tmpl.Reference = common.WorkloadTypeDescriptor{
|
||||
Definition: common.WorkloadGVK{
|
||||
APIVersion: metav1.GroupVersion{
|
||||
Group: gvk.Group,
|
||||
Version: gvk.Version,
|
||||
}.String(),
|
||||
Kind: gvk.Kind,
|
||||
},
|
||||
}
|
||||
return tmpl, nil
|
||||
}
|
||||
tmpl, err := newTemplateOfCompDefinition(cd.DeepCopy())
|
||||
|
||||
@@ -21,12 +21,13 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
"github.com/crossplane/crossplane-runtime/pkg/meta"
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/klog/v2"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
@@ -109,20 +110,17 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
}
|
||||
endReconcile, err := r.handleFinalizers(ctx, app)
|
||||
if err != nil {
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err), common.ApplicationStarting)
|
||||
}
|
||||
if endReconcile {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// parse application to appfile
|
||||
app.Status.Phase = common.ApplicationRendering
|
||||
|
||||
appFile, err := appParser.GenerateAppFile(ctx, app)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Failed to parse application", "application", klog.KObj(app))
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedParse, err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Parsed", err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Parsed", err), common.ApplicationRendering)
|
||||
}
|
||||
app.Status.SetConditions(condition.ReadyCondition("Parsed"))
|
||||
r.Recorder.Event(app, event.Normal(velatypes.ReasonParsed, velatypes.MessageParsed))
|
||||
@@ -130,103 +128,92 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err := handler.PrepareCurrentAppRevision(ctx, appFile); err != nil {
|
||||
klog.ErrorS(err, "Failed to prepare app revision", "application", klog.KObj(app))
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedRevision, err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Revision", err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Revision", err), common.ApplicationRendering)
|
||||
}
|
||||
if err := handler.FinalizeAndApplyAppRevision(ctx); err != nil {
|
||||
klog.ErrorS(err, "Failed to apply app revision", "application", klog.KObj(app))
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedRevision, err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Revision", err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Revision", err), common.ApplicationRendering)
|
||||
}
|
||||
|
||||
klog.Info("Successfully prepare current app revision", "revisionName", handler.currentAppRev.Name,
|
||||
"revisionHash", handler.currentRevHash, "isNewRevision", handler.isNewRevision)
|
||||
app.Status.SetConditions(condition.ReadyCondition("Revision"))
|
||||
r.Recorder.Event(app, event.Normal(velatypes.ReasonRevisoned, velatypes.MessageRevisioned))
|
||||
|
||||
if err := handler.UpdateAppLatestRevisionStatus(ctx); err != nil {
|
||||
klog.ErrorS(err, "Failed to update application status", "application", klog.KObj(app))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err), common.ApplicationRendering)
|
||||
}
|
||||
klog.Info("Successfully apply application revision", "application", klog.KObj(app))
|
||||
|
||||
policies, err := appFile.PrepareWorkflowAndPolicy()
|
||||
if err != nil {
|
||||
klog.Error(err, "[Handle PrepareWorkflowAndPolicy]")
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedRender, err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("PrepareWorkflowAndPolicy", err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("PrepareWorkflowAndPolicy", err), common.ApplicationPolicyGenerating)
|
||||
}
|
||||
|
||||
if len(policies) > 0 {
|
||||
if err := handler.Dispatch(ctx, "", common.PolicyResourceCreator, policies...); err != nil {
|
||||
klog.Error(err, "[Handle ApplyPolicyResources]")
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedApply, err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("ApplyPolices", err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("ApplyPolices", err), common.ApplicationPolicyGenerating)
|
||||
}
|
||||
klog.InfoS("Successfully generated application policies", "application", klog.KObj(app))
|
||||
}
|
||||
|
||||
app.Status.SetConditions(condition.ReadyCondition("Render"))
|
||||
r.Recorder.Event(app, event.Normal(velatypes.ReasonRendered, velatypes.MessageRendered))
|
||||
klog.InfoS("Successfully render application resources", "application", klog.KObj(app))
|
||||
|
||||
if !appWillRollout(app) {
|
||||
steps, err := handler.GenerateApplicationSteps(ctx, app, appParser, appFile, handler.currentAppRev, r.Client, r.dm, r.pd)
|
||||
if err != nil {
|
||||
klog.Error(err, "[handle workflow]")
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedWorkflow, err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Workflow", err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Workflow", err), common.ApplicationRunningWorkflow)
|
||||
}
|
||||
|
||||
done, pause, err := workflow.NewWorkflow(app, r.Client, appFile.WorkflowMode).ExecuteSteps(ctx, handler.currentAppRev, steps)
|
||||
workflowState, err := workflow.NewWorkflow(app, r.Client, appFile.WorkflowMode).ExecuteSteps(ctx, handler.currentAppRev, steps)
|
||||
if err != nil {
|
||||
klog.Error(err, "[handle workflow]")
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedWorkflow, err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Workflow", err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Workflow", err), common.ApplicationRunningWorkflow)
|
||||
}
|
||||
|
||||
handler.addServiceStatus(false, app.Status.Services...)
|
||||
handler.addAppliedResource(app.Status.AppliedResources...)
|
||||
app.Status.Services = handler.services
|
||||
app.Status.AppliedResources = handler.appliedResources
|
||||
|
||||
if pause {
|
||||
if err := r.patchStatus(ctx, app); err != nil {
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err))
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
if !done {
|
||||
if err := r.patchStatus(ctx, app); err != nil {
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err))
|
||||
}
|
||||
return reconcile.Result{RequeueAfter: WorkflowReconcileWaitTime}, nil
|
||||
}
|
||||
|
||||
wfStatus := app.Status.Workflow
|
||||
if wfStatus != nil {
|
||||
if wfStatus.Terminated && app.Status.Phase == common.ApplicationWorkflowTerminated {
|
||||
if err := r.patchStatus(ctx, app); err != nil {
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err))
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
if !wfStatus.Terminated {
|
||||
_, err := handler.DispatchAndGC(ctx)
|
||||
switch workflowState {
|
||||
case common.WorkflowStateSuspended:
|
||||
return ctrl.Result{}, r.patchStatus(ctx, app, common.ApplicationWorkflowSuspending)
|
||||
case common.WorkflowStateTerminated:
|
||||
return ctrl.Result{}, r.patchStatus(ctx, app, common.ApplicationWorkflowTerminated)
|
||||
case common.WorkflowStateExecuting:
|
||||
return reconcile.Result{RequeueAfter: WorkflowReconcileWaitTime}, r.patchStatus(ctx, app, common.ApplicationRunningWorkflow)
|
||||
case common.WorkflowStateFinished:
|
||||
wfStatus := app.Status.Workflow
|
||||
if wfStatus != nil {
|
||||
ref, err := handler.DispatchAndGC(ctx)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Failed to gc after workflow",
|
||||
"application", klog.KObj(app))
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedGC, err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("GCAfterWorkflow", err))
|
||||
}
|
||||
wfStatus.Terminated = true
|
||||
if err := r.patchStatus(ctx, app); err != nil {
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("GCAfterWorkflow", err), common.ApplicationRunningWorkflow)
|
||||
}
|
||||
app.Status.ResourceTracker = ref
|
||||
}
|
||||
}
|
||||
app.Status.SetConditions(condition.ReadyCondition("WorkflowFinished"))
|
||||
r.Recorder.Event(app, event.Normal(velatypes.ReasonApplied, velatypes.MessageWorkflowFinished))
|
||||
klog.Info("Application manifests has applied by workflow successfully", "application", klog.KObj(app))
|
||||
} else {
|
||||
var comps []*velatypes.ComponentManifest
|
||||
comps, err = appFile.GenerateComponentManifests()
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Failed to render components", "application", klog.KObj(app))
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedRender, err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Render", err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Render", err), common.ApplicationRendering)
|
||||
}
|
||||
|
||||
handler.handleCheckManageWorkloadTrait(handler.currentAppRev.Spec.TraitDefinitions, comps)
|
||||
@@ -234,32 +221,23 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err := handler.HandleComponentsRevision(ctx, comps); err != nil {
|
||||
klog.ErrorS(err, "Failed to handle compoents revision", "application", klog.KObj(app))
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedRevision, err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Render", err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Render", err), common.ApplicationRendering)
|
||||
}
|
||||
klog.Info("Application manifests has prepared and ready for appRollout to handle", "application", klog.KObj(app))
|
||||
}
|
||||
|
||||
if err := handler.UpdateAppLatestRevisionStatus(ctx); err != nil {
|
||||
klog.ErrorS(err, "Failed to update application status", "application", klog.KObj(app))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err))
|
||||
}
|
||||
app.Status.SetConditions(condition.ReadyCondition("Applied"))
|
||||
r.Recorder.Event(app, event.Normal(velatypes.ReasonApplied, velatypes.MessageApplied))
|
||||
klog.Info("Successfully apply application manifests", "application", klog.KObj(app))
|
||||
|
||||
// if inplace is false and rolloutPlan is nil, it means the user will use an outer AppRollout object to rollout the application
|
||||
if handler.app.Spec.RolloutPlan != nil {
|
||||
res, err := handler.handleRollout(ctx)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Failed to handle rollout", "application", klog.KObj(app))
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedRollout, err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Rollout", err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("Rollout", err), common.ApplicationRollingOut)
|
||||
}
|
||||
// skip health check and garbage collection if rollout have not finished
|
||||
// start next reconcile immediately
|
||||
if res.Requeue || res.RequeueAfter > 0 {
|
||||
app.Status.Phase = common.ApplicationRollingOut
|
||||
if err := r.patchStatus(ctx, app); err != nil {
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err))
|
||||
if err := r.patchStatus(ctx, app, common.ApplicationRollingOut); err != nil {
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err), common.ApplicationRollingOut)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
@@ -267,45 +245,29 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
// there is no need reconcile immediately, that means the rollout operation have finished
|
||||
r.Recorder.Event(app, event.Normal(velatypes.ReasonRollout, velatypes.MessageRollout))
|
||||
app.Status.SetConditions(condition.ReadyCondition("Rollout"))
|
||||
klog.Info("Finished rollout ")
|
||||
klog.InfoS("Finished rollout ", "application", klog.KObj(app))
|
||||
}
|
||||
|
||||
var phase = common.ApplicationRunning
|
||||
if !hasHealthCheckPolicy(appFile.Policies) {
|
||||
app.Status.Phase = common.ApplicationHealthChecking
|
||||
if !isHealthy(handler.services) {
|
||||
app.Status.SetConditions(condition.Condition{
|
||||
Type: v1beta1.TypeHealthy,
|
||||
Status: corev1.ConditionFalse,
|
||||
LastTransitionTime: metav1.Now(),
|
||||
Reason: v1beta1.ReasonUnhealthy,
|
||||
})
|
||||
if err := r.patchStatus(ctx, app); err != nil {
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err))
|
||||
}
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ErrorCondition("HealthCheck", errors.New("not healthy")))
|
||||
phase = common.ApplicationUnhealthy
|
||||
}
|
||||
app.Status.SetConditions(condition.Condition{
|
||||
Type: v1beta1.TypeHealthy,
|
||||
Status: corev1.ConditionTrue,
|
||||
LastTransitionTime: metav1.Now(),
|
||||
Reason: v1beta1.ReasonHealthy,
|
||||
})
|
||||
r.Recorder.Event(app, event.Normal(velatypes.ReasonHealthCheck, velatypes.MessageHealthCheck))
|
||||
}
|
||||
|
||||
app.Status.Phase = common.ApplicationRunning
|
||||
if err := garbageCollection(ctx, handler); err != nil {
|
||||
klog.ErrorS(err, "Failed to run garbage collection")
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedGC, err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err))
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err), phase)
|
||||
}
|
||||
klog.Info("Successfully garbage collect", "application", klog.KObj(app))
|
||||
|
||||
app.Status.SetConditions(condition.Condition{
|
||||
Type: condition.TypeReady,
|
||||
Status: corev1.ConditionTrue,
|
||||
LastTransitionTime: metav1.Now(),
|
||||
Reason: condition.ReasonReconcileSuccess,
|
||||
})
|
||||
r.Recorder.Event(app, event.Normal(velatypes.ReasonDeployed, velatypes.MessageDeployed))
|
||||
if err := r.patchStatus(ctx, app); err != nil {
|
||||
return r.endWithNegativeCondition(ctx, app, condition.ReconcileError(err))
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
return ctrl.Result{}, r.patchStatus(ctx, app, phase)
|
||||
}
|
||||
|
||||
// NOTE Because resource tracker is cluster-scoped resources, we cannot garbage collect them
|
||||
@@ -358,15 +320,16 @@ func (r *Reconciler) handleFinalizers(ctx context.Context, app *v1beta1.Applicat
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (r *Reconciler) endWithNegativeCondition(ctx context.Context, app *v1beta1.Application, condition condition.Condition) (ctrl.Result, error) {
|
||||
func (r *Reconciler) endWithNegativeCondition(ctx context.Context, app *v1beta1.Application, condition condition.Condition, phase common.ApplicationPhase) (ctrl.Result, error) {
|
||||
app.SetConditions(condition)
|
||||
if err := r.patchStatus(ctx, app); err != nil {
|
||||
if err := r.patchStatus(ctx, app, phase); err != nil {
|
||||
return ctrl.Result{}, errors.WithMessage(err, "cannot update application status")
|
||||
}
|
||||
return ctrl.Result{}, fmt.Errorf("object level reconcile error, type: %q, msg: %q", string(condition.Type), condition.Message)
|
||||
}
|
||||
|
||||
func (r *Reconciler) patchStatus(ctx context.Context, app *v1beta1.Application) error {
|
||||
func (r *Reconciler) patchStatus(ctx context.Context, app *v1beta1.Application, phase common.ApplicationPhase) error {
|
||||
app.Status.Phase = phase
|
||||
updateObservedGeneration(app)
|
||||
return r.Client.Status().Patch(ctx, app, client.Merge)
|
||||
}
|
||||
|
||||
@@ -134,7 +134,8 @@ var _ = Describe("Test application controller finalizer logic", func() {
|
||||
checkApp = new(v1beta1.Application)
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
Expect(k8sClient.Get(ctx, getTrackerKey(checkApp.Namespace, checkApp.Name, "v1"), rt)).Should(Succeed())
|
||||
Expect(checkApp.Status.ResourceTracker).Should(BeNil())
|
||||
Expect(checkApp.Status.ResourceTracker).ShouldNot(BeNil())
|
||||
Expect(checkApp.Status.ResourceTracker.Name).Should(BeEquivalentTo("app-1-v1-cross-namespace"))
|
||||
})
|
||||
|
||||
It("Test error occurs in the middle of dispatching", func() {
|
||||
@@ -148,10 +149,10 @@ var _ = Describe("Test application controller finalizer logic", func() {
|
||||
testutil.ReconcileOnceAfterFinalizer(reconciler, ctrl.Request{NamespacedName: appKey})
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
|
||||
// because error occurs in the middle of dispatching
|
||||
// resource tracker for v1 is created but v1 is not recorded in app status
|
||||
By("Verify latest app revision is not recorded in status")
|
||||
Expect(checkApp.Status.LatestRevision).Should(BeNil())
|
||||
// though error occurs in the middle of dispatching
|
||||
// resource tracker for v1 is also created and recorded in app status
|
||||
By("Verify latest app revision is also recorded in status")
|
||||
Expect(checkApp.Status.LatestRevision).ShouldNot(BeNil())
|
||||
|
||||
By("Verify ResourceTracker is created")
|
||||
rt := &v1beta1.ResourceTracker{}
|
||||
@@ -222,7 +223,7 @@ var _ = Describe("Test application controller finalizer logic", func() {
|
||||
testutil.ReconcileOnceAfterFinalizer(reconciler, ctrl.Request{NamespacedName: appKey})
|
||||
checkApp = new(v1beta1.Application)
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
Expect(checkApp.Status.ResourceTracker).Should(BeNil())
|
||||
Expect(checkApp.Status.ResourceTracker).ShouldNot(BeNil())
|
||||
Expect(k8sClient.Get(ctx, getTrackerKey(checkApp.Namespace, checkApp.Name, "v2"), rt)).Should(Succeed())
|
||||
Expect(k8sClient.Delete(ctx, checkApp)).Should(BeNil())
|
||||
testutil.ReconcileOnceAfterFinalizer(reconciler, ctrl.Request{NamespacedName: appKey})
|
||||
|
||||
@@ -63,6 +63,9 @@ func (h *AppHandler) Dispatch(ctx context.Context, cluster string, owner common.
|
||||
_, err := h.dispatcher.Dispatch(ctx, manifests)
|
||||
if err == nil {
|
||||
for _, mf := range manifests {
|
||||
if mf == nil {
|
||||
continue
|
||||
}
|
||||
ref := common.ClusterObjectReference{
|
||||
Cluster: cluster,
|
||||
Creator: owner,
|
||||
@@ -390,7 +393,7 @@ func (h *AppHandler) handleRollout(ctx context.Context) (reconcile.Result, error
|
||||
}
|
||||
|
||||
// construct a fake rollout object and call rollout.DoReconcile
|
||||
r := applicationrollout.NewReconciler(h.r.Client, h.r.dm, h.r.Recorder, h.r.Scheme)
|
||||
r := applicationrollout.NewReconciler(h.r.Client, h.r.dm, h.r.pd, h.r.Recorder, h.r.Scheme, h.r.concurrentReconciles)
|
||||
res, err := r.DoReconcile(ctx, &appRollout)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
|
||||
@@ -189,34 +189,24 @@ func (am *AppManifests) assemble() {
|
||||
return
|
||||
}
|
||||
for _, comp := range am.componentManifests {
|
||||
if checkAutoDetectComponent(comp.StandardWorkload) {
|
||||
klog.Warningf("component without specify workloadDef can not attach traits currently")
|
||||
continue
|
||||
}
|
||||
compRevisionName := comp.RevisionName
|
||||
compName := comp.Name
|
||||
additionalLabel := map[string]string{
|
||||
oam.LabelAppComponentRevision: compRevisionName,
|
||||
oam.LabelAppRevisionHash: am.AppRevision.Labels[oam.LabelAppRevisionHash],
|
||||
}
|
||||
klog.InfoS("Assemble manifests for component", "name", compName)
|
||||
wl, err := am.assembleWorkload(compName, comp.StandardWorkload, additionalLabel, comp.PackagedWorkloadResources)
|
||||
klog.InfoS("Assemble manifests for component", "name", comp.Name)
|
||||
wl, traits, err := PrepareBeforeApply(comp, am.AppRevision, am.WorkloadOptions)
|
||||
if err != nil {
|
||||
am.finalizeAssemble(err)
|
||||
return
|
||||
}
|
||||
am.assembledWorkloads[compName] = wl
|
||||
if wl == nil {
|
||||
klog.Warningf("component without specify workloadDef can not attach traits currently")
|
||||
continue
|
||||
}
|
||||
|
||||
am.assembledWorkloads[comp.Name] = wl
|
||||
workloadRef := corev1.ObjectReference{
|
||||
APIVersion: wl.GetAPIVersion(),
|
||||
Kind: wl.GetKind(),
|
||||
Name: wl.GetName(),
|
||||
}
|
||||
am.assembledTraits[compName] = make([]*unstructured.Unstructured, len(comp.Traits))
|
||||
for i, trait := range comp.Traits {
|
||||
am.setTraitLabels(trait, additionalLabel)
|
||||
am.assembledTraits[compName][i] = trait
|
||||
}
|
||||
|
||||
am.assembledTraits[comp.Name] = traits
|
||||
am.referencedScopes[workloadRef] = make([]corev1.ObjectReference, len(comp.Scopes))
|
||||
for i, scope := range comp.Scopes {
|
||||
am.referencedScopes[workloadRef][i] = *scope
|
||||
@@ -225,6 +215,31 @@ func (am *AppManifests) assemble() {
|
||||
am.finalizeAssemble(nil)
|
||||
}
|
||||
|
||||
// PrepareBeforeApply will prepare for some necessary info before apply
|
||||
func PrepareBeforeApply(comp *types.ComponentManifest, appRev *v1beta1.ApplicationRevision, workloadOpt []WorkloadOption) (*unstructured.Unstructured, []*unstructured.Unstructured, error) {
|
||||
if checkAutoDetectComponent(comp.StandardWorkload) {
|
||||
return nil, nil, nil
|
||||
}
|
||||
compRevisionName := comp.RevisionName
|
||||
compName := comp.Name
|
||||
additionalLabel := map[string]string{
|
||||
oam.LabelAppComponentRevision: compRevisionName,
|
||||
oam.LabelAppRevisionHash: appRev.Labels[oam.LabelAppRevisionHash],
|
||||
}
|
||||
wl, err := assembleWorkload(compName, comp.StandardWorkload, additionalLabel, comp.PackagedWorkloadResources, appRev, workloadOpt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
assembledTraits := make([]*unstructured.Unstructured, len(comp.Traits))
|
||||
for i, trait := range comp.Traits {
|
||||
setTraitLabels(trait, additionalLabel)
|
||||
assembledTraits[i] = trait
|
||||
}
|
||||
|
||||
return wl, assembledTraits, nil
|
||||
}
|
||||
|
||||
func (am *AppManifests) complete() error {
|
||||
if len(am.componentManifests) == 0 {
|
||||
var err error
|
||||
@@ -275,20 +290,20 @@ func (am *AppManifests) validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (am *AppManifests) assembleWorkload(compName string, wl *unstructured.Unstructured,
|
||||
labels map[string]string, resources []*unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
func assembleWorkload(compName string, wl *unstructured.Unstructured,
|
||||
labels map[string]string, resources []*unstructured.Unstructured, appRev *v1beta1.ApplicationRevision, wop []WorkloadOption) (*unstructured.Unstructured, error) {
|
||||
// use component name as workload name
|
||||
// override the name set in render phase if exist
|
||||
wl.SetName(compName)
|
||||
am.setWorkloadLabels(wl, labels)
|
||||
setWorkloadLabels(wl, labels)
|
||||
|
||||
workloadType := wl.GetLabels()[oam.WorkloadTypeLabel]
|
||||
compDefinition := am.AppRevision.Spec.ComponentDefinitions[workloadType]
|
||||
compDefinition := appRev.Spec.ComponentDefinitions[workloadType]
|
||||
copyPackagedResources := make([]*unstructured.Unstructured, len(resources))
|
||||
for i, v := range resources {
|
||||
copyPackagedResources[i] = v.DeepCopy()
|
||||
}
|
||||
for _, wo := range am.WorkloadOptions {
|
||||
for _, wo := range wop {
|
||||
if err := wo.ApplyToWorkload(wl, compDefinition.DeepCopy(), copyPackagedResources); err != nil {
|
||||
klog.ErrorS(err, "Failed applying a workload option", "workload", klog.KObj(wl), "name", wl.GetName())
|
||||
return nil, errors.Wrapf(err, "cannot apply workload option for component %q", compName)
|
||||
@@ -301,14 +316,14 @@ func (am *AppManifests) assembleWorkload(compName string, wl *unstructured.Unstr
|
||||
|
||||
// component revision label added here
|
||||
// label key: app.oam.dev/revision
|
||||
func (am *AppManifests) setWorkloadLabels(wl *unstructured.Unstructured, additionalLabels map[string]string) {
|
||||
func setWorkloadLabels(wl *unstructured.Unstructured, additionalLabels map[string]string) {
|
||||
// add more workload-specific labels here
|
||||
util.AddLabels(wl, additionalLabels)
|
||||
}
|
||||
|
||||
// component revision label added here
|
||||
// label key: app.oam.dev/revision
|
||||
func (am *AppManifests) setTraitLabels(trait *unstructured.Unstructured, additionalLabels map[string]string) {
|
||||
func setTraitLabels(trait *unstructured.Unstructured, additionalLabels map[string]string) {
|
||||
// add more trait-specific labels here
|
||||
util.AddLabels(trait, additionalLabels)
|
||||
}
|
||||
|
||||
@@ -228,6 +228,9 @@ func (a *AppManifestsDispatcher) applyAndRecordManifests(ctx context.Context, ma
|
||||
BlockOwnerDeletion: pointer.BoolPtr(true),
|
||||
}
|
||||
for _, rsc := range manifests {
|
||||
if rsc == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
immutable, err := a.ImmutableResourcesUpdate(ctx, rsc, ownerRef, applyOpts)
|
||||
if immutable {
|
||||
@@ -284,6 +287,9 @@ func (a *AppManifestsDispatcher) updateResourceTrackerStatus(ctx context.Context
|
||||
a.currentRT.Status.TrackedResources = make([]v1.ObjectReference, 0)
|
||||
}
|
||||
for _, rsc := range appliedManifests {
|
||||
if rsc == nil {
|
||||
continue
|
||||
}
|
||||
appliedRef := v1.ObjectReference{
|
||||
APIVersion: rsc.GetAPIVersion(),
|
||||
Kind: rsc.GetKind(),
|
||||
|
||||
@@ -60,15 +60,15 @@ func (h *GCHandler) GarbageCollect(ctx context.Context, oldRT, newRT *v1beta1.Re
|
||||
}
|
||||
klog.InfoS("Garbage collect for application", "old", h.oldRT.Name, "new", h.newRT.Name)
|
||||
for _, oldRsc := range h.oldRT.Status.TrackedResources {
|
||||
isRemoved := true
|
||||
reused := false
|
||||
for _, newRsc := range h.newRT.Status.TrackedResources {
|
||||
if oldRsc.APIVersion == newRsc.APIVersion && oldRsc.Kind == newRsc.Kind &&
|
||||
oldRsc.Namespace == newRsc.Namespace && oldRsc.Name == newRsc.Name {
|
||||
isRemoved = false
|
||||
reused = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if isRemoved {
|
||||
if !reused {
|
||||
toBeDeleted := &unstructured.Unstructured{}
|
||||
toBeDeleted.SetAPIVersion(oldRsc.APIVersion)
|
||||
toBeDeleted.SetKind(oldRsc.Kind)
|
||||
|
||||
@@ -19,6 +19,8 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1alpha2/application/assemble"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -126,18 +128,27 @@ func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1bet
|
||||
if err := af.SetOAMContract(manifest); err != nil {
|
||||
return nil, nil, false, errors.WithMessage(err, "SetOAMContract")
|
||||
}
|
||||
if err := h.HandleComponentsRevision(context.Background(), []*types.ComponentManifest{manifest}); err != nil {
|
||||
if err := h.HandleComponentsRevision(context.TODO(), []*types.ComponentManifest{manifest}); err != nil {
|
||||
return nil, nil, false, errors.WithMessage(err, "HandleComponentsRevision")
|
||||
}
|
||||
if len(manifest.PackagedWorkloadResources) != 0 {
|
||||
if err := h.Dispatch(context.TODO(), "", common.WorkflowResourceCreator, manifest.PackagedWorkloadResources...); err != nil {
|
||||
return nil, nil, false, errors.WithMessage(err, "cannot dispatch packaged workload resources")
|
||||
}
|
||||
}
|
||||
readyWorkload, readyTraits, err := assemble.PrepareBeforeApply(manifest, appRev, []assemble.WorkloadOption{assemble.DiscoveryHelmBasedWorkload(context.TODO(), h.r.Client)})
|
||||
if err != nil {
|
||||
return nil, nil, false, errors.WithMessage(err, "assemble resources before apply fail")
|
||||
}
|
||||
|
||||
skipStandardWorkload := skipApplyWorkload(wl)
|
||||
if !skipStandardWorkload {
|
||||
if err := h.Dispatch(context.Background(), "", common.WorkflowResourceCreator, manifest.StandardWorkload); err != nil {
|
||||
if err := h.Dispatch(context.TODO(), "", common.WorkflowResourceCreator, readyWorkload); err != nil {
|
||||
return nil, nil, false, errors.WithMessage(err, "DispatchStandardWorkload")
|
||||
}
|
||||
}
|
||||
|
||||
if err := h.Dispatch(context.Background(), "", common.WorkflowResourceCreator, manifest.Traits...); err != nil {
|
||||
if err := h.Dispatch(context.TODO(), "", common.WorkflowResourceCreator, readyTraits...); err != nil {
|
||||
return nil, nil, false, errors.WithMessage(err, "DispatchTraits")
|
||||
}
|
||||
|
||||
|
||||
@@ -689,7 +689,7 @@ func (h *AppHandler) UpdateAppLatestRevisionStatus(ctx context.Context) error {
|
||||
Revision: int64(revNum),
|
||||
RevisionHash: h.currentRevHash,
|
||||
}
|
||||
if err := h.r.patchStatus(ctx, h.app); err != nil {
|
||||
if err := h.r.patchStatus(ctx, h.app, common.ApplicationRendering); err != nil {
|
||||
klog.InfoS("Failed to update the latest appConfig revision to status", "application", klog.KObj(h.app),
|
||||
"latest revision", revName, "err", err)
|
||||
return err
|
||||
@@ -759,6 +759,13 @@ func gatherUsingAppRevision(ctx context.Context, h *AppHandler) (map[string]bool
|
||||
appRev := dispatch.ExtractAppRevisionName(rt.Name, ns)
|
||||
usingRevision[appRev] = true
|
||||
}
|
||||
appRolloutRevision, err := utils.CheckAppRolloutUsingAppRevision(ctx, h.r.Client, h.app.Namespace, h.app.Name)
|
||||
if err != nil {
|
||||
return usingRevision, err
|
||||
}
|
||||
for _, revName := range appRolloutRevision {
|
||||
usingRevision[revName] = true
|
||||
}
|
||||
appDeployUsingRevision, err := utils.CheckAppDeploymentUsingAppRevision(ctx, h.r.Client, h.app.Namespace, h.app.Name)
|
||||
if err != nil {
|
||||
return usingRevision, err
|
||||
|
||||
@@ -70,8 +70,6 @@ var controllerDone context.CancelFunc
|
||||
var mgr ctrl.Manager
|
||||
var appRevisionLimit = 5
|
||||
|
||||
// TODO: create a mock client and add UT to cover all the failure cases
|
||||
|
||||
func TestAPIs(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ var _ = Describe("Test Workflow", func() {
|
||||
}, appObj)).Should(BeNil())
|
||||
|
||||
Expect(appObj.Status.Workflow.Steps[0].Phase).Should(Equal(common.WorkflowStepPhaseSucceeded))
|
||||
Expect(appObj.Status.Workflow.Terminated).Should(BeTrue())
|
||||
Expect(appObj.Status.Phase).Should(BeEquivalentTo(common.ApplicationRunning))
|
||||
})
|
||||
|
||||
It("test workflow suspend", func() {
|
||||
@@ -253,10 +253,16 @@ var _ = Describe("Test Workflow", func() {
|
||||
|
||||
Expect(appObj.Status.Workflow.Suspend).Should(BeTrue())
|
||||
Expect(appObj.Status.Phase).Should(BeEquivalentTo(common.ApplicationWorkflowSuspending))
|
||||
Expect(appObj.Status.Workflow.Steps[0].Phase).Should(BeEquivalentTo(common.WorkflowStepPhaseSucceeded))
|
||||
|
||||
// resume
|
||||
appObj.Status.Workflow.Suspend = false
|
||||
Expect(k8sClient.Status().Patch(ctx, appObj, client.Merge)).Should(BeNil())
|
||||
Expect(k8sClient.Get(ctx, client.ObjectKey{
|
||||
Name: suspendApp.Name,
|
||||
Namespace: suspendApp.Namespace,
|
||||
}, appObj)).Should(BeNil())
|
||||
Expect(appObj.Status.Workflow.Suspend).Should(BeFalse())
|
||||
|
||||
tryReconcile(reconciler, suspendApp.Name, suspendApp.Namespace)
|
||||
tryReconcile(reconciler, suspendApp.Name, suspendApp.Namespace)
|
||||
@@ -268,7 +274,7 @@ var _ = Describe("Test Workflow", func() {
|
||||
}, appObj)).Should(BeNil())
|
||||
|
||||
Expect(appObj.Status.Workflow.Suspend).Should(BeFalse())
|
||||
Expect(appObj.Status.Workflow.Terminated).Should(BeTrue())
|
||||
Expect(appObj.Status.Phase).Should(BeEquivalentTo(common.ApplicationRunning))
|
||||
})
|
||||
|
||||
It("test workflow terminate a suspend workflow", func() {
|
||||
|
||||
+7
-6
@@ -150,7 +150,6 @@ func (r *Reconciler) DoReconcile(ctx context.Context, appRollout *v1beta1.AppRol
|
||||
if len(appRollout.Spec.ComponentList) == 1 {
|
||||
h.needRollComponent = appRollout.Spec.ComponentList[0]
|
||||
}
|
||||
|
||||
// call assemble func generate source and target manifest
|
||||
if err = h.prepareWorkloads(ctx); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
@@ -282,12 +281,14 @@ func (r *Reconciler) updateStatus(ctx context.Context, appRollout *v1beta1.AppRo
|
||||
}
|
||||
|
||||
// NewReconciler render a applicationRollout reconciler
|
||||
func NewReconciler(c client.Client, dm discoverymapper.DiscoveryMapper, record event.Recorder, scheme *runtime.Scheme) *Reconciler {
|
||||
func NewReconciler(c client.Client, dm discoverymapper.DiscoveryMapper, pd *packages.PackageDiscover, record event.Recorder, scheme *runtime.Scheme, concurrent int) *Reconciler {
|
||||
return &Reconciler{
|
||||
Client: c,
|
||||
dm: dm,
|
||||
record: record,
|
||||
Scheme: scheme,
|
||||
Client: c,
|
||||
dm: dm,
|
||||
pd: pd,
|
||||
record: record,
|
||||
Scheme: scheme,
|
||||
concurrentReconciles: concurrent,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-16
@@ -65,17 +65,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
|
||||
var componentDefinition v1beta1.ComponentDefinition
|
||||
if err := r.Get(ctx, req.NamespacedName, &componentDefinition); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
err = nil
|
||||
}
|
||||
klog.InfoS("The ComponentDefinition doesn't exist", "componentDefinition", klog.KRef(req.Namespace, req.Name))
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
// this is a placeholder for finalizer here in the future
|
||||
if componentDefinition.DeletionTimestamp != nil {
|
||||
klog.InfoS("The ComponentDefinition is being deleted", "componentDefinition", klog.KRef(req.Namespace, req.Name))
|
||||
return ctrl.Result{}, nil
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
// refresh package discover when componentDefinition is registered
|
||||
@@ -94,7 +84,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Could not generate DefinitionRevision", "componentDefinition", klog.KObj(&componentDefinition))
|
||||
r.record.Event(&componentDefinition, event.Warning("Could not generate DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &componentDefinition,
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &componentDefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrGenerateDefinitionRevision, componentDefinition.Name, err)))
|
||||
}
|
||||
|
||||
@@ -102,7 +92,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err := r.createComponentDefRevision(ctx, &componentDefinition, defRev.DeepCopy()); err != nil {
|
||||
klog.ErrorS(err, "Could not create DefinitionRevision")
|
||||
r.record.Event(&componentDefinition, event.Warning("cannot create DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &componentDefinition,
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &componentDefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrCreateDefinitionRevision, defRev.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully created definitionRevision", "definitionRevision", klog.KObj(defRev))
|
||||
@@ -116,7 +106,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err := r.UpdateStatus(ctx, &componentDefinition); err != nil {
|
||||
klog.ErrorS(err, "Could not update componentDefinition Status")
|
||||
r.record.Event(&componentDefinition, event.Warning("cannot update ComponentDefinition Status", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &componentDefinition,
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &componentDefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdateComponentDefinition, componentDefinition.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully updated the status.latestRevision of the ComponentDefinition", "componentDefinition", klog.KRef(req.Namespace, req.Name),
|
||||
@@ -134,7 +124,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err != nil {
|
||||
klog.InfoS("Could not capability in ConfigMap", "err", err)
|
||||
r.record.Event(&(componentDefinition), event.Warning("Could not store capability in ConfigMap", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &(componentDefinition),
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &(componentDefinition),
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrStoreCapabilityInConfigMap, def.Name, err)))
|
||||
}
|
||||
|
||||
@@ -143,7 +133,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err := r.UpdateStatus(ctx, &componentDefinition); err != nil {
|
||||
klog.InfoS("Could not update componentDefinition Status", "err", err)
|
||||
r.record.Event(&componentDefinition, event.Warning("cannot update ComponentDefinition Status", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &componentDefinition,
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &componentDefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdateComponentDefinition, componentDefinition.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully updated the status.configMapRef of the ComponentDefinition", "componentDefinition",
|
||||
|
||||
+4
-7
@@ -65,10 +65,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
klog.InfoS("Reconciling PolicyDefinition...", "Name", definitionName, "Namespace", req.Namespace)
|
||||
var policydefinition v1beta1.PolicyDefinition
|
||||
if err := r.Get(ctx, req.NamespacedName, &policydefinition); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
err = nil
|
||||
}
|
||||
return ctrl.Result{}, err
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
// this is a placeholder for finalizer here in the future
|
||||
@@ -92,7 +89,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "cannot generate DefinitionRevision", "PolicyDefinitionName", policydefinition.Name)
|
||||
r.record.Event(&policydefinition, event.Warning("cannot generate DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &policydefinition,
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &policydefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrGenerateDefinitionRevision, policydefinition.Name, err)))
|
||||
}
|
||||
|
||||
@@ -100,7 +97,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err = r.createPolicyDefRevision(ctx, &policydefinition, defRev); err != nil {
|
||||
klog.ErrorS(err, "cannot create DefinitionRevision")
|
||||
r.record.Event(&(policydefinition), event.Warning("cannot create DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &(policydefinition),
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &(policydefinition),
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrCreateDefinitionRevision, defRev.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully created PolicyDefRevision", "name", defRev.Name)
|
||||
@@ -114,7 +111,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err := r.UpdateStatus(ctx, &policydefinition); err != nil {
|
||||
klog.ErrorS(err, "cannot update PolicyDefinition Status")
|
||||
r.record.Event(&(policydefinition), event.Warning("cannot update PolicyDefinition Status", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &(policydefinition),
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &(policydefinition),
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdatePolicyDefinition, policydefinition.Name, err)))
|
||||
}
|
||||
|
||||
|
||||
+6
-10
@@ -64,11 +64,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
|
||||
var traitdefinition v1beta1.TraitDefinition
|
||||
if err := r.Get(ctx, req.NamespacedName, &traitdefinition); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
err = nil
|
||||
}
|
||||
klog.InfoS("The TraitDefinition doesn't exist", "traitDefinition", klog.KRef(req.Namespace, req.Name))
|
||||
return ctrl.Result{}, err
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
// this is a placeholder for finalizer here in the future
|
||||
@@ -93,7 +89,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err != nil {
|
||||
klog.InfoS("Could not generate definitionRevision", "traitDefinition", klog.KObj(&traitdefinition), "err", err)
|
||||
r.record.Event(&traitdefinition, event.Warning("Could not generate DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &traitdefinition,
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &traitdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrGenerateDefinitionRevision, traitdefinition.Name, err)))
|
||||
}
|
||||
|
||||
@@ -101,7 +97,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err := r.createTraitDefRevision(ctx, &traitdefinition, defRev); err != nil {
|
||||
klog.ErrorS(err, "Could not create DefinitionRevision")
|
||||
r.record.Event(&traitdefinition, event.Warning("Could not create definitionRevision", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &traitdefinition,
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &traitdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrCreateDefinitionRevision, defRev.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully created definitionRevision", "definitionRevision", klog.KObj(defRev))
|
||||
@@ -114,7 +110,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err := r.UpdateStatus(ctx, &traitdefinition); err != nil {
|
||||
klog.ErrorS(err, "Could not update TraitDefinition Status", "traitDefinition", klog.KRef(req.Namespace, req.Name))
|
||||
r.record.Event(&traitdefinition, event.Warning("Could not update TraitDefinition Status", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &traitdefinition,
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &traitdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdateTraitDefinition, traitdefinition.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully updated the status.latestRevision of the TraitDefinition", "traitDefinition", klog.KRef(req.Namespace, req.Name),
|
||||
@@ -133,7 +129,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err != nil {
|
||||
klog.InfoS("Could not store capability in ConfigMap", "err", err)
|
||||
r.record.Event(&(traitdefinition), event.Warning("Could not store capability in ConfigMap", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &traitdefinition,
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &traitdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrStoreCapabilityInConfigMap, traitdefinition.Name, err)))
|
||||
}
|
||||
|
||||
@@ -142,7 +138,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err := r.UpdateStatus(ctx, &traitdefinition); err != nil {
|
||||
klog.ErrorS(err, "Could not update TraitDefinition Status", "traitDefinition", klog.KRef(req.Namespace, req.Name))
|
||||
r.record.Event(&traitdefinition, event.Warning("Could not update TraitDefinition Status", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &traitdefinition,
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &traitdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdateTraitDefinition, traitdefinition.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully updated the status.configMapRef of the TraitDefinition", "traitDefinition",
|
||||
|
||||
+4
-7
@@ -65,10 +65,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
|
||||
var wfstepdefinition v1beta1.WorkflowStepDefinition
|
||||
if err := r.Get(ctx, req.NamespacedName, &wfstepdefinition); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
err = nil
|
||||
}
|
||||
return ctrl.Result{}, err
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
// this is a placeholder for finalizer here in the future
|
||||
@@ -91,7 +88,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "cannot generate DefinitionRevision", "WorkflowStepDefinitionName", wfstepdefinition.Name)
|
||||
r.record.Event(&wfstepdefinition, event.Warning("cannot generate DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &wfstepdefinition,
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &wfstepdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrGenerateDefinitionRevision, wfstepdefinition.Name, err)))
|
||||
}
|
||||
|
||||
@@ -99,7 +96,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err = r.createWFStepDefRevision(ctx, &wfstepdefinition, defRev); err != nil {
|
||||
klog.ErrorS(err, "cannot create DefinitionRevision")
|
||||
r.record.Event(&(wfstepdefinition), event.Warning("cannot create DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &(wfstepdefinition),
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &(wfstepdefinition),
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrCreateDefinitionRevision, defRev.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully created WFStepDefRevision", "name", defRev.Name)
|
||||
@@ -112,7 +109,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
if err := r.UpdateStatus(ctx, &wfstepdefinition); err != nil {
|
||||
klog.ErrorS(err, "cannot update WorkflowStepDefinition Status")
|
||||
r.record.Event(&(wfstepdefinition), event.Warning("cannot update WorkflowStepDefinition Status", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &(wfstepdefinition),
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &(wfstepdefinition),
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdateWorkflowStepDefinition, wfstepdefinition.Name, err)))
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
|
||||
mapset "github.com/deckarep/golang-set"
|
||||
"github.com/mitchellh/hashstructure/v2"
|
||||
@@ -320,6 +322,52 @@ func RefreshPackageDiscover(ctx context.Context, k8sClient client.Client, dm dis
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckAppRolloutUsingAppRevision get all AppRollout using appRevisions related the app
|
||||
func CheckAppRolloutUsingAppRevision(ctx context.Context, c client.Reader, appNs string, appName string) ([]string, error) {
|
||||
rolloutOpts := []client.ListOption{
|
||||
client.InNamespace(appNs),
|
||||
}
|
||||
var res []string
|
||||
ars := new(v1beta1.AppRolloutList)
|
||||
if err := c.List(ctx, ars, rolloutOpts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(ars.Items) == 0 {
|
||||
return res, nil
|
||||
}
|
||||
relatedRevs := new(v1beta1.ApplicationRevisionList)
|
||||
revOpts := []client.ListOption{
|
||||
client.InNamespace(appNs),
|
||||
client.MatchingLabels{oam.LabelAppName: appName},
|
||||
}
|
||||
if err := c.List(ctx, relatedRevs, revOpts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(relatedRevs.Items) == 0 {
|
||||
return res, nil
|
||||
}
|
||||
revName := map[string]bool{}
|
||||
for _, rev := range relatedRevs.Items {
|
||||
if len(rev.Name) != 0 {
|
||||
revName[rev.Name] = true
|
||||
}
|
||||
}
|
||||
for _, d := range ars.Items {
|
||||
if d.Status.RollingState == v1alpha1.RolloutSucceedState ||
|
||||
d.Status.RollingState == v1alpha1.RolloutAbandoningState ||
|
||||
d.Status.RollingState == v1alpha1.RolloutFailedState {
|
||||
continue
|
||||
}
|
||||
if revName[d.Spec.TargetAppRevisionName] {
|
||||
res = append(res, d.Spec.TargetAppRevisionName)
|
||||
}
|
||||
if revName[d.Spec.SourceAppRevisionName] {
|
||||
res = append(res, d.Spec.SourceAppRevisionName)
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// CheckAppDeploymentUsingAppRevision get all appDeployments using appRevisions related the app
|
||||
func CheckAppDeploymentUsingAppRevision(ctx context.Context, c client.Reader, appNs string, appName string) ([]string, error) {
|
||||
deployOpts := []client.ListOption{
|
||||
|
||||
@@ -483,6 +483,17 @@ func EndReconcileWithNegativeCondition(ctx context.Context, r client.StatusClien
|
||||
return errors.Errorf(ErrReconcileErrInCondition, condition[0].Type, condition[0].Message)
|
||||
}
|
||||
|
||||
// PatchCondition will patch status with condition and return, it generally used by cases which don't want reconcile after patch
|
||||
func PatchCondition(ctx context.Context, r client.StatusClient, workload ConditionedObject,
|
||||
condition ...condition.Condition) error {
|
||||
if len(condition) == 0 {
|
||||
return nil
|
||||
}
|
||||
workloadPatch := client.MergeFrom(workload.DeepCopyObject().(client.Object))
|
||||
workload.SetConditions(condition...)
|
||||
return r.Status().Patch(ctx, workload, workloadPatch, client.FieldOwner(workload.GetUID()))
|
||||
}
|
||||
|
||||
// IsConditionChanged will check if conditions in workload is changed compare to newCondition
|
||||
func IsConditionChanged(newCondition []condition.Condition, workload ConditionedObject) bool {
|
||||
var conditionIsChanged bool
|
||||
|
||||
@@ -20,9 +20,6 @@ import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -31,6 +28,8 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
)
|
||||
|
||||
var k8sScheme = runtime.NewScheme()
|
||||
|
||||
@@ -82,7 +82,7 @@ func (h *MutatingHandler) Mutate(obj *v1beta1.ComponentDefinition) error {
|
||||
klog.InfoS("mutate", "name", obj.Name)
|
||||
|
||||
// If the Type field is not empty, it means that ComponentDefinition refers to an existing WorkloadDefinition
|
||||
if obj.Spec.Workload.Type != "" && obj.Spec.Workload.Definition == (common.WorkloadGVK{}) {
|
||||
if obj.Spec.Workload.Type != types.AutoDetectWorkloadDefinition && (obj.Spec.Workload.Type != "" && obj.Spec.Workload.Definition == (common.WorkloadGVK{})) {
|
||||
workloadDef := new(v1beta1.WorkloadDefinition)
|
||||
return h.Client.Get(context.TODO(), client.ObjectKey{Name: obj.Spec.Workload.Type, Namespace: obj.Namespace}, workloadDef)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package workflow
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/types"
|
||||
)
|
||||
@@ -26,5 +27,5 @@ import (
|
||||
type Workflow interface {
|
||||
// ExecuteSteps executes the steps of an Application with given steps of rendered resources.
|
||||
// It returns done=true only if all steps are executed and succeeded.
|
||||
ExecuteSteps(ctx context.Context, appRev *v1beta1.ApplicationRevision, taskRunners []types.TaskRunner) (done bool, pause bool, err error)
|
||||
ExecuteSteps(ctx context.Context, appRev *v1beta1.ApplicationRevision, taskRunners []types.TaskRunner) (state common.WorkflowState, err error)
|
||||
}
|
||||
|
||||
+22
-35
@@ -52,13 +52,13 @@ func NewWorkflow(app *oamcore.Application, cli client.Client, mode common.Workfl
|
||||
}
|
||||
|
||||
// ExecuteSteps process workflow step in order.
|
||||
func (w *workflow) ExecuteSteps(ctx context.Context, appRev *oamcore.ApplicationRevision, taskRunners []wfTypes.TaskRunner) (done bool, pause bool, gerr error) {
|
||||
func (w *workflow) ExecuteSteps(ctx context.Context, appRev *oamcore.ApplicationRevision, taskRunners []wfTypes.TaskRunner) (common.WorkflowState, error) {
|
||||
revAndSpecHash, err := computeAppRevisionHash(appRev.Name, w.app)
|
||||
if err != nil {
|
||||
return false, false, err
|
||||
return common.WorkflowStateExecuting, err
|
||||
}
|
||||
if len(taskRunners) == 0 {
|
||||
return true, false, nil
|
||||
return common.WorkflowStateFinished, nil
|
||||
}
|
||||
|
||||
if w.app.Status.Workflow == nil || w.app.Status.Workflow.AppRevision != revAndSpecHash {
|
||||
@@ -76,37 +76,24 @@ func (w *workflow) ExecuteSteps(ctx context.Context, appRev *oamcore.Application
|
||||
}
|
||||
|
||||
wfStatus := w.app.Status.Workflow
|
||||
|
||||
allTasksDone := w.allDone(taskRunners)
|
||||
|
||||
if wfStatus.Terminated {
|
||||
done = true
|
||||
if !allTasksDone {
|
||||
w.app.Status.Phase = common.ApplicationWorkflowTerminated
|
||||
}
|
||||
return
|
||||
return common.WorkflowStateTerminated, nil
|
||||
}
|
||||
|
||||
w.app.Status.Phase = common.ApplicationRunningWorkflow
|
||||
|
||||
if allTasksDone {
|
||||
done = true
|
||||
return
|
||||
}
|
||||
|
||||
if wfStatus.Suspend {
|
||||
pause = true
|
||||
w.app.Status.Phase = common.ApplicationWorkflowSuspending
|
||||
return
|
||||
return common.WorkflowStateSuspended, nil
|
||||
}
|
||||
if allTasksDone {
|
||||
return common.WorkflowStateFinished, nil
|
||||
}
|
||||
|
||||
var (
|
||||
wfCtx wfContext.Context
|
||||
)
|
||||
|
||||
wfCtx, gerr = w.makeContext(appRev.Name)
|
||||
if gerr != nil {
|
||||
return
|
||||
wfCtx, err = w.makeContext(appRev.Name)
|
||||
if err != nil {
|
||||
return common.WorkflowStateExecuting, err
|
||||
}
|
||||
|
||||
e := &engine{
|
||||
@@ -114,20 +101,20 @@ func (w *workflow) ExecuteSteps(ctx context.Context, appRev *oamcore.Application
|
||||
dagMode: w.dagMode,
|
||||
}
|
||||
|
||||
gerr = e.run(wfCtx, taskRunners)
|
||||
|
||||
if wfStatus.Suspend {
|
||||
pause = true
|
||||
w.app.Status.Phase = common.ApplicationWorkflowSuspending
|
||||
err = e.run(wfCtx, taskRunners)
|
||||
if err != nil {
|
||||
return common.WorkflowStateExecuting, err
|
||||
}
|
||||
|
||||
if wfStatus.Terminated {
|
||||
done = true
|
||||
w.app.Status.Phase = common.ApplicationWorkflowTerminated
|
||||
} else {
|
||||
done = w.allDone(taskRunners)
|
||||
return common.WorkflowStateTerminated, nil
|
||||
}
|
||||
return done, pause, gerr
|
||||
if wfStatus.Suspend {
|
||||
return common.WorkflowStateSuspended, nil
|
||||
}
|
||||
if w.allDone(taskRunners) {
|
||||
return common.WorkflowStateFinished, nil
|
||||
}
|
||||
return common.WorkflowStateExecuting, nil
|
||||
}
|
||||
|
||||
func (w *workflow) allDone(taskRunners []wfTypes.TaskRunner) bool {
|
||||
|
||||
@@ -66,10 +66,9 @@ var _ = Describe("Test Workflow", func() {
|
||||
},
|
||||
})
|
||||
wf := NewWorkflow(app, k8sClient, common.WorkflowModeStep)
|
||||
done, pause, err := wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
state, err := wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(pause).Should(BeFalse())
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(state).Should(BeEquivalentTo(common.WorkflowStateExecuting))
|
||||
workflowStatus := app.Status.Workflow
|
||||
Expect(workflowStatus.ContextBackend.Name).Should(BeEquivalentTo("workflow-" + revision.Name))
|
||||
workflowStatus.ContextBackend = nil
|
||||
@@ -104,10 +103,9 @@ var _ = Describe("Test Workflow", func() {
|
||||
|
||||
app.Status.Workflow = workflowStatus
|
||||
wf = NewWorkflow(app, k8sClient, common.WorkflowModeStep)
|
||||
done, pause, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
state, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(pause).Should(BeFalse())
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(state).Should(BeEquivalentTo(common.WorkflowStateFinished))
|
||||
app.Status.Workflow.ContextBackend = nil
|
||||
Expect(cmp.Diff(*app.Status.Workflow, common.WorkflowStatus{
|
||||
AppRevision: app.Status.Workflow.AppRevision,
|
||||
@@ -145,10 +143,9 @@ var _ = Describe("Test Workflow", func() {
|
||||
},
|
||||
})
|
||||
wf := NewWorkflow(app, k8sClient, common.WorkflowModeStep)
|
||||
done, pause, err := wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
state, err := wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(pause).Should(BeTrue())
|
||||
Expect(state).Should(BeEquivalentTo(common.WorkflowStateSuspended))
|
||||
wfStatus := *app.Status.Workflow
|
||||
wfStatus.ContextBackend = nil
|
||||
Expect(cmp.Diff(wfStatus, common.WorkflowStatus{
|
||||
@@ -167,19 +164,17 @@ var _ = Describe("Test Workflow", func() {
|
||||
})).Should(BeEquivalentTo(""))
|
||||
|
||||
// check suspend...
|
||||
done, pause, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
state, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(pause).Should(BeTrue())
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(state).Should(BeEquivalentTo(common.WorkflowStateSuspended))
|
||||
|
||||
// check resume
|
||||
app.Status.Workflow.Suspend = false
|
||||
// check app meta changed
|
||||
app.Name = "changed"
|
||||
done, pause, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
state, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(pause).Should(BeFalse())
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(state).Should(BeEquivalentTo(common.WorkflowStateFinished))
|
||||
app.Status.Workflow.ContextBackend = nil
|
||||
Expect(cmp.Diff(*app.Status.Workflow, common.WorkflowStatus{
|
||||
AppRevision: app.Status.Workflow.AppRevision,
|
||||
@@ -199,10 +194,9 @@ var _ = Describe("Test Workflow", func() {
|
||||
}},
|
||||
})).Should(BeEquivalentTo(""))
|
||||
|
||||
done, pause, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
state, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(pause).Should(BeFalse())
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(state).Should(BeEquivalentTo(common.WorkflowStateFinished))
|
||||
})
|
||||
|
||||
It("test for terminate", func() {
|
||||
@@ -217,10 +211,9 @@ var _ = Describe("Test Workflow", func() {
|
||||
},
|
||||
})
|
||||
wf := NewWorkflow(app, k8sClient, common.WorkflowModeStep)
|
||||
done, pause, err := wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
state, err := wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(pause).Should(BeFalse())
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(state).Should(BeEquivalentTo(common.WorkflowStateTerminated))
|
||||
app.Status.Workflow.ContextBackend = nil
|
||||
Expect(cmp.Diff(*app.Status.Workflow, common.WorkflowStatus{
|
||||
AppRevision: app.Status.Workflow.AppRevision,
|
||||
@@ -237,10 +230,9 @@ var _ = Describe("Test Workflow", func() {
|
||||
}},
|
||||
})).Should(BeEquivalentTo(""))
|
||||
|
||||
done, pause, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
state, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(pause).Should(BeFalse())
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(state).Should(BeEquivalentTo(common.WorkflowStateTerminated))
|
||||
})
|
||||
|
||||
It("test for error", func() {
|
||||
@@ -255,10 +247,9 @@ var _ = Describe("Test Workflow", func() {
|
||||
},
|
||||
})
|
||||
wf := NewWorkflow(app, k8sClient, common.WorkflowModeStep)
|
||||
done, pause, err := wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
state, err := wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(pause).Should(BeFalse())
|
||||
Expect(state).Should(BeEquivalentTo(common.WorkflowStateExecuting))
|
||||
app.Status.Workflow.ContextBackend = nil
|
||||
Expect(cmp.Diff(*app.Status.Workflow, common.WorkflowStatus{
|
||||
AppRevision: app.Status.Workflow.AppRevision,
|
||||
@@ -274,10 +265,9 @@ var _ = Describe("Test Workflow", func() {
|
||||
It("skip workflow", func() {
|
||||
app, runners := makeTestCase([]oamcore.WorkflowStep{})
|
||||
wf := NewWorkflow(app, k8sClient, common.WorkflowModeStep)
|
||||
done, pause, err := wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
state, err := wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(pause).Should(BeFalse())
|
||||
Expect(state).Should(BeEquivalentTo(common.WorkflowStateFinished))
|
||||
})
|
||||
|
||||
It("test for DAG", func() {
|
||||
@@ -297,10 +287,9 @@ var _ = Describe("Test Workflow", func() {
|
||||
})
|
||||
pending = true
|
||||
wf := NewWorkflow(app, k8sClient, common.WorkflowModeDAG)
|
||||
done, pause, err := wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
state, err := wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(pause).Should(BeFalse())
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(state).Should(BeEquivalentTo(common.WorkflowStateExecuting))
|
||||
app.Status.Workflow.ContextBackend = nil
|
||||
Expect(cmp.Diff(*app.Status.Workflow, common.WorkflowStatus{
|
||||
AppRevision: app.Status.Workflow.AppRevision,
|
||||
@@ -316,16 +305,14 @@ var _ = Describe("Test Workflow", func() {
|
||||
}},
|
||||
})).Should(BeEquivalentTo(""))
|
||||
|
||||
done, pause, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
state, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(pause).Should(BeFalse())
|
||||
Expect(done).Should(BeFalse())
|
||||
Expect(state).Should(BeEquivalentTo(common.WorkflowStateExecuting))
|
||||
|
||||
pending = false
|
||||
done, pause, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
state, err = wf.ExecuteSteps(context.Background(), revision, runners)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(pause).Should(BeFalse())
|
||||
Expect(done).Should(BeTrue())
|
||||
Expect(state).Should(BeEquivalentTo(common.WorkflowStateFinished))
|
||||
app.Status.Workflow.ContextBackend = nil
|
||||
Expect(cmp.Diff(*app.Status.Workflow, common.WorkflowStatus{
|
||||
AppRevision: app.Status.Workflow.AppRevision,
|
||||
|
||||
@@ -1188,7 +1188,7 @@ type swaggerInfo struct {
|
||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||
var SwaggerInfo = swaggerInfo{
|
||||
Version: "0.0.1",
|
||||
Host: "127.0.0.1:38081",
|
||||
Host: "127.0.0.1:37081",
|
||||
BasePath: "/api",
|
||||
Schemes: []string{},
|
||||
Title: "KubeVela Restful API",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"version": "0.0.1"
|
||||
},
|
||||
"host": "127.0.0.1:38081",
|
||||
"host": "127.0.0.1:37081",
|
||||
"basePath": "/api",
|
||||
"paths": {
|
||||
"/definitions/{definitionName}": {
|
||||
|
||||
@@ -466,7 +466,7 @@ definitions:
|
||||
description: Reference to a trait created by an ApplicationConfiguration.
|
||||
type: string
|
||||
type: object
|
||||
host: 127.0.0.1:38081
|
||||
host: 127.0.0.1:37081
|
||||
info:
|
||||
contact:
|
||||
email: NA
|
||||
|
||||
@@ -42,7 +42,7 @@ import (
|
||||
// @contact.email NA
|
||||
// @license.name Apache 2.0
|
||||
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
// @host 127.0.0.1:38081
|
||||
// @host 127.0.0.1:37081
|
||||
// @BasePath /api
|
||||
func (s *APIServer) setupRoute(staticPath string) http.Handler {
|
||||
// if deploying static Dashboard, set the mode to `release`, or to `debug`
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
)
|
||||
|
||||
// DefaultDashboardPort refers to the default port number of dashboard
|
||||
var DefaultDashboardPort = ":38081"
|
||||
var DefaultDashboardPort = ":37081"
|
||||
|
||||
// DefaultAPIServerPort refers to the default port number of APIServer
|
||||
const DefaultAPIServerPort = ":38081"
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
|
||||
"github.com/aryann/difflib"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
@@ -256,6 +255,7 @@ func generateManifest(app *v1beta1.Application, comps []*types.ComponentManifest
|
||||
Name: app.Name,
|
||||
Kind: AppKind,
|
||||
}
|
||||
removeRevisionRelatedLabelAndAnnotation(app)
|
||||
b, err := yaml.Marshal(app)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot marshal application %q", app.Name)
|
||||
@@ -270,7 +270,7 @@ func generateManifest(app *v1beta1.Application, comps []*types.ComponentManifest
|
||||
Name: comp.Name,
|
||||
Kind: RawCompKind,
|
||||
}
|
||||
emptifyAppRevisionLabel(comp.StandardWorkload)
|
||||
removeRevisionRelatedLabelAndAnnotation(comp.StandardWorkload)
|
||||
b, err := yaml.Marshal(comp.StandardWorkload)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot marshal component %q", comp.Name)
|
||||
@@ -290,7 +290,7 @@ func generateManifest(app *v1beta1.Application, comps []*types.ComponentManifest
|
||||
// get matched raw component and add it into appConfigComponent's subs
|
||||
subs := []*manifest{rawCompManifests[comp.Name]}
|
||||
for _, t := range comp.Traits {
|
||||
emptifyAppRevisionLabel(t)
|
||||
removeRevisionRelatedLabelAndAnnotation(t)
|
||||
|
||||
tType := t.GetLabels()[oam.TraitTypeLabel]
|
||||
tResource := t.GetLabels()[oam.TraitResource]
|
||||
@@ -345,9 +345,9 @@ func extractNameFromRevisionName(r string) string {
|
||||
return strings.Join(s[0:len(s)-1], "-")
|
||||
}
|
||||
|
||||
// emptifyAppRevisionLabel will set label oam.LabelAppRevision to empty
|
||||
// removeRevisionRelatedLabelAndAnnotation will set label oam.LabelAppRevision to empty
|
||||
// because dry-run cannot set value to this label
|
||||
func emptifyAppRevisionLabel(o *unstructured.Unstructured) {
|
||||
func removeRevisionRelatedLabelAndAnnotation(o client.Object) {
|
||||
newLabels := map[string]string{}
|
||||
labels := o.GetLabels()
|
||||
for k, v := range labels {
|
||||
@@ -358,6 +358,16 @@ func emptifyAppRevisionLabel(o *unstructured.Unstructured) {
|
||||
newLabels[k] = v
|
||||
}
|
||||
o.SetLabels(newLabels)
|
||||
|
||||
newAnnotations := map[string]string{}
|
||||
annotations := o.GetAnnotations()
|
||||
for k, v := range annotations {
|
||||
if k == oam.AnnotationKubeVelaVersion || k == oam.AnnotationAppRevision {
|
||||
continue
|
||||
}
|
||||
newAnnotations[k] = v
|
||||
}
|
||||
o.SetAnnotations(newAnnotations)
|
||||
}
|
||||
|
||||
// hasChanges checks whether existing change in diff records
|
||||
|
||||
@@ -320,6 +320,13 @@ func trackHealthCheckingStatus(ctx context.Context, c client.Client, compName, a
|
||||
}
|
||||
}
|
||||
if wlhc == nil {
|
||||
cTime := app.GetCreationTimestamp()
|
||||
if time.Since(cTime.Time) <= deployTimeout {
|
||||
return compStatusHealthChecking, HealthStatusUnknown, "", nil
|
||||
}
|
||||
if len(healthScope.Spec.AppRefs) == 0 && len(healthScope.Spec.WorkloadReferences) == 0 {
|
||||
return compStatusHealthCheckDone, HealthStatusHealthy, "no workload or app found in health scope", nil
|
||||
}
|
||||
return compStatusUnknown, HealthStatusUnknown, "", fmt.Errorf("cannot get health condition from the health scope: %s", healthScope.Name)
|
||||
}
|
||||
healthStatus = wlhc.HealthStatus
|
||||
|
||||
@@ -33,10 +33,9 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
apicommon "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/utils"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/common"
|
||||
)
|
||||
@@ -230,7 +229,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based app embed rollout test
|
||||
}, time.Second*30, time.Microsecond*300).Should(BeNil())
|
||||
}
|
||||
|
||||
PIt("Test upgrade application", func() {
|
||||
It("Test upgrade application", func() {
|
||||
plan := &v1alpha1.RolloutPlan{
|
||||
RolloutStrategy: v1alpha1.IncreaseFirstRolloutStrategyType,
|
||||
RolloutBatches: []v1alpha1.RolloutBatch{
|
||||
@@ -364,7 +363,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based app embed rollout test
|
||||
verifyRolloutSucceeded(utils.ConstructRevisionName(appName, 3), "3")
|
||||
})
|
||||
|
||||
PIt("Test upgrade application in middle of rolling out", func() {
|
||||
It("Test upgrade application in middle of rolling out", func() {
|
||||
plan := &v1alpha1.RolloutPlan{
|
||||
RolloutStrategy: v1alpha1.IncreaseFirstRolloutStrategyType,
|
||||
RolloutBatches: []v1alpha1.RolloutBatch{
|
||||
@@ -406,7 +405,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based app embed rollout test
|
||||
verifyRolloutSucceeded(utils.ConstructRevisionName(appName, 3), "3")
|
||||
})
|
||||
|
||||
PIt("Test pause in middle of embed app rolling out", func() {
|
||||
It("Test pause in middle of embed app rolling out", func() {
|
||||
plan := &v1alpha1.RolloutPlan{
|
||||
RolloutStrategy: v1alpha1.IncreaseFirstRolloutStrategyType,
|
||||
RolloutBatches: []v1alpha1.RolloutBatch{
|
||||
@@ -479,7 +478,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based app embed rollout test
|
||||
verifyRolloutSucceeded(utils.ConstructRevisionName(appName, 2), "2")
|
||||
})
|
||||
|
||||
PIt("Test rollout with trait", func() {
|
||||
It("Test rollout with trait", func() {
|
||||
plan := &v1alpha1.RolloutPlan{
|
||||
RolloutStrategy: v1alpha1.IncreaseFirstRolloutStrategyType,
|
||||
RolloutBatches: []v1alpha1.RolloutBatch{
|
||||
|
||||
@@ -77,7 +77,7 @@ var _ = Describe("Test application cross namespace resource", func() {
|
||||
Expect(k8sClient.Delete(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: crossNamespace}}, client.PropagationPolicy(metav1.DeletePropagationForeground))).Should(Succeed())
|
||||
})
|
||||
|
||||
PIt("Test application containing cluster-scoped trait", func() {
|
||||
It("Test application containing cluster-scoped trait", func() {
|
||||
By("Install TraitDefinition")
|
||||
traitDef := &v1beta1.TraitDefinition{}
|
||||
Expect(yaml.Unmarshal([]byte(fmt.Sprintf(clusterScopeTraitDefYAML, namespace)), traitDef)).Should(Succeed())
|
||||
@@ -139,7 +139,7 @@ var _ = Describe("Test application cross namespace resource", func() {
|
||||
}, 20*time.Second, 500*time.Millisecond).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test GC for cluster-scoped trait", func() {
|
||||
It("Test GC for cluster-scoped trait", func() {
|
||||
By("Install cluster-scoped trait's TraitDefinition")
|
||||
clusterTraitDef := &v1beta1.TraitDefinition{}
|
||||
Expect(yaml.Unmarshal([]byte(fmt.Sprintf(clusterScopeTraitDefYAML, namespace)), clusterTraitDef)).Should(Succeed())
|
||||
@@ -253,7 +253,7 @@ var _ = Describe("Test application cross namespace resource", func() {
|
||||
}, 20*time.Second, 2*time.Second).Should(SatisfyAll(&util.NotFoundMatcher{}))
|
||||
})
|
||||
|
||||
PIt("Test application have cross-namespace workload", func() {
|
||||
It("Test application have cross-namespace workload", func() {
|
||||
// install component definition
|
||||
crossCdJson, _ := yaml.YAMLToJSON([]byte(fmt.Sprintf(crossCompDefYaml, namespace, crossNamespace)))
|
||||
ccd := new(v1beta1.ComponentDefinition)
|
||||
@@ -351,7 +351,7 @@ var _ = Describe("Test application cross namespace resource", func() {
|
||||
}, time.Second*5, time.Millisecond*300).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test update application by add a cross namespace trait resource ", func() {
|
||||
It("Test update application by add a cross namespace trait resource ", func() {
|
||||
var (
|
||||
appName = "test-app-2"
|
||||
app = new(v1beta1.Application)
|
||||
@@ -394,7 +394,7 @@ var _ = Describe("Test application cross namespace resource", func() {
|
||||
if err := k8sClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: appName}, app); err != nil {
|
||||
return fmt.Errorf("error to create application %v", err)
|
||||
}
|
||||
if app.Status.Phase != common.ApplicationRunning {
|
||||
if app.Status.Phase != common.ApplicationRunning || app.Status.ObservedGeneration != app.Generation {
|
||||
return fmt.Errorf("application status not running")
|
||||
}
|
||||
depolys := new(appsv1.DeploymentList)
|
||||
@@ -461,13 +461,13 @@ var _ = Describe("Test application cross namespace resource", func() {
|
||||
return fmt.Errorf("trait owner reference missmatch")
|
||||
}
|
||||
if len(resourceTracker.Status.TrackedResources) != 2 {
|
||||
return fmt.Errorf("expect track %q resources, but got %q", 2, len(resourceTracker.Status.TrackedResources))
|
||||
return fmt.Errorf("expect track %d resources, but got %d", 2, len(resourceTracker.Status.TrackedResources))
|
||||
}
|
||||
return nil
|
||||
}, time.Second*5, time.Millisecond*500).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test update application by delete a cross namespace trait resource", func() {
|
||||
It("Test update application by delete a cross namespace trait resource", func() {
|
||||
var (
|
||||
appName = "test-app-3"
|
||||
app = new(v1beta1.Application)
|
||||
@@ -516,7 +516,7 @@ var _ = Describe("Test application cross namespace resource", func() {
|
||||
if err := k8sClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: appName}, app); err != nil {
|
||||
return fmt.Errorf("error to get application %v", err)
|
||||
}
|
||||
if app.Status.Phase != common.ApplicationRunning {
|
||||
if app.Status.Phase != common.ApplicationRunning || app.Status.ObservedGeneration != app.Generation {
|
||||
return fmt.Errorf("application status not running")
|
||||
}
|
||||
err := k8sClient.Get(ctx, generateResourceTrackerKey(app.Namespace, app.Name, 1), resourceTracker)
|
||||
@@ -578,7 +578,7 @@ var _ = Describe("Test application cross namespace resource", func() {
|
||||
}, time.Second*5, time.Millisecond*500).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test application have two different workload", func() {
|
||||
It("Test application have two different workload", func() {
|
||||
var (
|
||||
appName = "test-app-4"
|
||||
app = new(v1beta1.Application)
|
||||
@@ -717,7 +717,7 @@ var _ = Describe("Test application cross namespace resource", func() {
|
||||
}, time.Second*5, time.Millisecond*300).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("Update a cross namespace workload of application", func() {
|
||||
It("Update a cross namespace workload of application", func() {
|
||||
// install component definition
|
||||
crossCdJson, _ := yaml.YAMLToJSON([]byte(fmt.Sprintf(crossCompDefYaml, namespace, crossNamespace)))
|
||||
ccd := new(v1beta1.ComponentDefinition)
|
||||
@@ -857,7 +857,7 @@ var _ = Describe("Test application cross namespace resource", func() {
|
||||
}, time.Second*5, time.Millisecond*500).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test cross-namespace resource gc logic, delete a cross-ns component", func() {
|
||||
It("Test cross-namespace resource gc logic, delete a cross-ns component", func() {
|
||||
var (
|
||||
appName = "test-app-6"
|
||||
app = new(v1beta1.Application)
|
||||
@@ -1006,7 +1006,7 @@ var _ = Describe("Test application cross namespace resource", func() {
|
||||
}, time.Second*5, time.Millisecond*500).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test cross-namespace resource gc logic, delete a cross-ns trait", func() {
|
||||
It("Test cross-namespace resource gc logic, delete a cross-ns trait", func() {
|
||||
var (
|
||||
appName = "test-app-7"
|
||||
app = new(v1beta1.Application)
|
||||
@@ -1167,7 +1167,7 @@ var _ = Describe("Test application cross namespace resource", func() {
|
||||
}, time.Second*5, time.Millisecond*500).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test cross-namespace resource gc logic, update a cross-ns workload's namespace", func() {
|
||||
It("Test cross-namespace resource gc logic, update a cross-ns workload's namespace", func() {
|
||||
// install related definition
|
||||
crossCdJson, _ := yaml.YAMLToJSON([]byte(fmt.Sprintf(crossCompDefYaml, namespace, crossNamespace)))
|
||||
ccd := new(v1beta1.ComponentDefinition)
|
||||
|
||||
@@ -71,11 +71,10 @@ var _ = Describe("Test application controller clean up appRevision", func() {
|
||||
k8sClient.DeleteAllOf(ctx, &v1beta1.ComponentDefinition{}, client.InNamespace(namespace))
|
||||
k8sClient.DeleteAllOf(ctx, &v1beta1.WorkloadDefinition{}, client.InNamespace(namespace))
|
||||
k8sClient.DeleteAllOf(ctx, &v1beta1.TraitDefinition{}, client.InNamespace(namespace))
|
||||
|
||||
Expect(k8sClient.Delete(ctx, &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}, client.PropagationPolicy(metav1.DeletePropagationForeground))).Should(Succeed())
|
||||
})
|
||||
|
||||
PIt("Test clean up appRevision", func() {
|
||||
It("Test clean up appRevision", func() {
|
||||
appName := "app-1"
|
||||
appKey := types.NamespacedName{Namespace: namespace, Name: appName}
|
||||
app := getApp(appName, namespace, "normal-worker")
|
||||
@@ -100,6 +99,15 @@ var _ = Describe("Test application controller clean up appRevision", func() {
|
||||
}
|
||||
return nil
|
||||
}, time.Second*10, time.Millisecond*500).Should(BeNil())
|
||||
Eventually(func() error {
|
||||
checkApp = new(v1beta1.Application)
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
if checkApp.Status.ObservedGeneration == checkApp.Generation && checkApp.Status.Phase == common.ApplicationRunning {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("application is not observed or status %s is not running", checkApp.Status.Phase)
|
||||
}, time.Second*10, time.Millisecond*500).Should(BeNil())
|
||||
|
||||
}
|
||||
listOpts := []client.ListOption{
|
||||
client.InNamespace(namespace),
|
||||
@@ -118,11 +126,17 @@ var _ = Describe("Test application controller clean up appRevision", func() {
|
||||
}
|
||||
return nil
|
||||
}, time.Second*10, time.Millisecond*500).Should(BeNil())
|
||||
By("create new appRevision will remove appRevison1")
|
||||
Expect(k8sClient.Get(ctx, appKey, checkApp)).Should(BeNil())
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 5)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
Expect(k8sClient.Update(ctx, checkApp)).Should(BeNil())
|
||||
By("create new appRevision will remove appRevision v1")
|
||||
Eventually(func() error {
|
||||
err := k8sClient.Get(ctx, appKey, checkApp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 5)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
return k8sClient.Update(ctx, checkApp)
|
||||
}, time.Second*10, time.Millisecond*500).Should(BeNil())
|
||||
|
||||
deletedRevison := new(v1beta1.ApplicationRevision)
|
||||
revKey := types.NamespacedName{Namespace: namespace, Name: appName + "-v1"}
|
||||
Eventually(func() error {
|
||||
@@ -148,7 +162,7 @@ var _ = Describe("Test application controller clean up appRevision", func() {
|
||||
if err := k8sClient.Get(ctx, appKey, checkApp); err != nil {
|
||||
return err
|
||||
}
|
||||
property = fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 6)
|
||||
property := fmt.Sprintf(`{"cmd":["sleep","1000"],"image":"busybox:%d"}`, 6)
|
||||
checkApp.Spec.Components[0].Properties = runtime.RawExtension{Raw: []byte(property)}
|
||||
if err := k8sClient.Update(ctx, checkApp); err != nil {
|
||||
return err
|
||||
@@ -175,7 +189,7 @@ var _ = Describe("Test application controller clean up appRevision", func() {
|
||||
}, time.Second*10, time.Millisecond*500).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test clean up rollout appRevision", func() {
|
||||
It("Test clean up rollout appRevision", func() {
|
||||
appName := "app-2"
|
||||
appKey := types.NamespacedName{Namespace: namespace, Name: appName}
|
||||
app := getApp(appName, namespace, "normal-worker")
|
||||
|
||||
@@ -136,7 +136,7 @@ var _ = Describe("Finalizer for HealthScope in ApplicationConfiguration", func()
|
||||
})
|
||||
|
||||
When("AppConfig has no scopes", func() {
|
||||
PIt("should not register finalizer", func() {
|
||||
It("should not register finalizer", func() {
|
||||
appConfig.Spec.Components = []v1alpha2.ApplicationConfigurationComponent{
|
||||
{
|
||||
ComponentName: componentName,
|
||||
@@ -166,7 +166,7 @@ var _ = Describe("Finalizer for HealthScope in ApplicationConfiguration", func()
|
||||
})
|
||||
|
||||
When("AppConfig has scopes", func() {
|
||||
PIt("should handle finalizer before being deleted", func() {
|
||||
It("should handle finalizer before being deleted", func() {
|
||||
// create health scope definition
|
||||
sd := v1alpha2.ScopeDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
||||
@@ -80,7 +80,7 @@ var _ = Describe("AppConfig renders workloads", func() {
|
||||
Expect(k8sClient.Delete(ctx, &ns, client.PropagationPolicy(metav1.DeletePropagationForeground))).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test AppConfig controller renders workloads", func() {
|
||||
It("Test AppConfig controller renders workloads", func() {
|
||||
By("Create WorkloadDefinition")
|
||||
d := wd(wdNameAndDef(wdName))
|
||||
Expect(k8sClient.Create(ctx, d)).Should(Succeed())
|
||||
|
||||
@@ -64,7 +64,7 @@ var _ = Describe("Test compatibility for deprecation of appContext", func() {
|
||||
Expect(k8sClient.DeleteAllOf(ctx, &corev1.PersistentVolume{})).Should(Succeed())
|
||||
})
|
||||
|
||||
PIt("Test application can update its resources' owners", func() {
|
||||
It("Test application can update its resources' owners", func() {
|
||||
var err error
|
||||
var appCtxKey, rtKey *client.ObjectKey
|
||||
|
||||
@@ -162,7 +162,7 @@ var _ = Describe("Test compatibility for deprecation of appContext", func() {
|
||||
}, 30*time.Second, 500*time.Millisecond).Should(util.NotFoundMatcher{})
|
||||
})
|
||||
|
||||
PIt("Test delete an application with a legacy finalizer", func() {
|
||||
It("Test delete an application with a legacy finalizer", func() {
|
||||
var err error
|
||||
var rtKey *client.ObjectKey
|
||||
// simulate a resource tracker created by a legacy application
|
||||
|
||||
@@ -160,7 +160,7 @@ var _ = Describe("Application Normal tests", func() {
|
||||
Expect(k8sClient.Delete(ctx, &ns, client.PropagationPolicy(metav1.DeletePropagationBackground))).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test app created normally", func() {
|
||||
It("Test app created normally", func() {
|
||||
applyApp("app1.yaml")
|
||||
By("Apply the application rollout go directly to the target")
|
||||
verifyWorkloadRunningExpected("myweb", 1, "stefanprodan/podinfo:4.0.3")
|
||||
@@ -185,7 +185,7 @@ var _ = Describe("Application Normal tests", func() {
|
||||
verifyComponentRevision("myweb", 4)
|
||||
})
|
||||
|
||||
PIt("Test app have component with multiple same type traits", func() {
|
||||
It("Test app have component with multiple same type traits", func() {
|
||||
traitDef := new(v1beta1.TraitDefinition)
|
||||
Expect(common.ReadYamlToObject("testdata/app/trait_config.yaml", traitDef)).Should(BeNil())
|
||||
traitDef.Namespace = namespaceName
|
||||
@@ -216,7 +216,7 @@ var _ = Describe("Application Normal tests", func() {
|
||||
Expect(testApp.Status.Services[0].Traits[1].Message).Should(Equal("secret:app-env-config"))
|
||||
})
|
||||
|
||||
PIt("Test app have rollout-template false annotation", func() {
|
||||
It("Test app have rollout-template false annotation", func() {
|
||||
By("Apply an application")
|
||||
var newApp v1beta1.Application
|
||||
Expect(common.ReadYamlToObject("testdata/app/app5.yaml", &newApp)).Should(BeNil())
|
||||
@@ -224,7 +224,7 @@ var _ = Describe("Application Normal tests", func() {
|
||||
Expect(k8sClient.Create(ctx, &newApp)).ShouldNot(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test app have empty rollingBatches rolloutPlan", func() {
|
||||
It("Test app have empty rollingBatches rolloutPlan", func() {
|
||||
By("Apply an application")
|
||||
var newApp v1beta1.Application
|
||||
Expect(common.ReadYamlToObject("testdata/app/app6.yaml", &newApp)).Should(BeNil())
|
||||
@@ -232,7 +232,7 @@ var _ = Describe("Application Normal tests", func() {
|
||||
Expect(k8sClient.Create(ctx, &newApp)).ShouldNot(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test app have components with same name", func() {
|
||||
It("Test app have components with same name", func() {
|
||||
By("Apply an application")
|
||||
var newApp v1beta1.Application
|
||||
Expect(common.ReadYamlToObject("testdata/app/app8.yaml", &newApp)).Should(BeNil())
|
||||
@@ -240,7 +240,7 @@ var _ = Describe("Application Normal tests", func() {
|
||||
Expect(k8sClient.Create(ctx, &newApp)).ShouldNot(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test two app have component with same name", func() {
|
||||
It("Test two app have component with same name", func() {
|
||||
By("Apply an application")
|
||||
var firstApp v1beta1.Application
|
||||
Expect(common.ReadYamlToObject("testdata/app/app9.yaml", &firstApp)).Should(BeNil())
|
||||
|
||||
@@ -594,7 +594,7 @@ var _ = Describe("Component revision", func() {
|
||||
}
|
||||
|
||||
Context("Attach a revision-enable trait the first time, workload should not be recreated", func() {
|
||||
PIt("should create Component and ApplicationConfiguration", func() {
|
||||
It("should create Component and ApplicationConfiguration", func() {
|
||||
By("submit Component")
|
||||
Expect(k8sClient.Create(ctx, &component)).Should(Succeed())
|
||||
By("check Component exist")
|
||||
|
||||
@@ -227,7 +227,7 @@ var _ = Describe("ContainerizedWorkload", func() {
|
||||
Expect(k8sClient.Delete(ctx, &ns, client.PropagationPolicy(metav1.DeletePropagationForeground))).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("apply an application config", func() {
|
||||
It("apply an application config", func() {
|
||||
logf.Log.Info("Creating workload definition")
|
||||
// For some reason, WorkloadDefinition is created as a Cluster scope object
|
||||
Expect(k8sClient.Create(ctx, &wd)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
@@ -325,7 +325,7 @@ var _ = Describe("ContainerizedWorkload", func() {
|
||||
time.Second*15, time.Millisecond*500).Should(BeTrue())
|
||||
})
|
||||
|
||||
PIt("checking appConfig status changed outside of the controller loop is preserved", func() {
|
||||
It("checking appConfig status changed outside of the controller loop is preserved", func() {
|
||||
logf.Log.Info("Creating workload definition")
|
||||
// For some reason, WorkloadDefinition is created as a Cluster scope object
|
||||
Expect(k8sClient.Create(ctx, &wd)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
|
||||
@@ -62,7 +62,7 @@ var _ = Describe("ComponentDefinition Normal tests", func() {
|
||||
|
||||
Context("Test dynamic admission control for componentDefinition", func() {
|
||||
|
||||
PIt("Test componentDefinition which only set type field", func() {
|
||||
It("Test componentDefinition which only set type field", func() {
|
||||
workDef := &v1beta1.WorkloadDefinition{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "ComponentDefinition",
|
||||
@@ -95,7 +95,7 @@ var _ = Describe("ComponentDefinition Normal tests", func() {
|
||||
}).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test componentDefinition only set definition field", func() {
|
||||
It("Test componentDefinition only set definition field", func() {
|
||||
testCd := webServiceWithNoTemplate.DeepCopy()
|
||||
testCd.Spec.Schematic.CUE.Template = webServiceV1Template
|
||||
testCd.SetName("test-componentdef-v1")
|
||||
@@ -121,7 +121,7 @@ var _ = Describe("ComponentDefinition Normal tests", func() {
|
||||
Expect(newWd.Spec.Reference.Version).To(Equal("v1"))
|
||||
})
|
||||
|
||||
PIt("Test componentDefinition which definition and type fields are all empty", func() {
|
||||
It("Test componentDefinition which definition and type fields are all empty", func() {
|
||||
testCd1 := webServiceWithNoTemplate.DeepCopy()
|
||||
testCd1.SetName("test-componentdef-v2")
|
||||
testCd1.Spec.Workload.Definition = common.WorkloadGVK{}
|
||||
@@ -136,7 +136,7 @@ var _ = Describe("ComponentDefinition Normal tests", func() {
|
||||
Expect(newCd.Spec.Workload.Type).Should(Equal(types.AutoDetectWorkloadDefinition))
|
||||
})
|
||||
|
||||
PIt("Test componentDefinition which definition and type point to same workload type", func() {
|
||||
It("Test componentDefinition which definition and type point to same workload type", func() {
|
||||
testCd2 := webServiceWithNoTemplate.DeepCopy()
|
||||
testCd2.SetName("test-componentdef-v3")
|
||||
testCd2.Spec.Workload.Type = "deployments.apps"
|
||||
@@ -145,7 +145,7 @@ var _ = Describe("ComponentDefinition Normal tests", func() {
|
||||
Expect(k8sClient.Create(ctx, testCd2)).Should(Succeed())
|
||||
})
|
||||
|
||||
PIt("Test componentDefinition which definition and type point to different workload type", func() {
|
||||
It("Test componentDefinition which definition and type point to different workload type", func() {
|
||||
testCd3 := webServiceWithNoTemplate.DeepCopy()
|
||||
testCd3.SetName("test-componentdef-v4")
|
||||
testCd3.Spec.Workload.Type = "jobs.batch"
|
||||
@@ -154,7 +154,7 @@ var _ = Describe("ComponentDefinition Normal tests", func() {
|
||||
Expect(k8sClient.Create(ctx, testCd3)).Should(HaveOccurred())
|
||||
})
|
||||
|
||||
PIt("Test componentDefinition which specify the name of definitionRevision", func() {
|
||||
It("Test componentDefinition which specify the name of definitionRevision", func() {
|
||||
By("create componentDefinition")
|
||||
cd := webServiceWithNoTemplate.DeepCopy()
|
||||
cd.SetNamespace(namespace)
|
||||
@@ -184,7 +184,7 @@ var _ = Describe("ComponentDefinition Normal tests", func() {
|
||||
})
|
||||
|
||||
Context("Test dynamic admission control for traitDefinition", func() {
|
||||
PIt("Test traitDefinition which specify the name of definitionRevision", func() {
|
||||
It("Test traitDefinition which specify the name of definitionRevision", func() {
|
||||
By("create traitDefinition")
|
||||
td := exposeWithNoTemplate.DeepCopy()
|
||||
td.SetNamespace(namespace)
|
||||
|
||||
@@ -23,6 +23,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -116,13 +118,13 @@ var _ = Describe("Test application containing helm module", func() {
|
||||
|
||||
AfterEach(func() {
|
||||
By("Clean up resources after a test")
|
||||
|
||||
k8sClient.DeleteAllOf(ctx, &v1beta1.Application{}, client.InNamespace(namespace))
|
||||
k8sClient.DeleteAllOf(ctx, &v1beta1.ComponentDefinition{}, client.InNamespace(namespace))
|
||||
k8sClient.DeleteAllOf(ctx, &v1beta1.WorkloadDefinition{}, client.InNamespace(namespace))
|
||||
k8sClient.DeleteAllOf(ctx, &v1beta1.TraitDefinition{}, client.InNamespace(namespace))
|
||||
By(fmt.Sprintf("Delete the entire namespaceName %s", ns.Name))
|
||||
Expect(k8sClient.Delete(ctx, &ns, client.PropagationPolicy(metav1.DeletePropagationForeground))).Should(Succeed())
|
||||
|
||||
By("Remove 'deployments.apps' from scaler's appliesToWorkloads")
|
||||
scalerTd := v1beta1.TraitDefinition{}
|
||||
Expect(k8sClient.Get(ctx, client.ObjectKey{Name: "scaler", Namespace: "vela-system"}, &scalerTd)).Should(Succeed())
|
||||
@@ -131,7 +133,7 @@ var _ = Describe("Test application containing helm module", func() {
|
||||
Expect(k8sClient.Patch(ctx, &scalerTd, client.Merge)).Should(Succeed())
|
||||
})
|
||||
|
||||
PIt("Test deploy an application containing helm module", func() {
|
||||
It("Test deploy an application containing helm module", func() {
|
||||
app = v1beta1.Application{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: appName,
|
||||
@@ -151,7 +153,7 @@ var _ = Describe("Test application containing helm module", func() {
|
||||
{
|
||||
Type: "scaler",
|
||||
Properties: util.Object2RawExtension(map[string]interface{}{
|
||||
"replicas": 2,
|
||||
"replicas": 0,
|
||||
}),
|
||||
},
|
||||
{
|
||||
@@ -190,7 +192,7 @@ var _ = Describe("Test application containing helm module", func() {
|
||||
return false
|
||||
}
|
||||
By("Verify scaler trait is applied")
|
||||
if *deploy.Spec.Replicas != 2 {
|
||||
if *deploy.Spec.Replicas != 0 {
|
||||
return false
|
||||
}
|
||||
By("Verify application's settings override chart default values")
|
||||
@@ -212,14 +214,14 @@ var _ = Describe("Test application containing helm module", func() {
|
||||
Type: cdName,
|
||||
Properties: util.Object2RawExtension(map[string]interface{}{
|
||||
"image": map[string]interface{}{
|
||||
"tag": "5.1.3", // change 5.1.4 => 5.1.3
|
||||
"tag": "5.1.3", // change 5.1.2 => 5.1.3
|
||||
},
|
||||
}),
|
||||
Traits: []common.ApplicationTrait{
|
||||
{
|
||||
Type: "scaler",
|
||||
Properties: util.Object2RawExtension(map[string]interface{}{
|
||||
"replicas": 3, // change 2 => 3
|
||||
"replicas": 1, // change 0 => 1
|
||||
}),
|
||||
},
|
||||
{
|
||||
@@ -248,9 +250,7 @@ var _ = Describe("Test application containing helm module", func() {
|
||||
return false
|
||||
}
|
||||
By("Verify new scaler trait is applied")
|
||||
// TODO(roywang) how to enforce scaler controller reconcile
|
||||
// immediately? e2e test cannot wait 5min for reconciliation.
|
||||
if *deploy.Spec.Replicas == 2 {
|
||||
if *deploy.Spec.Replicas != 1 {
|
||||
return false
|
||||
}
|
||||
By("Verify new application's settings override chart default values")
|
||||
@@ -258,7 +258,7 @@ var _ = Describe("Test application containing helm module", func() {
|
||||
}, 120*time.Second, 10*time.Second).Should(BeTrue())
|
||||
})
|
||||
|
||||
PIt("Test deploy an application containing helm module defined by workloadDefinition", func() {
|
||||
It("Test deploy an application containing helm module defined by workloadDefinition", func() {
|
||||
|
||||
workloaddef := v1beta1.WorkloadDefinition{}
|
||||
workloaddef.SetName(wdName)
|
||||
@@ -315,7 +315,7 @@ var _ = Describe("Test application containing helm module", func() {
|
||||
}, 240*time.Second, 5*time.Second).Should(Succeed())
|
||||
})
|
||||
|
||||
PIt("Test deploy an application containing helm module and the componet refer to autodetect type workload", func() {
|
||||
It("Test deploy an application containing helm module and the component refer to autodetect type workload", func() {
|
||||
cd := v1beta1.ComponentDefinition{}
|
||||
cd.SetName("podinfo")
|
||||
cd.SetNamespace(namespace)
|
||||
@@ -334,6 +334,7 @@ var _ = Describe("Test application containing helm module", func() {
|
||||
}),
|
||||
},
|
||||
}
|
||||
cd.Spec.Workload.Type = types.AutoDetectWorkloadDefinition
|
||||
Expect(k8sClient.Create(ctx, &cd)).Should(Succeed())
|
||||
|
||||
newAppName := "test-autodetect"
|
||||
@@ -369,7 +370,7 @@ var _ = Describe("Test application containing helm module", func() {
|
||||
}, 120*time.Second, 5*time.Second).Should(Succeed())
|
||||
})
|
||||
|
||||
PIt("Test store JSON schema of Helm Chart in ConfigMap", func() {
|
||||
It("Test store JSON schema of Helm Chart in ConfigMap", func() {
|
||||
By("Get the ConfigMap")
|
||||
cmName := fmt.Sprintf("schema-%s", cdName)
|
||||
Eventually(func() error {
|
||||
|
||||
@@ -72,7 +72,7 @@ var _ = Describe("Initializer Normal tests", func() {
|
||||
Expect(k8sClient.Delete(ctx, &ns, client.PropagationPolicy(metav1.DeletePropagationForeground))).Should(Succeed())
|
||||
})
|
||||
|
||||
PIt("Test apply initializer without dependsOn", func() {
|
||||
It("Test apply initializer without dependsOn", func() {
|
||||
compName := "env1-comp"
|
||||
init := &v1beta1.Initializer{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
@@ -125,7 +125,7 @@ var _ = Describe("Initializer Normal tests", func() {
|
||||
}, 30*time.Second, 5*time.Second).Should(Succeed())
|
||||
})
|
||||
|
||||
PIt("Test apply initializer which will create namespace", func() {
|
||||
It("Test apply initializer which will create namespace", func() {
|
||||
randomNs := randomNamespaceName("initializer-createns")
|
||||
init := &v1beta1.Initializer{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
@@ -182,7 +182,7 @@ var _ = Describe("Initializer Normal tests", func() {
|
||||
|
||||
Context("Test apply initializer depends on other initializer", func() {
|
||||
|
||||
PIt("initializer depends on existing initializer", func() {
|
||||
It("initializer depends on existing initializer", func() {
|
||||
compName := "env2-comp"
|
||||
|
||||
init := &v1beta1.Initializer{
|
||||
@@ -279,7 +279,7 @@ var _ = Describe("Initializer Normal tests", func() {
|
||||
}, 30*time.Second, 5*time.Second).Should(Succeed())
|
||||
})
|
||||
|
||||
PIt("initializer depends on not non-built-in initializer not found, should be rejected by webhook", func() {
|
||||
It("initializer depends on not non-built-in initializer not found, should be rejected by webhook", func() {
|
||||
init := &v1beta1.Initializer{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Initializer",
|
||||
@@ -319,7 +319,7 @@ var _ = Describe("Initializer Normal tests", func() {
|
||||
Expect(k8sClient.Create(ctx, init)).Should(HaveOccurred())
|
||||
})
|
||||
|
||||
PIt("initializer depends on built-in initializer", func() {
|
||||
It("initializer depends on built-in initializer", func() {
|
||||
initCm := &corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "ConfigMap",
|
||||
@@ -406,7 +406,7 @@ var _ = Describe("Initializer Normal tests", func() {
|
||||
}, 120*time.Second, 500*time.Millisecond).Should(Succeed())
|
||||
})
|
||||
|
||||
PIt("Deleting initializer depended by other initializer should be rejected by webhook", func() {
|
||||
It("Deleting initializer depended by other initializer should be rejected by webhook", func() {
|
||||
initA := &v1beta1.Initializer{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Initializer",
|
||||
|
||||
@@ -163,7 +163,7 @@ spec:
|
||||
Expect(k8sClient.Patch(ctx, &scalerTd, client.Merge)).Should(Succeed())
|
||||
})
|
||||
|
||||
PIt("Test deploy an application containing kube module", func() {
|
||||
It("Test deploy an application containing kube module", func() {
|
||||
app = v1beta1.Application{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: appName,
|
||||
@@ -286,7 +286,7 @@ spec:
|
||||
}, 60*time.Second, 10*time.Second).Should(BeTrue())
|
||||
})
|
||||
|
||||
PIt("Test deploy an application containing kube module defined by workloadDefinition", func() {
|
||||
It("Test deploy an application containing kube module defined by workloadDefinition", func() {
|
||||
workloaddef := v1beta1.WorkloadDefinition{}
|
||||
workloaddef.SetName(wdName)
|
||||
workloaddef.SetNamespace(namespace)
|
||||
@@ -339,7 +339,7 @@ spec:
|
||||
}, 15*time.Second, 3*time.Second).Should(Succeed())
|
||||
})
|
||||
|
||||
PIt("Test store JSON schema of Kube parameter in ConfigMap", func() {
|
||||
It("Test store JSON schema of Kube parameter in ConfigMap", func() {
|
||||
By("Get the ConfigMap")
|
||||
cmName := fmt.Sprintf("schema-%s", cdName)
|
||||
Eventually(func() error {
|
||||
|
||||
@@ -75,7 +75,7 @@ var _ = Describe("Test kubernetes native workloads", func() {
|
||||
Expect(k8sClient.Delete(ctx, &ns, client.PropagationPolicy(metav1.DeletePropagationForeground))).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("use deployment workload", func() {
|
||||
It("use deployment workload", func() {
|
||||
label := map[string]string{"workload": "deployment"}
|
||||
// create a workload definition for
|
||||
wd := v1alpha2.WorkloadDefinition{
|
||||
|
||||
@@ -360,7 +360,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based rollout tests", func()
|
||||
Expect(k8sClient.Delete(ctx, &ns, client.PropagationPolicy(metav1.DeletePropagationBackground))).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("Test cloneset basic scale", func() {
|
||||
It("Test cloneset basic scale", func() {
|
||||
CreateClonesetDef()
|
||||
applySourceApp("app-no-replica.yaml")
|
||||
By("Apply the application rollout go directly to the target")
|
||||
@@ -375,7 +375,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based rollout tests", func()
|
||||
verifyRolloutSucceeded(appRollout.Spec.TargetAppRevisionName)
|
||||
})
|
||||
|
||||
PIt("Test cloneset rollout with a manual check", func() {
|
||||
It("Test cloneset rollout with a manual check", func() {
|
||||
applyTwoAppVersion()
|
||||
// scale to v1
|
||||
initialScale()
|
||||
@@ -431,7 +431,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based rollout tests", func()
|
||||
verifyRolloutSucceeded(appRollout.Spec.TargetAppRevisionName)
|
||||
})
|
||||
|
||||
PIt("Test pause and modify rollout plan after rolling succeeded", func() {
|
||||
It("Test pause and modify rollout plan after rolling succeeded", func() {
|
||||
CreateClonesetDef()
|
||||
applySourceApp("app-no-replica.yaml")
|
||||
By("Apply the application rollout go directly to the target")
|
||||
@@ -502,7 +502,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based rollout tests", func()
|
||||
Expect(appRollout.Status.GetCondition(oamstd.RolloutSucceed).LastTransitionTime).Should(BeEquivalentTo(lt))
|
||||
})
|
||||
|
||||
PIt("Test rolling forward after a successful rollout", func() {
|
||||
It("Test rolling forward after a successful rollout", func() {
|
||||
applyTwoAppVersion()
|
||||
// scale to v1
|
||||
initialScale()
|
||||
@@ -529,7 +529,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based rollout tests", func()
|
||||
rollForwardToSource()
|
||||
})
|
||||
|
||||
PIt("Test rolling forward in the middle of rollout", func() {
|
||||
It("Test rolling forward in the middle of rollout", func() {
|
||||
applyTwoAppVersion()
|
||||
// scale to v1
|
||||
initialScale()
|
||||
@@ -555,7 +555,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based rollout tests", func()
|
||||
rollForwardToSource()
|
||||
})
|
||||
|
||||
PIt("Test delete rollout plan should not remove workload", func() {
|
||||
It("Test delete rollout plan should not remove workload", func() {
|
||||
CreateClonesetDef()
|
||||
applyTwoAppVersion()
|
||||
// scale to v1
|
||||
@@ -598,7 +598,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based rollout tests", func()
|
||||
}, time.Second*30, time.Second).Should(BeTrue())
|
||||
})
|
||||
|
||||
PIt("Test revert the rollout plan in the middle of rollout", func() {
|
||||
It("Test revert the rollout plan in the middle of rollout", func() {
|
||||
CreateClonesetDef()
|
||||
applyTwoAppVersion()
|
||||
// scale to v1
|
||||
@@ -648,7 +648,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based rollout tests", func()
|
||||
}, time.Second*30, time.Second).Should(BeEquivalentTo(v1beta1.ResourceTrackerKind))
|
||||
})
|
||||
|
||||
PIt("Test rollout will update same name trait", func() {
|
||||
It("Test rollout will update same name trait", func() {
|
||||
CreateClonesetDef()
|
||||
CreateIngressDef()
|
||||
applySourceApp("app-with-ingress-source.yaml")
|
||||
@@ -680,7 +680,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based rollout tests", func()
|
||||
verifyIngress("test-1.example.com")
|
||||
})
|
||||
|
||||
PIt("Test rollout succeed will gc useless trait", func() {
|
||||
It("Test rollout succeed will gc useless trait", func() {
|
||||
CreateClonesetDef()
|
||||
CreateIngressDef()
|
||||
applySourceApp("app-with-ingress-source.yaml")
|
||||
@@ -716,7 +716,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based rollout tests", func()
|
||||
}, time.Second*30, 300*time.Microsecond).Should(util.NotFoundMatcher{})
|
||||
})
|
||||
|
||||
PIt("Test scale again by modify targetSize", func() {
|
||||
It("Test scale again by modify targetSize", func() {
|
||||
var err error
|
||||
CreateClonesetDef()
|
||||
applySourceApp("app-no-replica.yaml")
|
||||
@@ -784,30 +784,7 @@ var _ = Describe("rollout related e2e-test,Cloneset based rollout tests", func()
|
||||
verifyRolloutSucceeded(appRollout.Spec.TargetAppRevisionName)
|
||||
})
|
||||
|
||||
PIt("Test rolling by changing the definition", func() {
|
||||
CreateClonesetDef()
|
||||
applySourceApp("app-source.yaml")
|
||||
By("Apply the definition change")
|
||||
var cd, newCD v1beta1.ComponentDefinition
|
||||
Expect(common.ReadYamlToObject("testdata/rollout/cloneset/clonesetDefinitionModified.yaml.yaml", &newCD)).Should(BeNil())
|
||||
Eventually(
|
||||
func() error {
|
||||
k8sClient.Get(ctx, client.ObjectKey{Namespace: namespaceName, Name: newCD.Name}, &cd)
|
||||
cd.Spec = newCD.Spec
|
||||
return k8sClient.Update(ctx, &cd)
|
||||
},
|
||||
time.Second*3, time.Millisecond*300).Should(Succeed())
|
||||
By("Apply the application rollout")
|
||||
var newAppRollout v1beta1.AppRollout
|
||||
Expect(common.ReadYamlToObject("testdata/rollout/cloneset/appRollout.yaml", &newAppRollout)).Should(BeNil())
|
||||
Expect(common.ReadYamlToObject("testdata/rollout/cloneset/appRollout.yaml", &newAppRollout)).Should(BeNil())
|
||||
newAppRollout.Namespace = namespaceName
|
||||
newAppRollout.Spec.RolloutPlan.BatchPartition = pointer.Int32Ptr(int32(len(newAppRollout.Spec.RolloutPlan.
|
||||
RolloutBatches) - 1))
|
||||
createAppRolling(&newAppRollout)
|
||||
|
||||
verifyRolloutSucceeded(appRollout.Spec.TargetAppRevisionName)
|
||||
// Clean up
|
||||
k8sClient.Delete(ctx, &appRollout)
|
||||
It("Test rolling by changing the definition", func() {
|
||||
//TODO(@wonderflow): we should support rollout by changing definition
|
||||
})
|
||||
})
|
||||
|
||||
@@ -164,7 +164,7 @@ var _ = Describe("rollout related e2e-test,rollout trait test", func() {
|
||||
Expect(k8sClient.Delete(ctx, &ns, client.PropagationPolicy(metav1.DeletePropagationBackground))).Should(BeNil())
|
||||
})
|
||||
|
||||
PIt("rollout as a trait whole process e2e-test", func() {
|
||||
It("rollout as a trait whole process e2e-test", func() {
|
||||
By("first scale operation")
|
||||
Expect(common.ReadYamlToObject("testdata/rollout/deployment/application.yaml", &app)).Should(BeNil())
|
||||
app.Namespace = namespaceName
|
||||
|
||||
Reference in New Issue
Block a user