diff options
| author | ming.tang <ming.tang@daocloud.io> | 2023-12-05 13:05:12 +0800 |
|---|---|---|
| committer | ming.tang <ming.tang@daocloud.io> | 2024-01-17 17:00:07 +0800 |
| commit | b73223139f4d10e80414d205dbc41f6a1d36ebfd (patch) | |
| tree | 8e7a8c2ccf71e1b93f9753aa195c56ec21cf3376 /cloud | |
| parent | Merge pull request #5321 from luomengY/ci-cri (diff) | |
| download | kubeedge-b73223139f4d10e80414d205dbc41f6a1d36ebfd.tar.gz | |
Update the EdgeApplication API definition. EdgeApplication Differential configuration Added support for command and arg fields.
Signed-off-by: ming.tang <ming.tang@daocloud.io>
Diffstat (limited to 'cloud')
5 files changed, 182 insertions, 6 deletions
diff --git a/cloud/pkg/controllermanager/controllermanager.go b/cloud/pkg/controllermanager/controllermanager.go index 141da5730..52781e843 100644 --- a/cloud/pkg/controllermanager/controllermanager.go +++ b/cloud/pkg/controllermanager/controllermanager.go @@ -66,6 +66,8 @@ func setupControllers(ctx context.Context, mgr manager.Manager) error { &overridemanager.ReplicasOverrider{}, &overridemanager.ImageOverrider{}, &overridemanager.NodeSelectorOverrider{}, + &overridemanager.CommandOverrider{}, + &overridemanager.ArgsOverrider{}, }, }, } diff --git a/cloud/pkg/controllermanager/edgeapplication/overridemanager/argsoverrider.go b/cloud/pkg/controllermanager/edgeapplication/overridemanager/argsoverrider.go new file mode 100644 index 000000000..ceb8b3691 --- /dev/null +++ b/cloud/pkg/controllermanager/edgeapplication/overridemanager/argsoverrider.go @@ -0,0 +1,31 @@ +/* +CHANGELOG +KubeEdge Authors: +- This File is drived from github.com/karmada-io/karmada/pkg/util/overridemanager/argsoverride.go +- refactor argsOverrider as a struct that implements the Overrider interface +*/ +package overridemanager + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/klog/v2" +) + +type ArgsOverrider struct{} + +func (o *ArgsOverrider) ApplyOverrides(rawObj *unstructured.Unstructured, overriders OverriderInfo) error { + argsOverriders := overriders.Overriders.ArgsOverriders + for index := range argsOverriders { + patches, err := buildCommandArgsPatches(ArgsString, rawObj, &argsOverriders[index]) + if err != nil { + return err + } + + klog.V(4).Infof("Parsed JSON patches by argsOverriders(%+v): %+v", argsOverriders[index], patches) + if err = applyJSONPatch(rawObj, patches); err != nil { + return err + } + } + + return nil +} diff --git a/cloud/pkg/controllermanager/edgeapplication/overridemanager/commandoverrider.go b/cloud/pkg/controllermanager/edgeapplication/overridemanager/commandoverrider.go new file mode 100644 index 000000000..bbdd12753 --- /dev/null +++ b/cloud/pkg/controllermanager/edgeapplication/overridemanager/commandoverrider.go @@ -0,0 +1,136 @@ +/* +CHANGELOG +KubeEdge Authors: +- This File is drived from github.com/karmada-io/karmada/pkg/util/overridemanager/commandoverride.go +- refactor commandOverrider as a struct that implements the Overrider interface +*/ +package overridemanager + +import ( + "fmt" + "strings" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/klog/v2" + + "github.com/kubeedge/kubeedge/pkg/apis/apps/v1alpha1" +) + +type CommandOverrider struct{} + +func (o *CommandOverrider) ApplyOverrides(rawObj *unstructured.Unstructured, overriders OverriderInfo) error { + commandOverriders := overriders.Overriders.CommandOverriders + for index := range commandOverriders { + patches, err := buildCommandArgsPatches(CommandString, rawObj, &commandOverriders[index]) + if err != nil { + return err + } + + klog.V(4).Infof("Parsed JSON patches by commandOverriders(%+v): %+v", commandOverriders[index], patches) + if err = applyJSONPatch(rawObj, patches); err != nil { + return err + } + } + + return nil +} + +// buildCommandArgsPatches build JSON patches for the resource object according to override declaration. +func buildCommandArgsPatches(target string, rawObj *unstructured.Unstructured, commandRunOverrider *v1alpha1.CommandArgsOverrider) ([]overrideOption, error) { + switch rawObj.GetKind() { + case PodKind: + return buildCommandArgsPatchesWithPath(target, "spec/containers", rawObj, commandRunOverrider) + case ReplicaSetKind: + fallthrough + case DeploymentKind: + fallthrough + case DaemonSetKind: + fallthrough + case JobKind: + fallthrough + case StatefulSetKind: + return buildCommandArgsPatchesWithPath(target, "spec/template/spec/containers", rawObj, commandRunOverrider) + } + return nil, nil +} +func buildCommandArgsPatchesWithPath(target string, specContainersPath string, rawObj *unstructured.Unstructured, commandRunOverrider *v1alpha1.CommandArgsOverrider) ([]overrideOption, error) { + patches := make([]overrideOption, 0) + containers, ok, err := unstructured.NestedSlice(rawObj.Object, strings.Split(specContainersPath, pathSplit)...) + if err != nil { + return nil, fmt.Errorf("failed to retrieves path(%s) from rawObj, error: %v", specContainersPath, err) + } + if !ok || len(containers) == 0 { + return nil, nil + } + klog.V(4).Infof("buildCommandArgsPatchesWithPath containers info (%+v)", containers) + for index, container := range containers { + if container.(map[string]interface{})["name"] == commandRunOverrider.ContainerName { + commandArgsPath := fmt.Sprintf("/%s/%d/%s", specContainersPath, index, target) + commandArgsValue := make([]string, 0) + var patch overrideOption + // if target is nil, to add new [target] + if container.(map[string]interface{})[target] == nil { + patch, _ = acquireAddOverrideOption(commandArgsPath, commandRunOverrider) + } else { + for _, val := range container.(map[string]interface{})[target].([]interface{}) { + commandArgsValue = append(commandArgsValue, fmt.Sprintf("%s", val)) + } + patch, _ = acquireReplaceOverrideOption(commandArgsPath, commandArgsValue, commandRunOverrider) + } + + klog.V(4).Infof("[buildCommandArgsPatchesWithPath] containers patch info (%+v)", patch) + patches = append(patches, patch) + } + } + return patches, nil +} + +func acquireAddOverrideOption(commandArgsPath string, commandOverrider *v1alpha1.CommandArgsOverrider) (overrideOption, error) { + if !strings.HasPrefix(commandArgsPath, pathSplit) { + return overrideOption{}, fmt.Errorf("internal error: [acquireCommandOverrideOption] commandRunPath should be start with / character") + } + newCommandArgs := overrideCommandArgs([]string{}, commandOverrider) + return overrideOption{ + Op: string(v1alpha1.OverriderOpAdd), + Path: commandArgsPath, + Value: newCommandArgs, + }, nil +} + +func acquireReplaceOverrideOption(commandArgsPath string, commandArgsValue []string, commandOverrider *v1alpha1.CommandArgsOverrider) (overrideOption, error) { + if !strings.HasPrefix(commandArgsPath, pathSplit) { + return overrideOption{}, fmt.Errorf("internal error: [acquireCommandOverrideOption] commandRunPath should be start with / character") + } + newCommandArgs := overrideCommandArgs(commandArgsValue, commandOverrider) + return overrideOption{ + Op: string(v1alpha1.OverriderOpReplace), + Path: commandArgsPath, + Value: newCommandArgs, + }, nil +} + +func overrideCommandArgs(curCommandArgs []string, commandArgsOverrider *v1alpha1.CommandArgsOverrider) []string { + var newCommandArgs []string + switch commandArgsOverrider.Operator { + case v1alpha1.OverriderOpAdd: + newCommandArgs = append(curCommandArgs, commandArgsOverrider.Value...) + case v1alpha1.OverriderOpRemove: + newCommandArgs = commandArgsRemove(curCommandArgs, commandArgsOverrider.Value) + default: + newCommandArgs = curCommandArgs + klog.V(4).Infof("[overrideCommandArgs], op: %s , op not supported, ignored.", v1alpha1.OverriderOpRemove) + } + return newCommandArgs +} + +func commandArgsRemove(curCommandArgs []string, removeValues []string) []string { + newCommandArgs := make([]string, 0, len(curCommandArgs)) + currentSet := sets.NewString(removeValues...) + for _, val := range curCommandArgs { + if !currentSet.Has(val) { + newCommandArgs = append(newCommandArgs, val) + } + } + return newCommandArgs +} diff --git a/cloud/pkg/controllermanager/edgeapplication/overridemanager/constants.go b/cloud/pkg/controllermanager/edgeapplication/overridemanager/constants.go index f4bb7d9fb..3f95dce9d 100644 --- a/cloud/pkg/controllermanager/edgeapplication/overridemanager/constants.go +++ b/cloud/pkg/controllermanager/edgeapplication/overridemanager/constants.go @@ -21,3 +21,16 @@ const ( // DaemonSetKind indicates the target resource is a daemonset DaemonSetKind = "DaemonSet" ) + +const ( + pathSplit = "/" + podSpecPrefix = "/spec" + podTemplatePrefix = "/spec/template/spec" +) + +const ( + // CommandString command string + CommandString = "command" + // ArgsString args string + ArgsString = "args" +) diff --git a/cloud/pkg/controllermanager/edgeapplication/overridemanager/imageoverrider.go b/cloud/pkg/controllermanager/edgeapplication/overridemanager/imageoverrider.go index e4d1e9dc7..5e6dbb31a 100644 --- a/cloud/pkg/controllermanager/edgeapplication/overridemanager/imageoverrider.go +++ b/cloud/pkg/controllermanager/edgeapplication/overridemanager/imageoverrider.go @@ -19,12 +19,6 @@ import ( appsv1alpha1 "github.com/kubeedge/kubeedge/pkg/apis/apps/v1alpha1" ) -const ( - pathSplit = "/" - podSpecPrefix = "/spec" - podTemplatePrefix = "/spec/template/spec" -) - type ImageOverrider struct{} var _ Overrider = &ImageOverrider{} |
