Compare commits

...

8 Commits

Author SHA1 Message Date
github-actions[bot]
8ef2513b2e fix: fix --cluster when addon enable (#5343)
Signed-off-by: zhaowei.wang <zhaowei.wang@metabit-trading.com>
(cherry picked from commit 021ca69cfd)

Co-authored-by: zhaowei.wang <zhaowei.wang@metabit-trading.com>
2023-01-13 17:09:26 +08:00
github-actions[bot]
657e3b1bde Fix: optimize skip reconcile and expose error if the traits patch an invalid workload like terraform (#5342)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 3730291eff)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2023-01-13 17:08:52 +08:00
github-actions[bot]
004e2a814d Feat: upgrade the workflow version to v0.4.0 (#5337)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit e0b8c9e4c9)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2023-01-13 16:57:03 +08:00
github-actions[bot]
6dcba5ef11 [Backport release-1.7] Fix: conflict while using gc policy and shared-resource policy concurrently (#5333)
* Fix: conflict while using gc policy and shared-resource policy concurrently

Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit f8239be21e)

* Fix: github ci

Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 72e54e5f90)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2023-01-13 15:55:05 +08:00
github-actions[bot]
fd39804dc9 Fix: maintain compatibility with old project data (#5331)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit fef55b9b1b)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2023-01-13 13:59:35 +08:00
github-actions[bot]
ce57fbb752 Feat: need one Trait to set Rollout strategy of Workload (#5327)
Signed-off-by: StevenLeiZhang <zhangleiic@163.com>
(cherry picked from commit 5d00b2ac73)

Co-authored-by: StevenLeiZhang <zhangleiic@163.com>
2023-01-12 17:19:17 +08:00
github-actions[bot]
80b2b2c2d3 velaql support indexing into exported array field (#5323)
Signed-off-by: hnd4r7 <307365651@qq.com>
(cherry picked from commit 441d8f0a66)

Co-authored-by: hnd4r7 <307365651@qq.com>
2023-01-12 10:13:57 +08:00
github-actions[bot]
49d97e5c2b Fix typo in the long cli description of vela system command (#5322)
Signed-off-by: Girish Ramnani <girishramnani95@gmail.com>
(cherry picked from commit 273b91c41f)

Co-authored-by: Girish <girishramnani95@gmail.com>
2023-01-12 10:10:15 +08:00
23 changed files with 538 additions and 21 deletions

View File

@@ -64,6 +64,8 @@ jobs:
- name: Install ginkgo
run: |
sudo sed -i 's/azure\.//' /etc/apt/sources.list
sudo apt-get update
sudo apt-get install -y golang-ginkgo-dev
- name: Start MongoDB

View File

@@ -61,6 +61,8 @@ jobs:
- name: Install ginkgo
run: |
sudo sed -i 's/azure\.//' /etc/apt/sources.list
sudo apt-get update
sudo apt-get install -y golang-ginkgo-dev
- name: Setup K3d

View File

@@ -0,0 +1,77 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/k8s-update-strategy.cue
apiVersion: core.oam.dev/v1beta1
kind: TraitDefinition
metadata:
annotations:
definition.oam.dev/alias: ""
definition.oam.dev/description: Set k8s update strategy for Deployment/DaemonSet/StatefulSet
name: k8s-update-strategy
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
- daemonsets.apps
conflictsWith: []
podDisruptive: false
schematic:
cue:
template: |
patch: spec: {
if parameter.targetKind == "Deployment" && parameter.strategy.type != "OnDelete" {
// +patchStrategy=retainKeys
strategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: {
maxSurge: parameter.strategy.rollingStrategy.maxSurge
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
}
}
}
}
if parameter.targetKind == "StatefulSet" && parameter.strategy.type != "Recreate" {
// +patchStrategy=retainKeys
updateStrategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: partition: parameter.strategy.rollingStrategy.partition
}
}
}
if parameter.targetKind == "DaemonSet" && parameter.strategy.type != "Recreate" {
// +patchStrategy=retainKeys
updateStrategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: {
maxSurge: parameter.strategy.rollingStrategy.maxSurge
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
}
}
}
}
}
parameter: {
// +usage=Specify the apiVersion of target
targetAPIVersion: *"apps/v1" | string
// +usage=Specify the kind of target
targetKind: *"Deployment" | "StatefulSet" | "DaemonSet"
// +usage=Specify the strategy of update
strategy: {
// +usage=Specify the strategy type
type: *"RollingUpdate" | "Recreate" | "OnDelete"
// +usage=Specify the parameters of rollong update strategy
rollingStrategy?: {
maxSurge: *"25%" | string
maxUnavailable: *"25%" | string
partition: *0 | int
}
}
}
workloadRefPath: ""

