mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-27 16:17:34 +00:00
Merge pull request #1142 from ryanzhang-oss/e2e-test
add rollout cloneset based rudimentory e2e test
This commit is contained in:
@@ -64,7 +64,10 @@ func makeHTTPRequest(ctx context.Context, webhookEndPoint, method string, payloa
|
||||
|
||||
// failed even with retry
|
||||
if err != nil {
|
||||
return nil, r.StatusCode, err
|
||||
if r != nil {
|
||||
return nil, r.StatusCode, err
|
||||
}
|
||||
return nil, -1, err
|
||||
}
|
||||
return body, r.StatusCode, nil
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ const mockUrl = "127.0.0.1:4848"
|
||||
|
||||
func Test_MakeHTTPRequest(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
type parameter struct {
|
||||
type mockHTTPParameter struct {
|
||||
method string
|
||||
statusCode int
|
||||
body string
|
||||
@@ -29,15 +29,16 @@ func Test_MakeHTTPRequest(t *testing.T) {
|
||||
body string
|
||||
}
|
||||
tests := map[string]struct {
|
||||
method string
|
||||
payload interface{}
|
||||
parameter parameter
|
||||
want want
|
||||
url string
|
||||
method string
|
||||
payload interface{}
|
||||
httpParameter mockHTTPParameter
|
||||
want want
|
||||
}{
|
||||
"Test normal case": {
|
||||
method: http.MethodPost,
|
||||
payload: "doesn't matter",
|
||||
parameter: parameter{
|
||||
httpParameter: mockHTTPParameter{
|
||||
method: http.MethodPost,
|
||||
statusCode: http.StatusAccepted,
|
||||
body: "all good",
|
||||
@@ -48,10 +49,25 @@ func Test_MakeHTTPRequest(t *testing.T) {
|
||||
body: "all good",
|
||||
},
|
||||
},
|
||||
"Test http failed case with retry": {
|
||||
url: "127.0.0.1:13622",
|
||||
method: http.MethodPost,
|
||||
payload: "doesn't matter",
|
||||
httpParameter: mockHTTPParameter{
|
||||
method: http.MethodGet,
|
||||
statusCode: http.StatusAccepted,
|
||||
body: "doesn't matter",
|
||||
},
|
||||
want: want{
|
||||
err: fmt.Errorf("internal server error, status code = %d", http.StatusNotImplemented),
|
||||
statusCode: -1,
|
||||
body: "",
|
||||
},
|
||||
},
|
||||
"Test failed case with retry": {
|
||||
method: http.MethodPost,
|
||||
payload: "doesn't matter",
|
||||
parameter: parameter{
|
||||
httpParameter: mockHTTPParameter{
|
||||
method: http.MethodPost,
|
||||
statusCode: http.StatusNotImplemented,
|
||||
body: "please retry",
|
||||
@@ -65,7 +81,7 @@ func Test_MakeHTTPRequest(t *testing.T) {
|
||||
"Test client error failed case": {
|
||||
method: http.MethodPost,
|
||||
payload: "doesn't matter",
|
||||
parameter: parameter{
|
||||
httpParameter: mockHTTPParameter{
|
||||
method: http.MethodPost,
|
||||
statusCode: http.StatusBadRequest,
|
||||
body: "bad request",
|
||||
@@ -80,22 +96,33 @@ func Test_MakeHTTPRequest(t *testing.T) {
|
||||
for testName, tt := range tests {
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
// generate a test server so we can capture and inspect the request
|
||||
testServer := NewMock(tt.parameter.method, tt.parameter.statusCode, tt.parameter.body)
|
||||
testServer := NewMock(tt.httpParameter.method, tt.httpParameter.statusCode, tt.httpParameter.body)
|
||||
defer testServer.Close()
|
||||
gotReply, gotCode, gotErr := makeHTTPRequest(ctx, "http://"+mockUrl, tt.method, tt.payload)
|
||||
if (tt.want.err == nil && gotErr != nil) || (tt.want.err != nil && gotErr == nil) {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want error `%s`, got error:`%s`\n", testName, tt.want.err, gotErr)
|
||||
}
|
||||
if tt.want.err != nil && gotErr != nil && gotErr.Error() != tt.want.err.Error() {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want error `%s`, got error:`%s`\n", testName, tt.want.err, gotErr)
|
||||
}
|
||||
if string(gotReply) != tt.want.body {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want reply `%s`, got reply:`%s`\n", testName, tt.want.body, string(gotReply))
|
||||
if len(tt.url) == 0 {
|
||||
tt.url = mockUrl
|
||||
}
|
||||
gotReply, gotCode, gotErr := makeHTTPRequest(ctx, "http://"+tt.url, tt.method, tt.payload)
|
||||
if gotCode != tt.want.statusCode {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want code `%d`, got code:`%d`\n", testName, tt.want.statusCode,
|
||||
gotCode)
|
||||
}
|
||||
if gotCode == -1 {
|
||||
// we don't know exactly what error we should get when the network call failed
|
||||
if gotErr == nil {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want some error, got error:`%s`\n", testName, gotErr)
|
||||
}
|
||||
} else {
|
||||
if (tt.want.err == nil && gotErr != nil) || (tt.want.err != nil && gotErr == nil) {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want error `%s`, got error:`%s`\n", testName, tt.want.err, gotErr)
|
||||
}
|
||||
if tt.want.err != nil && gotErr != nil && gotErr.Error() != tt.want.err.Error() {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want error `%s`, got error:`%s`\n", testName, tt.want.err, gotErr)
|
||||
}
|
||||
|
||||
}
|
||||
if string(gotReply) != tt.want.body {
|
||||
t.Errorf("\n%s\nr.Reconcile(...): want reply `%s`, got reply:`%s`\n", testName, tt.want.body, string(gotReply))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
package controllers_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
|
||||
kruise "github.com/openkruise/kruise-api/apps/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2"
|
||||
oamstd "github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
var _ = Describe("Test Rolling out Application", func() {
|
||||
ctx := context.Background()
|
||||
namespace := "rolling"
|
||||
var ns corev1.Namespace
|
||||
|
||||
BeforeEach(func() {
|
||||
logf.Log.Info("Start to run a test, clean up previous resources")
|
||||
namespace = string(strconv.AppendInt([]byte(namespace), rand.Int63(), 16))
|
||||
ns = corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: namespace,
|
||||
},
|
||||
}
|
||||
// delete the namespace with all its resources
|
||||
Expect(k8sClient.Delete(ctx, &ns, client.PropagationPolicy(metav1.DeletePropagationForeground))).
|
||||
Should(SatisfyAny(BeNil(), &util.NotFoundMatcher{}))
|
||||
logf.Log.Info("make sure all the resources are removed")
|
||||
objectKey := client.ObjectKey{
|
||||
Name: namespace,
|
||||
}
|
||||
res := &corev1.Namespace{}
|
||||
Eventually(
|
||||
func() error {
|
||||
return k8sClient.Get(ctx, objectKey, res)
|
||||
},
|
||||
time.Second*120, time.Millisecond*500).Should(&util.NotFoundMatcher{})
|
||||
Eventually(
|
||||
func() error {
|
||||
return k8sClient.Create(ctx, &ns)
|
||||
},
|
||||
time.Second*3, time.Millisecond*300).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
By("Install CloneSet based workloadDefinition")
|
||||
var cd v1alpha2.WorkloadDefinition
|
||||
Expect(readYaml("testdata/rollout/clonesetDefinition.yaml", &cd)).Should(BeNil())
|
||||
// create the workloadDefinition if not exist
|
||||
Eventually(
|
||||
func() error {
|
||||
return k8sClient.Create(ctx, &cd)
|
||||
},
|
||||
time.Second*3, time.Millisecond*300).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
logf.Log.Info("Clean up resources")
|
||||
// delete the namespace with all its resources
|
||||
Expect(k8sClient.Delete(ctx, &ns, client.PropagationPolicy(metav1.DeletePropagationForeground))).Should(BeNil())
|
||||
})
|
||||
|
||||
It("Basic cloneset rollout", func() {
|
||||
By("Apply an application")
|
||||
var app v1alpha2.Application
|
||||
Expect(readYaml("testdata/rollout/app-source.yaml", &app)).Should(BeNil())
|
||||
app.Namespace = namespace
|
||||
Expect(k8sClient.Create(ctx, &app)).Should(Succeed())
|
||||
By("Get Application latest status after AppConfig created")
|
||||
Eventually(
|
||||
func() *v1alpha2.Revision {
|
||||
k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: app.Name}, &app)
|
||||
return app.Status.LatestRevision
|
||||
},
|
||||
time.Second*30, time.Millisecond*500).ShouldNot(BeNil())
|
||||
By("Wait for AppConfig1 synced")
|
||||
var appConfig1 v1alpha2.ApplicationConfiguration
|
||||
Eventually(
|
||||
func() corev1.ConditionStatus {
|
||||
k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: app.Status.LatestRevision.Name}, &appConfig1)
|
||||
return appConfig1.Status.GetCondition(v1alpha1.TypeSynced).Status
|
||||
},
|
||||
time.Second*30, time.Millisecond*500).Should(BeEquivalentTo(corev1.ConditionTrue))
|
||||
|
||||
By("Mark the application as rolling")
|
||||
Expect(readYaml("testdata/rollout/app-source-prep.yaml", &app)).Should(BeNil())
|
||||
app.Namespace = namespace
|
||||
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
|
||||
By("Wait for AppConfig1 to be templated")
|
||||
Eventually(
|
||||
func() v1alpha2.RollingStatus {
|
||||
k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: app.Status.LatestRevision.Name}, &appConfig1)
|
||||
return appConfig1.Status.RollingStatus
|
||||
},
|
||||
time.Second*60, time.Millisecond*500).Should(BeEquivalentTo(v1alpha2.RollingTemplated))
|
||||
|
||||
By("Update the application during rolling")
|
||||
Expect(readYaml("testdata/rollout/app-target.yaml", &app)).Should(BeNil())
|
||||
app.Namespace = namespace
|
||||
Expect(k8sClient.Update(ctx, &app)).Should(Succeed())
|
||||
By("Get Application latest status after AppConfig created")
|
||||
Eventually(
|
||||
func() int64 {
|
||||
k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: app.Name}, &app)
|
||||
return app.Status.LatestRevision.Revision
|
||||
},
|
||||
time.Second*10, time.Millisecond*500).ShouldNot(BeEquivalentTo(1))
|
||||
By("Wait for AppConfig2 synced")
|
||||
var appConfig2 v1alpha2.ApplicationConfiguration
|
||||
Eventually(
|
||||
func() corev1.ConditionStatus {
|
||||
k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: app.Status.LatestRevision.Name}, &appConfig2)
|
||||
return appConfig2.Status.GetCondition(v1alpha1.TypeSynced).Status
|
||||
},
|
||||
time.Second*60, time.Millisecond*500).Should(BeEquivalentTo(corev1.ConditionTrue))
|
||||
|
||||
By("Wait for AppConfig2 to be templated")
|
||||
Eventually(
|
||||
func() v1alpha2.RollingStatus {
|
||||
k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: app.Status.LatestRevision.Name}, &appConfig2)
|
||||
return appConfig2.Status.RollingStatus
|
||||
},
|
||||
time.Second*60, time.Millisecond*500).Should(BeEquivalentTo(v1alpha2.RollingTemplated))
|
||||
|
||||
By("Get the cloneset workload")
|
||||
var kc kruise.CloneSet
|
||||
workloadName := utils.ExtractComponentName(appConfig2.Spec.Components[0].RevisionName)
|
||||
Expect(k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: workloadName},
|
||||
&kc)).ShouldNot(HaveOccurred())
|
||||
Expect(kc.Spec.UpdateStrategy.Paused).Should(BeTrue())
|
||||
|
||||
By("Apply the application rollout that stops after two batches")
|
||||
var appDeploy v1alpha2.ApplicationDeployment
|
||||
Expect(readYaml("testdata/rollout/app-deploy-pause.yaml", &appDeploy)).Should(BeNil())
|
||||
appDeploy.Namespace = namespace
|
||||
Expect(k8sClient.Create(ctx, &appDeploy)).Should(Succeed())
|
||||
|
||||
By("Wait for the rollout phase change to rolling in batches")
|
||||
Eventually(
|
||||
func() oamstd.RollingState {
|
||||
k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: appDeploy.Name}, &appDeploy)
|
||||
return appDeploy.Status.RollingState
|
||||
},
|
||||
time.Second*60, time.Millisecond*500).Should(BeEquivalentTo(oamstd.RollingInBatchesState))
|
||||
|
||||
By("Wait for rollout to finish two batches")
|
||||
Eventually(
|
||||
func() int32 {
|
||||
k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: appDeploy.Name}, &appDeploy)
|
||||
return appDeploy.Status.CurrentBatch
|
||||
},
|
||||
time.Second*60, time.Millisecond*500).Should(BeEquivalentTo(1))
|
||||
|
||||
By("Verify that the rollout stops at two batches")
|
||||
// wait for the batch to be ready
|
||||
Eventually(
|
||||
func() oamstd.BatchRollingState {
|
||||
k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: appDeploy.Name}, &appDeploy)
|
||||
return appDeploy.Status.BatchRollingState
|
||||
},
|
||||
time.Second*60, time.Millisecond*500).Should(Equal(oamstd.BatchReadyState))
|
||||
// wait for 30 seconds, it should still be at 1
|
||||
time.Sleep(30 * time.Second)
|
||||
k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: appDeploy.Name}, &appDeploy)
|
||||
Expect(appDeploy.Status.CurrentBatch).Should(BeEquivalentTo(1))
|
||||
Expect(appDeploy.Status.BatchRollingState).Should(BeEquivalentTo(oamstd.BatchReadyState))
|
||||
|
||||
Expect(k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: workloadName},
|
||||
&kc)).ShouldNot(HaveOccurred())
|
||||
Expect(kc.Status.UpdatedReplicas).Should(BeEquivalentTo(3))
|
||||
Expect(kc.Status.UpdatedReadyReplicas).Should(BeEquivalentTo(3))
|
||||
|
||||
By("Finish the application rollout")
|
||||
Expect(readYaml("testdata/rollout/app-deploy-finish.yaml", &appDeploy)).Should(BeNil())
|
||||
appDeploy.Namespace = namespace
|
||||
Expect(k8sClient.Update(ctx, &appDeploy)).Should(Succeed())
|
||||
|
||||
By("Wait for the rollout phase change to succeeded")
|
||||
Eventually(
|
||||
func() oamstd.RollingState {
|
||||
k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: appDeploy.Name}, &appDeploy)
|
||||
return appDeploy.Status.RollingState
|
||||
},
|
||||
time.Second*60, time.Millisecond*500).Should(Equal(oamstd.RolloutSucceedState))
|
||||
|
||||
By("Wait for rollout to finish two batches")
|
||||
Expect(k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: workloadName},
|
||||
&kc)).ShouldNot(HaveOccurred())
|
||||
Expect(kc.Status.UpdatedReplicas).Should(BeEquivalentTo(5))
|
||||
Expect(kc.Status.UpdatedReadyReplicas).Should(BeEquivalentTo(5))
|
||||
// Clean up
|
||||
k8sClient.Delete(ctx, &appDeploy)
|
||||
k8sClient.Delete(ctx, &appConfig2)
|
||||
k8sClient.Delete(ctx, &appConfig1)
|
||||
k8sClient.Delete(ctx, &app)
|
||||
})
|
||||
})
|
||||
+12
-12
@@ -19,10 +19,12 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
kruise "github.com/openkruise/kruise-api/apps/v1alpha1"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
@@ -75,6 +77,8 @@ var _ = BeforeSuite(func(done Done) {
|
||||
Expect(err).Should(BeNil())
|
||||
err = crdv1.AddToScheme(scheme)
|
||||
Expect(err).Should(BeNil())
|
||||
err = kruise.AddToScheme(scheme)
|
||||
Expect(err).Should(BeNil())
|
||||
depExample := &unstructured.Unstructured{}
|
||||
depExample.SetGroupVersionKind(schema.GroupVersionKind{
|
||||
Group: "example.com",
|
||||
@@ -94,15 +98,6 @@ var _ = BeforeSuite(func(done Done) {
|
||||
}
|
||||
By("Finished setting up test environment")
|
||||
|
||||
By("Applying CRD of WorkloadDefinition and TraitDefinition")
|
||||
var workloadDefinitionCRD crdv1.CustomResourceDefinition
|
||||
Expect(readYaml("../../charts/vela-core/crds/core.oam.dev_workloaddefinitions.yaml", &workloadDefinitionCRD)).Should(BeNil())
|
||||
Expect(k8sClient.Create(context.Background(), &workloadDefinitionCRD)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
|
||||
var traitDefinitionCRD crdv1.CustomResourceDefinition
|
||||
Expect(readYaml("../../charts/vela-core/crds/core.oam.dev_traitdefinitions.yaml", &traitDefinitionCRD)).Should(BeNil())
|
||||
Expect(k8sClient.Create(context.Background(), &traitDefinitionCRD)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
|
||||
// Create manual scaler trait definition
|
||||
manualscalertrait = v1alpha2.TraitDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -263,7 +258,11 @@ var _ = BeforeSuite(func(done Done) {
|
||||
By("Create workload definition for revision mechanism test")
|
||||
var nwd v1alpha2.WorkloadDefinition
|
||||
Expect(readYaml("testdata/revision/workload-def.yaml", &nwd)).Should(BeNil())
|
||||
Expect(k8sClient.Create(context.Background(), &nwd)).Should(Succeed())
|
||||
Eventually(
|
||||
func() error {
|
||||
return k8sClient.Create(context.Background(), &nwd)
|
||||
},
|
||||
time.Second*3, time.Millisecond*300).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
|
||||
close(done)
|
||||
}, 300)
|
||||
@@ -288,12 +287,13 @@ var _ = AfterSuite(func() {
|
||||
Expect(k8sClient.Delete(context.Background(), &crd)).Should(BeNil())
|
||||
By("Deleted the custom resource definition")
|
||||
|
||||
By("Deleting all the definitions by deleting the definition CRDs")
|
||||
crd = crdv1.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "workloaddefinitions.core.oam.dev",
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Delete(context.Background(), &crd)).Should(BeNil())
|
||||
Expect(k8sClient.Delete(context.Background(), &crd)).Should(SatisfyAny(BeNil(), &util.NotFoundMatcher{}))
|
||||
By("Deleted the workloaddefinitions CRD")
|
||||
|
||||
crd = crdv1.CustomResourceDefinition{
|
||||
@@ -301,6 +301,6 @@ var _ = AfterSuite(func() {
|
||||
Name: "traitdefinitions.core.oam.dev",
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Delete(context.Background(), &crd)).Should(BeNil())
|
||||
Expect(k8sClient.Delete(context.Background(), &crd)).Should(SatisfyAny(BeNil(), &util.NotFoundMatcher{}))
|
||||
By("Deleted the workloaddefinitions CRD")
|
||||
})
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: ApplicationDeployment
|
||||
metadata:
|
||||
name: rolling-e2e-test
|
||||
spec:
|
||||
# application (revision) reference
|
||||
targetApplicationName: test-e2e-rolling-v2
|
||||
sourceApplicationName: test-e2e-rolling-v1
|
||||
# HPA reference (optional)
|
||||
componentList:
|
||||
- metrics-provider
|
||||
rolloutPlan:
|
||||
rolloutStrategy: "IncreaseFirst"
|
||||
rolloutBatches:
|
||||
- replicas: 10%
|
||||
- replicas: 2
|
||||
- replicas: 2
|
||||
batchPartition: 2
|
||||
@@ -0,0 +1,18 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: ApplicationDeployment
|
||||
metadata:
|
||||
name: rolling-e2e-test
|
||||
spec:
|
||||
# application (revision) reference
|
||||
targetApplicationName: test-e2e-rolling-v2
|
||||
sourceApplicationName: test-e2e-rolling-v1
|
||||
# HPA reference (optional)
|
||||
componentList:
|
||||
- metrics-provider
|
||||
rolloutPlan:
|
||||
rolloutStrategy: "IncreaseFirst"
|
||||
rolloutBatches:
|
||||
- replicas: 10%
|
||||
- replicas: 2
|
||||
- replicas: 2
|
||||
batchPartition: 1
|
||||
@@ -0,0 +1,18 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: Application
|
||||
metadata:
|
||||
name: test-e2e-rolling
|
||||
annotations:
|
||||
"app.oam.dev/rolling-components": "metrics-provider"
|
||||
"app.oam.dev/rollout-template": "true"
|
||||
spec:
|
||||
components:
|
||||
- name: metrics-provider
|
||||
type: clonesetservice
|
||||
settings:
|
||||
cmd:
|
||||
- ./podinfo
|
||||
- stress-cpu=1
|
||||
image: stefanprodan/podinfo:4.0.6
|
||||
port: 8080
|
||||
updateStrategyType: InPlaceIfPossible
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: Application
|
||||
metadata:
|
||||
name: test-e2e-rolling
|
||||
spec:
|
||||
components:
|
||||
- name: metrics-provider
|
||||
type: clonesetservice
|
||||
settings:
|
||||
cmd:
|
||||
- ./podinfo
|
||||
- stress-cpu=1
|
||||
image: stefanprodan/podinfo:4.0.6
|
||||
port: 8080
|
||||
updateStrategyType: InPlaceIfPossible
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: Application
|
||||
metadata:
|
||||
name: test-e2e-rolling
|
||||
annotations:
|
||||
"app.oam.dev/rolling-components": "metrics-provider"
|
||||
"app.oam.dev/rollout-template": "true"
|
||||
spec:
|
||||
components:
|
||||
- name: metrics-provider
|
||||
type: clonesetservice
|
||||
settings:
|
||||
cmd:
|
||||
- ./podinfo
|
||||
- stress-cpu=1
|
||||
image: stefanprodan/podinfo:5.0.2
|
||||
port: 8080
|
||||
updateStrategyType: InPlaceIfPossible
|
||||
@@ -0,0 +1,105 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT.
|
||||
apiVersion: core.oam.dev/v1alpha2
|
||||
kind: WorkloadDefinition
|
||||
metadata:
|
||||
name: clonesetservice
|
||||
annotations:
|
||||
definition.oam.dev/description: "Describes long-running, scalable, containerized services that have a stable network endpoint to receive external network traffic from customers.
|
||||
If workload type is skipped for any service defined in Appfile, it will be defaulted to `webservice` type."
|
||||
spec:
|
||||
definitionRef:
|
||||
name: clonesets.apps.kruise.io
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
output: {
|
||||
apiVersion: "apps.kruise.io/v1alpha1"
|
||||
kind: "CloneSet"
|
||||
metadata: labels: {
|
||||
"app.oam.dev/component": context.name
|
||||
}
|
||||
spec: {
|
||||
replicas: parameter.replicas
|
||||
selector: matchLabels: {
|
||||
"app.oam.dev/component": context.name
|
||||
}
|
||||
|
||||
template: {
|
||||
metadata: labels: {
|
||||
"app.oam.dev/component": context.name
|
||||
}
|
||||
|
||||
spec: {
|
||||
containers: [{
|
||||
name: context.name
|
||||
image: parameter.image
|
||||
|
||||
if parameter["cmd"] != _|_ {
|
||||
command: parameter.cmd
|
||||
}
|
||||
|
||||
if parameter["env"] != _|_ {
|
||||
env: parameter.env
|
||||
}
|
||||
|
||||
if context["config"] != _|_ {
|
||||
env: context.config
|
||||
}
|
||||
|
||||
ports: [{
|
||||
containerPort: parameter.port
|
||||
}]
|
||||
|
||||
if parameter["cpu"] != _|_ {
|
||||
resources: {
|
||||
limits:
|
||||
cpu: parameter.cpu
|
||||
requests:
|
||||
cpu: parameter.cpu
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
if parameter["updateStrategyType"] != _|_ {
|
||||
updateStrategy: {
|
||||
type: parameter.updateStrategyType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Which image would you like to use for your service
|
||||
// +short=i
|
||||
image: string
|
||||
|
||||
// +usage=Commands to run in the container
|
||||
cmd?: [...string]
|
||||
|
||||
// +usage=Which port do you want customer traffic sent to
|
||||
// +short=p
|
||||
port: *80 | int
|
||||
// +usage=Define arguments by using environment variables
|
||||
env?: [...{
|
||||
// +usage=Environment variable name
|
||||
name: string
|
||||
// +usage=The value of the environment variable
|
||||
value?: string
|
||||
// +usage=Specifies a source the value of this var should come from
|
||||
valueFrom?: {
|
||||
// +usage=Selects a key of a secret in the pod's namespace
|
||||
secretKeyRef: {
|
||||
// +usage=The name of the secret in the pod's namespace to select from
|
||||
name: string
|
||||
// +usage=The key of the secret to select from. Must be a valid secret key
|
||||
key: string
|
||||
}
|
||||
}
|
||||
}]
|
||||
// +usage=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)
|
||||
cpu?: string
|
||||
// +usage=Cloneset updateStrategy, candidates are `ReCreate`/`InPlaceIfPossible`/`InPlaceOnly`
|
||||
updateStrategyType?: string
|
||||
// +usage=Number of pods in the cloneset
|
||||
replicas: *5 | int
|
||||
}
|
||||
Reference in New Issue
Block a user