mirror of
https://github.com/kubevela/kubevela.git
synced 2026-02-28 16:50:29 +00:00
Compare commits
8 Commits
v1.7.0-bet
...
v1.7.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ef2513b2e | ||
|
|
657e3b1bde | ||
|
|
004e2a814d | ||
|
|
6dcba5ef11 | ||
|
|
fd39804dc9 | ||
|
|
ce57fbb752 | ||
|
|
80b2b2c2d3 | ||
|
|
49d97e5c2b |
2
.github/workflows/apiserver-test.yml
vendored
2
.github/workflows/apiserver-test.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/unit-test.yml
vendored
2
.github/workflows/unit-test.yml
vendored
@@ -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
|
||||
|
||||
@@ -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: ""
|
||||
|
||||
@@ -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
2
go.mod
@@ -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
4
go.sum
@@ -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=
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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" +
|
||||
|
||||
91
references/docgen/def-doc/trait/k8s-update-strategy.eg.md
Normal file
91
references/docgen/def-doc/trait/k8s-update-strategy.eg.md
Normal 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%
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
@@ -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())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
26
test/e2e-multicluster-test/testdata/app/app-gc-shared.yaml
vendored
Normal file
26
test/e2e-multicluster-test/testdata/app/app-gc-shared.yaml
vendored
Normal 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"]
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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%
|
||||
@@ -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%
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user