View File

@@ -0,0 +1,77 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/k8s-update-strategy.cue
apiVersion: core.oam.dev/v1beta1
kind: TraitDefinition
metadata:
annotations:
definition.oam.dev/alias: ""
definition.oam.dev/description: Set k8s update strategy for Deployment/DaemonSet/StatefulSet
name: k8s-update-strategy
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
- daemonsets.apps
conflictsWith: []
podDisruptive: false
schematic:
cue:
template: |
patch: spec: {
if parameter.targetKind == "Deployment" && parameter.strategy.type != "OnDelete" {
// +patchStrategy=retainKeys
strategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: {
maxSurge: parameter.strategy.rollingStrategy.maxSurge
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
}
}
}
}
if parameter.targetKind == "StatefulSet" && parameter.strategy.type != "Recreate" {
// +patchStrategy=retainKeys
updateStrategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: partition: parameter.strategy.rollingStrategy.partition
}
}
}
if parameter.targetKind == "DaemonSet" && parameter.strategy.type != "Recreate" {
// +patchStrategy=retainKeys
updateStrategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: {
maxSurge: parameter.strategy.rollingStrategy.maxSurge
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
}
}
}
}
}
parameter: {
// +usage=Specify the apiVersion of target
targetAPIVersion: *"apps/v1" | string
// +usage=Specify the kind of target
targetKind: *"Deployment" | "StatefulSet" | "DaemonSet"
// +usage=Specify the strategy of update
strategy: {
// +usage=Specify the strategy type
type: *"RollingUpdate" | "Recreate" | "OnDelete"
// +usage=Specify the parameters of rollong update strategy
rollingStrategy?: {
maxSurge: *"25%" | string
maxUnavailable: *"25%" | string
partition: *0 | int
}
}
}
workloadRefPath: ""

2
go.mod
View File

@@ -57,7 +57,7 @@ require (
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
github.com/kubevela/pkg v0.0.0-20230105054759-263dc191bf51
github.com/kubevela/prism v1.7.0-alpha.1
github.com/kubevela/workflow v0.3.6-0.20221230102636-6ae0c5cbc40f
github.com/kubevela/workflow v0.4.0
github.com/kyokomi/emoji v2.2.4+incompatible
github.com/mitchellh/hashstructure/v2 v2.0.1
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd

4
go.sum
View File

@@ -1289,8 +1289,8 @@ github.com/kubevela/pkg v0.0.0-20230105054759-263dc191bf51 h1:xrcNNaAjqC6tr1leSY
github.com/kubevela/pkg v0.0.0-20230105054759-263dc191bf51/go.mod h1:ZRnxY/gOcg/8FilZA+eYr+rtVXb1ijT5HFTe8zrv9zo=
github.com/kubevela/prism v1.7.0-alpha.1 h1:oeZFn1Oy6gxSSFzMTfsWjLOCKaaooMVm1JGNK4j4Mlo=
github.com/kubevela/prism v1.7.0-alpha.1/go.mod h1:AJSDfdA+RkRSnWx3xEcogbmOTpX+l7RSIwqVHxwUtaI=
github.com/kubevela/workflow v0.3.6-0.20221230102636-6ae0c5cbc40f h1:7EZWIfcTOgMlLgHkdDlf++hSjBTulfr4DYhZjeQbiJI=
github.com/kubevela/workflow v0.3.6-0.20221230102636-6ae0c5cbc40f/go.mod h1:AX/WL3G/YBkpmNpA/SKKm9M3Y0T9y95gZA8mFWylkyM=
github.com/kubevela/workflow v0.4.0 h1:Zzb9wPOvLUGEArdnC6EsfNM5j3VNJj0/v2iDKq1JT3k=
github.com/kubevela/workflow v0.4.0/go.mod h1:AX/WL3G/YBkpmNpA/SKKm9M3Y0T9y95gZA8mFWylkyM=
github.com/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U=
github.com/kunwardeep/paralleltest v1.0.3/go.mod h1:vLydzomDFpk7yu5UX02RmP0H8QfRPOV/oFhWN85Mjb4=
github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=

View File

@@ -550,10 +550,10 @@ func (w *workflowServiceImpl) syncWorkflowStatus(ctx context.Context,
record.Message = status.Message
record.Mode = status.Mode
if cb := app.Status.Workflow.ContextBackend; cb != nil && workflowContext == nil {
if cb := app.Status.Workflow.ContextBackend; cb != nil && workflowContext == nil && cb.Namespace != "" && cb.Name != "" {
var cm corev1.ConfigMap
if err := w.KubeClient.Get(ctx, types.NamespacedName{Namespace: cb.Namespace, Name: cb.Name}, &cm); err != nil {
klog.Error(err, "failed to load the context values", "Application", app.Name)
klog.Errorf("failed to load the context values of the application %s:%s", app.Name, err.Error())
}
record.ContextValue = cm.Data
}

View File

@@ -46,11 +46,7 @@ func (c *CR2UX) ConvertApp2DatastoreApp(ctx context.Context, targetApp *v1beta1.
}
sourceOfTruth := model.FromCR
if _, ok := targetApp.Labels[oam.LabelAddonName]; ok && strings.HasPrefix(targetApp.Name, "addon-") && targetApp.Namespace == apitypes.DefaultKubeVelaNS {
project = v1.CreateProjectRequest{
Name: model.DefaultSystemProject,
Alias: model.DefaultSystemProjectAlias,
Namespace: targetApp.Namespace,
}
project = c.generateSystemProject(ctx, targetApp.Namespace)
sourceOfTruth = model.FromInner
}
@@ -160,6 +156,27 @@ func (c *CR2UX) ConvertApp2DatastoreApp(ctx context.Context, targetApp *v1beta1.
return dsApp, nil
}
// In order to maintain compatibility with old data,
// if there is a project named addons, continue to use it, but change the alias to System.
func (c *CR2UX) generateSystemProject(ctx context.Context, ns string) v1.CreateProjectRequest {
var pro = model.Project{Name: "addons"}
if err := c.ds.Get(ctx, &pro); err == nil {
if pro.Alias == "Addons" {
pro.Alias = model.DefaultSystemProjectAlias
pro.Namespace = ns
if err := c.ds.Put(ctx, &pro); err != nil {
klog.Warningf("failed to update the project alias to System:%s", err.Error())
}
}
return v1.CreateProjectRequest{Name: pro.Name, Alias: pro.Alias, Namespace: pro.Namespace}
}
return v1.CreateProjectRequest{
Name: model.DefaultSystemProject,
Alias: model.DefaultSystemProjectAlias,
Namespace: ns,
}
}
func (c *CR2UX) generateEnv(ctx context.Context, defaultProject string, envNamespace string, envTargetNames map[string]string) (*model.Env, string, error) {
existEnv := &model.Env{Namespace: envNamespace}
existEnvs, err := c.ds.List(ctx, existEnv, nil)

View File

@@ -254,7 +254,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
}
}
case workflowv1alpha1.WorkflowStateSkipped:
return ctrl.Result{}, nil
return r.result(nil).requeue(executor.GetBackoffWaitTime()).ret()
default:
}

View File

@@ -351,13 +351,16 @@ func (td *traitDef) Complete(ctx process.Context, abstractTemplate string, param
patcher := val.LookupPath(value.FieldPath(PatchFieldName))
base, auxiliaries := ctx.Output()
if base != nil && patcher.Exists() {
if patcher.Exists() {
if base == nil {
return fmt.Errorf("patch trait %s into an invalid workload", td.name)
}
if err := base.Unify(patcher, sets.CreateUnifyOptionsForPatcher(patcher)...); err != nil {
return errors.WithMessagef(err, "invalid patch trait %s into workload", td.name)
}
}
outputsPatcher := val.LookupPath(value.FieldPath(PatchOutputsFieldName))
if base != nil && outputsPatcher.Exists() {
if outputsPatcher.Exists() {
for _, auxiliary := range auxiliaries {
target := outputsPatcher.LookupPath(value.FieldPath(auxiliary.Name))
if !target.Exists() {

View File

@@ -25,6 +25,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"github.com/kubevela/workflow/pkg/cue/packages"
wfprocess "github.com/kubevela/workflow/pkg/cue/process"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/cue/process"
@@ -1534,3 +1535,34 @@ func TestTraitPatchSingleOutput(t *testing.T) {
r.True(ok)
r.Equal("val", val)
}
func TestTraitCompleteErrorCases(t *testing.T) {
cases := map[string]struct {
ctx wfprocess.Context
traitName string
template string
params map[string]interface{}
err string
}{
"patch trait": {
ctx: process.NewContext(process.ContextData{}),
template: `
patch: {
// +patchKey=name
spec: template: spec: containers: [parameter]
}
parameter: {
name: string
image: string
command?: [...string]
}`,
err: "patch trait patch trait into an invalid workload",
},
}
for k, v := range cases {
td := NewTraitAbstractEngine(k, &packages.PackageDiscover{})
err := td.Complete(v.ctx, v.template, v.params)
assert.Error(t, err)
assert.Contains(t, err.Error(), v.err)
}
}

View File

@@ -371,6 +371,7 @@ func DeleteManagedResourceInApplication(ctx context.Context, cli client.Client,
}
return nil
}
util.RemoveAnnotations(obj, []string{oam.AnnotationAppSharedBy})
}
if mr.SkipGC || hasOrphanFinalizer(app) {
if labels := obj.GetLabels(); labels != nil {

View File

@@ -37,7 +37,7 @@ type QueryView struct {
const (
// PatternQL is the pattern string of velaQL, velaQL's query syntax is `ViewName{key1=value1 ,key2="value2",}.Export`
PatternQL = `(?P<view>[a-z0-9](?:[a-z0-9\-]{0,61}[a-z0-9])?)(?P<parameter>{.*?})?\.?(?P<export>[_a-zA-Z][\._a-zA-Z0-9]*)?`
PatternQL = `(?P<view>[a-z0-9](?:[a-z0-9\-]{0,61}[a-z0-9])?)(?P<parameter>{.*?})?\.?(?P<export>[_a-zA-Z][\._a-zA-Z0-9\[\]]*)?`
// PatternKV is the pattern string of parameter
PatternKV = `(?P<key>[^=]+)=(?P<value>[^=]*?)(?:,|$)`
// KeyWordView represent view keyword

View File

@@ -58,6 +58,13 @@ func TestParseVelaQL(t *testing.T) {
Export: "output.value.spec",
},
err: nil,
}, {
ql: `view{test=true}.output.value[0].spec`,
query: QueryView{
View: "view",
Export: "output.value[0].spec",
},
err: nil,
}}
for _, testcase := range testcases {

View File

@@ -1159,12 +1159,12 @@ func hasAddon(addons []*pkgaddon.UIData, name string) bool {
return false
}
func transClusters(cstr string) []string {
func transClusters(cstr string) []interface{} {
if len(cstr) == 0 {
return nil
}
cstr = strings.TrimPrefix(strings.TrimSuffix(cstr, "}"), "{")
var clusterL []string
var clusterL []interface{}
clusterList := strings.Split(cstr, ",")
for _, v := range clusterList {
clusterL = append(clusterL, strings.TrimSpace(v))

View File

@@ -191,19 +191,19 @@ func TestAddonUpgradeCmdWithErrLocalPath(t *testing.T) {
func TestTransCluster(t *testing.T) {
testcase := []struct {
str string
res []string
res []interface{}
}{
{
str: "{cluster1, cluster2}",
res: []string{"cluster1", "cluster2"},
res: []interface{}{"cluster1", "cluster2"},
},
{
str: "{cluster1,cluster2}",
res: []string{"cluster1", "cluster2"},
res: []interface{}{"cluster1", "cluster2"},
},
{
str: "{cluster1, cluster2 }",
res: []string{"cluster1", "cluster2"},
res: []interface{}{"cluster1", "cluster2"},
},
}
for _, s := range testcase {

View File

@@ -58,7 +58,7 @@ func NewSystemCommand(c common.Args) *cobra.Command {
cmd := &cobra.Command{
Use: "system",
Short: "Manage system.",
Long: "Manage system, incluing printing the system deployment information in vela-system namespace and diagnosing the system's health.",
Long: "Manage system, including printing the system deployment information in vela-system namespace and diagnosing the system's health.",
Example: "# Check all deployments information in all namespaces with label app.kubernetes.io/name=vela-core :\n" +
"> vela system info\n" +
"# Specify a deployment name with a namespace to check detail information:\n" +

View File

@@ -0,0 +1,91 @@
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: application-with-update-strategy
spec:
components:
- name: helloworld
type: webservice
properties:
cpu: "0.5"
exposeType: ClusterIP
image: oamdev/hello-world:latest
memory: 1024Mi
ports:
- expose: true
port: 80
protocol: TCP
traits:
- type: scaler
properties:
replicas: 5
- type: k8s-update-strategy
properties:
targetAPIVersion: apps/v1
targetKind: Deployment
strategy:
type: RollingUpdate
rollingStrategy:
maxSurge: 20%
maxUnavailable: 30%
---
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: application-node-exporter
spec:
components:
- name: node-exporter
type: daemon
properties:
image: prom/node-exporter
imagePullPolicy: IfNotPresent
volumeMounts:
hostPath:
- mountPath: /host/sys
mountPropagation: HostToContainer
name: sys
path: /sys
readOnly: true
- mountPath: /host/root
mountPropagation: HostToContainer
name: root
path: /
readOnly: true
traits:
- properties:
args:
- --path.sysfs=/host/sys
- --path.rootfs=/host/root
- --no-collector.wifi
- --no-collector.hwmon
- --collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/pods/.+)($|/)
- --collector.netclass.ignored-devices=^(veth.*)$
type: command
- properties:
annotations:
prometheus.io/path: /metrics
prometheus.io/port: "8080"
prometheus.io/scrape: "true"
port:
- 9100
type: expose
- properties:
cpu: 0.1
memory: 250Mi
type: resource
- type: k8s-update-strategy
properties:
targetAPIVersion: apps/v1
targetKind: DaemonSet
strategy:
type: RollingUpdate
rollingStrategy:
maxSurge: 20%
maxUnavailable: 30%
```

View File

@@ -912,5 +912,26 @@ var _ = Describe("Test multicluster scenario", func() {
g.Expect(cnt).Should(Equal(1))
}).WithTimeout(30 * time.Second).WithPolling(2 * time.Second).Should(Succeed())
})
It("Test application with gc policy and shared-resource policy", func() {
app := &v1beta1.Application{}
bs, err := os.ReadFile("./testdata/app/app-gc-shared.yaml")
Expect(err).Should(Succeed())
Expect(yaml.Unmarshal(bs, app)).Should(Succeed())
app.SetNamespace(namespace)
Expect(k8sClient.Create(hubCtx, app)).Should(Succeed())
appKey := client.ObjectKeyFromObject(app)
Eventually(func(g Gomega) {
g.Expect(k8sClient.Get(hubCtx, appKey, app)).Should(Succeed())
g.Expect(app.Status.Phase).Should(Equal(common.ApplicationRunning))
g.Expect(k8sClient.Get(hubCtx, appKey, &corev1.ConfigMap{})).Should(Succeed())
}).WithTimeout(10 * time.Second).Should(Succeed())
Expect(k8sClient.Get(hubCtx, appKey, app)).Should(Succeed())
Expect(k8sClient.Delete(hubCtx, app)).Should(Succeed())
Eventually(func(g Gomega) {
g.Expect(kerrors.IsNotFound(k8sClient.Get(hubCtx, appKey, app))).Should(BeTrue())
g.Expect(k8sClient.Get(hubCtx, appKey, &corev1.ConfigMap{})).Should(Succeed())
}).WithTimeout(10 * time.Second).Should(Succeed())
})
})
})

View File

@@ -0,0 +1,26 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: app-gc-shared
spec:
components:
- type: k8s-objects
name: app-gc-shared
properties:
objects:
- apiVersion: v1
kind: ConfigMap
policies:
- name: gc-policy
type: garbage-collect
properties:
rules:
- selector:
resourceTypes: ["ConfigMap"]
strategy: never
- name: shared-policy
type: shared-resource
properties:
rules:
- selector:
resourceTypes: ["ConfigMap"]

View File

@@ -0,0 +1,74 @@
"k8s-update-strategy": {
alias: ""
annotations: {}
attributes: {
appliesToWorkloads: ["deployments.apps", "statefulsets.apps", "daemonsets.apps"]
conflictsWith: []
podDisruptive: false
workloadRefPath: ""
}
description: "Set k8s update strategy for Deployment/DaemonSet/StatefulSet"
labels: {}
type: "trait"
}
template: {
patch: {
spec: {
if parameter.targetKind == "Deployment" && parameter.strategy.type != "OnDelete" {
// +patchStrategy=retainKeys
strategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: {
maxSurge: parameter.strategy.rollingStrategy.maxSurge
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
}
}
}
}
if parameter.targetKind == "StatefulSet" && parameter.strategy.type != "Recreate" {
// +patchStrategy=retainKeys
updateStrategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: {
partition: parameter.strategy.rollingStrategy.partition
}
}
}
}
if parameter.targetKind == "DaemonSet" && parameter.strategy.type != "Recreate" {
// +patchStrategy=retainKeys
updateStrategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: {
maxSurge: parameter.strategy.rollingStrategy.maxSurge
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
}
}
}
}
}}
parameter: {
// +usage=Specify the apiVersion of target
targetAPIVersion: *"apps/v1" | string
// +usage=Specify the kind of target
targetKind: *"Deployment" | "StatefulSet" | "DaemonSet"
// +usage=Specify the strategy of update
strategy: {
// +usage=Specify the strategy type
type: *"RollingUpdate" | "Recreate" | "OnDelete"
// +usage=Specify the parameters of rollong update strategy
rollingStrategy?: {
maxSurge: *"25%" | string
maxUnavailable: *"25%" | string
partition: *0 | int
}
}
}
}

View File

@@ -0,0 +1,54 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: application-node-exporter
spec:
components:
- name: node-exporter
type: daemon
properties:
image: prom/node-exporter
imagePullPolicy: IfNotPresent
volumeMounts:
hostPath:
- mountPath: /host/sys
mountPropagation: HostToContainer
name: sys
path: /sys
readOnly: true
- mountPath: /host/root
mountPropagation: HostToContainer
name: root
path: /
readOnly: true
traits:
- properties:
args:
- --path.sysfs=/host/sys
- --path.rootfs=/host/root
- --no-collector.wifi
- --no-collector.hwmon
- --collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/pods/.+)($|/)
- --collector.netclass.ignored-devices=^(veth.*)$
type: command
- properties:
annotations:
prometheus.io/path: /metrics
prometheus.io/port: "8080"
prometheus.io/scrape: "true"
port:
- 9100
type: expose
- properties:
cpu: 0.1
memory: 250Mi
type: resource
- type: k8s-update-strategy
properties:
targetAPIVersion: apps/v1
targetKind: DaemonSet
strategy:
type: RollingUpdate
rollingStrategy:
maxSurge: 20%
maxUnavailable: 30%

View File

@@ -0,0 +1,33 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: application-with-update-strategy
spec:
components:
- name: helloworld
type: webservice
properties:
cpu: "0.5"
exposeType: ClusterIP
image: oamdev/hello-world:latest
memory: 1024Mi
ports:
- expose: true
port: 80
protocol: TCP
traits:
- type: scaler
properties:
replicas: 5
- type: k8s-update-strategy
properties:
targetAPIVersion: apps/v1
targetKind: Deployment
strategy:
type: RollingUpdate
rollingStrategy:
maxSurge: 20%
maxUnavailable: 30%