KubeOS: update to new release 1.0.5

update KubeOS to v1.0.5

Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
This commit is contained in:
Yuhang Wei 2024-01-10 11:50:47 +08:00
parent db4b835145
commit 07641b4290
28 changed files with 153 additions and 9018 deletions

View File

@ -1,479 +0,0 @@
From 790d53dc581874575aef1777122856a59bcdbf8b Mon Sep 17 00:00:00 2001
From: liyuanr <liyuanrong1@huawei.com>
Date: Thu, 3 Aug 2023 22:18:23 +0800
Subject: [PATCH 01/17] KubeOS:add unit tests of containerd and docker,modify
code for cleancode
Add unit tests of using containerd or docker to upgrade.
Modify code for cleancode and fix issue of ctr images pull
Signed-off-by: liyuanr <liyuanrong1@huawei.com>
---
cmd/agent/server/containerd_image.go | 8 +-
cmd/agent/server/containerd_image_test.go | 139 ++++++++++++++++++++++
cmd/agent/server/docker_image.go | 2 +-
cmd/agent/server/docker_image_test.go | 88 ++++++++++++--
cmd/agent/server/utils.go | 102 ++++++++--------
5 files changed, 272 insertions(+), 67 deletions(-)
create mode 100644 cmd/agent/server/containerd_image_test.go
diff --git a/cmd/agent/server/containerd_image.go b/cmd/agent/server/containerd_image.go
index f180fb5..fd61274 100644
--- a/cmd/agent/server/containerd_image.go
+++ b/cmd/agent/server/containerd_image.go
@@ -23,9 +23,7 @@ import (
pb "openeuler.org/KubeOS/cmd/agent/api"
)
-var (
- defaultNamespace = "k8s.io"
-)
+const defaultNamespace = "k8s.io"
type conImageHandler struct{}
@@ -56,7 +54,7 @@ func (c conImageHandler) getRootfsArchive(req *pb.UpdateRequest, neededPath prep
}
} else {
containerdCommand = "ctr"
- if err := runCommand("ctr", "-n", defaultNamespace, "images", "pull", "--host-dir",
+ if err := runCommand("ctr", "-n", defaultNamespace, "images", "pull", "--hosts-dir",
"/etc/containerd/certs.d", imageName); err != nil {
return "", err
}
@@ -76,7 +74,7 @@ func (c conImageHandler) getRootfsArchive(req *pb.UpdateRequest, neededPath prep
return "", err
}
defer checkAndCleanMount(mountPath)
- if err := copyFile(neededPath.tarPath, mountPath+"/"+rootfsArchive); err != nil {
+ if err := copyFile(neededPath.tarPath, mountPath+"/"+neededPath.rootfsFile); err != nil {
return "", err
}
return "", nil
diff --git a/cmd/agent/server/containerd_image_test.go b/cmd/agent/server/containerd_image_test.go
new file mode 100644
index 0000000..d7133c3
--- /dev/null
+++ b/cmd/agent/server/containerd_image_test.go
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
+ * KubeOS is licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+// Package server implements server of os-agent and listener of os-agent server. The server uses gRPC interface.
+package server
+
+import (
+ "os"
+ "testing"
+
+ "github.com/agiledragon/gomonkey/v2"
+ pb "openeuler.org/KubeOS/cmd/agent/api"
+)
+
+func Test_conImageHandler_downloadImage(t *testing.T) {
+ type args struct {
+ req *pb.UpdateRequest
+ }
+ tests := []struct {
+ name string
+ c conImageHandler
+ args args
+ want string
+ wantErr bool
+ }{
+
+ {
+ name: "pullImageError",
+ c: conImageHandler{},
+ args: args{
+ req: &pb.UpdateRequest{ContainerImage: "testError"},
+ },
+ want: "",
+ wantErr: true,
+ },
+ {
+ name: "checkSumError",
+ c: conImageHandler{},
+ args: args{
+ req: &pb.UpdateRequest{ContainerImage: "docker.io/library/hello-world:latest"},
+ },
+ want: "",
+ wantErr: true,
+ },
+ {
+ name: "normal",
+ c: conImageHandler{},
+ args: args{
+ req: &pb.UpdateRequest{
+ ContainerImage: "docker.io/library/hello-world:latest",
+ },
+ },
+ want: "update-test1/upadte.img",
+ wantErr: false,
+ },
+ }
+ patchPrepareEnv := gomonkey.ApplyFunc(prepareEnv, func() (preparePath, error) {
+ return preparePath{updatePath: "update-test1/",
+ mountPath: "update-test1/mountPath",
+ tarPath: "update-test1/mountPath/hello",
+ imagePath: "update-test1/upadte.img",
+ rootfsFile: "hello"}, nil
+ })
+ defer patchPrepareEnv.Reset()
+ patchCreateOSImage := gomonkey.ApplyFunc(createOSImage, func(neededPath preparePath) (string, error) {
+ return "update-test1/upadte.img", nil
+ })
+ defer patchCreateOSImage.Reset()
+
+ if err := os.MkdirAll("update-test1/mountPath", os.ModePerm); err != nil {
+ t.Errorf("create test dir error = %v", err)
+ return
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ c := conImageHandler{}
+ if tt.name == "normal" {
+ imageDigests, err := getOCIImageDigest("crictl", "docker.io/library/hello-world:latest")
+ if err != nil {
+ t.Errorf("conImageHandler.getRootfsArchive() get oci image digests error = %v", err)
+ }
+ tt.args.req.CheckSum = imageDigests
+ }
+ got, err := c.downloadImage(tt.args.req)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("conImageHandler.downloadImage() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if got != tt.want {
+ t.Errorf("conImageHandler.downloadImage() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+ defer func() {
+ if err := runCommand("crictl", "rmi", "docker.io/library/hello-world:latest"); err != nil {
+ t.Errorf("remove kubeos-temp container error = %v", err)
+ }
+ if err := os.RemoveAll("update-test1"); err != nil {
+ t.Errorf("remove update-test error = %v", err)
+ }
+ }()
+}
+
+func Test_copyFile(t *testing.T) {
+ type args struct {
+ dstFileName string
+ srcFileName string
+ }
+ tests := []struct {
+ name string
+ args args
+ wantErr bool
+ }{
+ {
+ name: "srcFileNotExist",
+ args: args{
+ dstFileName: "bbb.txt",
+ srcFileName: "aaa.txt",
+ },
+ wantErr: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if err := copyFile(tt.args.dstFileName, tt.args.srcFileName); (err != nil) != tt.wantErr {
+ t.Errorf("copyFile() error = %v, wantErr %v", err, tt.wantErr)
+ }
+ })
+ }
+}
diff --git a/cmd/agent/server/docker_image.go b/cmd/agent/server/docker_image.go
index 23e596b..0b6ee35 100644
--- a/cmd/agent/server/docker_image.go
+++ b/cmd/agent/server/docker_image.go
@@ -61,7 +61,7 @@ func (d dockerImageHandler) getRootfsArchive(req *pb.UpdateRequest, neededPath p
if err != nil {
return "", err
}
- if err := runCommand("docker", "cp", containerId+":/"+rootfsArchive, neededPath.updatePath); err != nil {
+ if err := runCommand("docker", "cp", containerId+":/"+neededPath.rootfsFile, neededPath.updatePath); err != nil {
return "", err
}
defer func() {
diff --git a/cmd/agent/server/docker_image_test.go b/cmd/agent/server/docker_image_test.go
index 9987939..2dbf337 100644
--- a/cmd/agent/server/docker_image_test.go
+++ b/cmd/agent/server/docker_image_test.go
@@ -17,38 +17,102 @@ import (
"os"
"testing"
+ "github.com/agiledragon/gomonkey/v2"
pb "openeuler.org/KubeOS/cmd/agent/api"
)
-func TestpullOSImage(t *testing.T) {
+func Test_dockerImageHandler_downloadImage(t *testing.T) {
type args struct {
req *pb.UpdateRequest
}
- os.Mkdir("/persist", os.ModePerm)
tests := []struct {
name string
+ d dockerImageHandler
args args
want string
wantErr bool
}{
- {name: "pull image error", args: args{req: &pb.UpdateRequest{
- DockerImage: "test",
- }}, want: "", wantErr: true},
- {name: "normal", args: args{req: &pb.UpdateRequest{
- DockerImage: "centos",
- }}, want: "/persist/update.img", wantErr: false},
+ {
+ name: "pullImageError",
+ d: dockerImageHandler{},
+ args: args{
+ req: &pb.UpdateRequest{ContainerImage: "testError"},
+ },
+ want: "",
+ wantErr: true,
+ },
+
+ {
+ name: "checkSumError",
+ d: dockerImageHandler{},
+ args: args{
+ req: &pb.UpdateRequest{ContainerImage: "hello-world", CheckSum: "aaaaaa"},
+ },
+ want: "",
+ wantErr: true,
+ },
+
+ {
+ name: "normal",
+ d: dockerImageHandler{},
+ args: args{
+ req: &pb.UpdateRequest{ContainerImage: "hello-world"},
+ },
+ want: "update-test/upadte.img",
+ wantErr: false,
+ },
+ }
+ patchPrepareEnv := gomonkey.ApplyFunc(prepareEnv, func() (preparePath, error) {
+ return preparePath{updatePath: "update-test/",
+ mountPath: "update-test/mountPath",
+ tarPath: "update-test/mountPath/hello",
+ imagePath: "update-test/upadte.img",
+ rootfsFile: "hello"}, nil
+ })
+ defer patchPrepareEnv.Reset()
+
+ patchCreateOSImage := gomonkey.ApplyFunc(createOSImage, func(neededPath preparePath) (string, error) {
+ return "update-test/upadte.img", nil
+ })
+ defer patchCreateOSImage.Reset()
+
+ if err := os.MkdirAll("update-test/mountPath", os.ModePerm); err != nil {
+ t.Errorf("create test dir error = %v", err)
+ return
}
+
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- got, err := pullOSImage(tt.args.req)
+ if tt.name == "normal" {
+ _, err := runCommandWithOut("docker", "create", "--name", "kubeos-temp", "hello-world")
+ if err != nil {
+ t.Errorf("Test_dockerImageHandler_getRootfsArchive create container error = %v", err)
+ return
+ }
+ imageDigests, err := getOCIImageDigest("docker", "hello-world")
+
+ if err != nil {
+ t.Errorf("Test_dockerImageHandler_getRootfsArchive get oci image digests error = %v", err)
+ }
+ tt.args.req.CheckSum = imageDigests
+ }
+ d := dockerImageHandler{}
+ got, err := d.downloadImage(tt.args.req)
if (err != nil) != tt.wantErr {
- t.Errorf("pullOSImage() error = %v, wantErr %v", err, tt.wantErr)
+ t.Errorf("dockerImageHandler.downloadImage() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
- t.Errorf("pullOSImage() = %v, want %v", got, tt.want)
+ t.Errorf("dockerImageHandler.downloadImage() = %v, want %v", got, tt.want)
}
})
}
- defer os.RemoveAll("/persist")
+ defer func() {
+ if err := runCommand("docker", "rmi", "hello-world"); err != nil {
+ t.Errorf("remove kubeos-temp container error = %v", err)
+ }
+ if err := os.RemoveAll("update-test"); err != nil {
+ t.Errorf("remove update-test error = %v", err)
+ }
+ }()
}
diff --git a/cmd/agent/server/utils.go b/cmd/agent/server/utils.go
index c8a72c3..7134d74 100644
--- a/cmd/agent/server/utils.go
+++ b/cmd/agent/server/utils.go
@@ -31,10 +31,7 @@ import (
const (
needGBSize = 3 // the max size of update files needed
// KB is 1024 B
- KB = 1024
-)
-
-var (
+ KB = 1024
rootfsArchive = "os.tar"
updateDir = "KubeOS-Update"
mountDir = "kubeos-update"
@@ -51,6 +48,7 @@ type preparePath struct {
mountPath string
tarPath string
imagePath string
+ rootfsFile string
}
func runCommand(name string, args ...string) error {
@@ -192,9 +190,10 @@ func prepareEnv() (preparePath, error) {
if err := checkDiskSize(needGBSize, PersistDir); err != nil {
return preparePath{}, err
}
+ rootfsFile := rootfsArchive
updatePath := splicePath(PersistDir, updateDir)
mountPath := splicePath(updatePath, mountDir)
- tarPath := splicePath(updatePath, rootfsArchive)
+ tarPath := splicePath(updatePath, rootfsFile)
imagePath := splicePath(PersistDir, osImageName)
if err := cleanSpace(updatePath, mountPath, imagePath); err != nil {
@@ -208,6 +207,7 @@ func prepareEnv() (preparePath, error) {
mountPath: mountPath,
tarPath: tarPath,
imagePath: imagePath,
+ rootfsFile: rootfsFile,
}
return upgradePath, nil
}
@@ -284,50 +284,9 @@ func checkFileExist(path string) (bool, error) {
}
func checkOCIImageDigestMatch(containerRuntime string, imageName string, checkSum string) error {
- var cmdOutput string
- var err error
- switch containerRuntime {
- case "crictl":
- cmdOutput, err = runCommandWithOut("crictl", "inspecti", "--output", "go-template",
- "--template", "{{.status.repoDigests}}", imageName)
- if err != nil {
- return err
- }
- case "docker":
- cmdOutput, err = runCommandWithOut("docker", "inspect", "--format", "{{.RepoDigests}}", imageName)
- if err != nil {
- return err
- }
- case "ctr":
- cmdOutput, err = runCommandWithOut("ctr", "-n", "k8s.io", "images", "ls", "name=="+imageName)
- if err != nil {
- return err
- }
- // after Fields, we get slice like [REF TYPE DIGEST SIZE PLATFORMS LABELS x x x x x x]
- // the digest is the position 8 element
- imageDigest := strings.Split(strings.Fields(cmdOutput)[8], ":")[1]
- if imageDigest != checkSum {
- logrus.Errorln("checkSumFailed ", imageDigest, " mismatch to ", checkSum)
- return fmt.Errorf("checkSumFailed %s mismatch to %s", imageDigest, checkSum)
- }
- return nil
- default:
- logrus.Errorln("containerRuntime ", containerRuntime, " cannot be recognized")
- return fmt.Errorf("containerRuntime %s cannot be recognized", containerRuntime)
- }
- // cmdOutput format is as follows:
- // [imageRepository/imageName:imageTag@sha256:digests]
- // parse the output and get digest
- var imageDigests string
- outArray := strings.Split(cmdOutput, "@")
- if strings.HasPrefix(outArray[len(outArray)-1], "sha256") {
- pasredArray := strings.Split(strings.TrimSuffix(outArray[len(outArray)-1], "]"), ":")
- // 2 is the expected length of the array after dividing "imageName:imageTag@sha256:digests" based on ':'
- rightLen := 2
- if len(pasredArray) == rightLen {
- digestIndex := 1 // 1 is the index of digest data in pasredArray
- imageDigests = pasredArray[digestIndex]
- }
+ imageDigests, err := getOCIImageDigest(containerRuntime, imageName)
+ if err != nil {
+ return err
}
if imageDigests == "" {
logrus.Errorln("error when get ", imageName, " digests")
@@ -367,3 +326,48 @@ func isValidImageName(image string) error {
}
return nil
}
+
+func getOCIImageDigest(containerRuntime string, imageName string) (string, error) {
+ var cmdOutput string
+ var err error
+ var imageDigests string
+ switch containerRuntime {
+ case "crictl":
+ cmdOutput, err = runCommandWithOut("crictl", "inspecti", "--output", "go-template",
+ "--template", "{{.status.repoDigests}}", imageName)
+ if err != nil {
+ return "", err
+ }
+ case "docker":
+ cmdOutput, err = runCommandWithOut("docker", "inspect", "--format", "{{.RepoDigests}}", imageName)
+ if err != nil {
+ return "", err
+ }
+ case "ctr":
+ cmdOutput, err = runCommandWithOut("ctr", "-n", "k8s.io", "images", "ls", "name=="+imageName)
+ if err != nil {
+ return "", err
+ }
+ // after Fields, we get slice like [REF TYPE DIGEST SIZE PLATFORMS LABELS x x x x x x]
+ // the digest is the position 8 element
+ imageDigest := strings.Split(strings.Fields(cmdOutput)[8], ":")[1]
+ return imageDigest, nil
+ default:
+ logrus.Errorln("containerRuntime ", containerRuntime, " cannot be recognized")
+ return "", fmt.Errorf("containerRuntime %s cannot be recognized", containerRuntime)
+ }
+ // cmdOutput format is as follows:
+ // [imageRepository/imageName:imageTag@sha256:digests]
+ // parse the output and get digest
+ outArray := strings.Split(cmdOutput, "@")
+ if strings.HasPrefix(outArray[len(outArray)-1], "sha256") {
+ pasredArray := strings.Split(strings.TrimSuffix(outArray[len(outArray)-1], "]"), ":")
+ // 2 is the expected length of the array after dividing "imageName:imageTag@sha256:digests" based on ':'
+ rightLen := 2
+ if len(pasredArray) == rightLen {
+ digestIndex := 1 // 1 is the index of digest data in pasredArray
+ imageDigests = pasredArray[digestIndex]
+ }
+ }
+ return imageDigests, nil
+}
--
2.39.0

View File

@ -0,0 +1,56 @@
From 6e62adfa80c33d9b1fc4445487cc15e721db07bc Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Wed, 10 Jan 2024 15:53:26 +0800
Subject: [PATCH] build(rust os-agent): remove useless dependency
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
KubeOS-Rust/Cargo.lock | 11 -----------
KubeOS-Rust/manager/Cargo.toml | 2 +-
2 files changed, 1 insertion(+), 12 deletions(-)
diff --git a/KubeOS-Rust/Cargo.lock b/KubeOS-Rust/Cargo.lock
index 4b7fc12..2087339 100644
--- a/KubeOS-Rust/Cargo.lock
+++ b/KubeOS-Rust/Cargo.lock
@@ -199,16 +199,6 @@ dependencies = [
"serde_json",
]
-[[package]]
-name = "colored"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
-dependencies = [
- "lazy_static",
- "windows-sys",
-]
-
[[package]]
name = "core-foundation"
version = "0.9.3"
@@ -1209,7 +1199,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80f9fece9bd97ab74339fe19f4bcaf52b76dcc18e5364c7977c1838f76b38de9"
dependencies = [
"assert-json-diff",
- "colored",
"httparse",
"lazy_static",
"log",
diff --git a/KubeOS-Rust/manager/Cargo.toml b/KubeOS-Rust/manager/Cargo.toml
index 40672cc..9431fba 100644
--- a/KubeOS-Rust/manager/Cargo.toml
+++ b/KubeOS-Rust/manager/Cargo.toml
@@ -8,7 +8,7 @@ version = "0.1.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dev-dependencies]
mockall = { version = "=0.11.3" }
-mockito = { version = "0.31.1" }
+mockito = { version = "0.31.1", default-features = false }
predicates = { version = "=2.0.1" }
tempfile = { version = "3.6.0" }
--
2.34.1

View File

@ -1,346 +0,0 @@
From 64e36143591c014609fc517bcd6ee0f3ae1087fc Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Thu, 3 Aug 2023 11:01:22 +0800
Subject: [PATCH 02/17] KubeOS: refactor assignUpgrade function the
assignUpgrade function is refactored for maintainability replace
"osinstance-node" to variable
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/operator/controllers/os_controller.go | 73 ++++++-----
.../controllers/os_controller_test.go | 121 +++++++++++++++++-
cmd/proxy/controllers/os_controller.go | 2 +-
cmd/proxy/controllers/os_controller_test.go | 9 ++
pkg/values/values.go | 6 +-
5 files changed, 176 insertions(+), 35 deletions(-)
diff --git a/cmd/operator/controllers/os_controller.go b/cmd/operator/controllers/os_controller.go
index f86a0b2..620739b 100644
--- a/cmd/operator/controllers/os_controller.go
+++ b/cmd/operator/controllers/os_controller.go
@@ -109,7 +109,7 @@ func (r *OSReconciler) SetupWithManager(mgr ctrl.Manager) error {
func (r *OSReconciler) DeleteOSInstance(e event.DeleteEvent, q workqueue.RateLimitingInterface) {
ctx := context.Background()
hostname := e.Object.GetName()
- labelSelector := labels.SelectorFromSet(labels.Set{"upgrade.openeuler.org/osinstance-node": hostname})
+ labelSelector := labels.SelectorFromSet(labels.Set{values.LabelOSinstance: hostname})
osInstanceList := &upgradev1.OSInstanceList{}
if err := r.List(ctx, osInstanceList, client.MatchingLabelsSelector{Selector: labelSelector}); err != nil {
log.Error(err, "unable to list osInstances")
@@ -157,12 +157,23 @@ func assignUpgrade(ctx context.Context, r common.ReadStatusWriter, os upgradev1.
return false, err
}
- nodes, err := getNodes(ctx, r, limit+1, *requirement, *reqMaster) // one more to see if all node updated
+ nodes, err := getNodes(ctx, r, limit+1, *requirement, *reqMaster) // one more to see if all nodes updated
if err != nil {
return false, err
}
- var count = 0
+ // Upgrade OS for selected nodes
+ count, err := upgradeNodes(ctx, r, &os, nodes, limit)
+ if err != nil {
+ return false, err
+ }
+
+ return count >= limit, nil
+}
+
+func upgradeNodes(ctx context.Context, r common.ReadStatusWriter, os *upgradev1.OS,
+ nodes []corev1.Node, limit int) (int, error) {
+ var count int
for _, node := range nodes {
if count >= limit {
break
@@ -170,43 +181,45 @@ func assignUpgrade(ctx context.Context, r common.ReadStatusWriter, os upgradev1.
osVersionNode := node.Status.NodeInfo.OSImage
if os.Spec.OSVersion != osVersionNode {
var osInstance upgradev1.OSInstance
- if err = r.Get(ctx, types.NamespacedName{Namespace: nameSpace, Name: node.Name}, &osInstance); err != nil {
+ if err := r.Get(ctx, types.NamespacedName{Namespace: os.GetObjectMeta().GetNamespace(), Name: node.Name}, &osInstance); err != nil {
if err = client.IgnoreNotFound(err); err != nil {
log.Error(err, "failed to get osInstance "+node.Name)
- return false, err
+ return count, err
}
continue
}
+ updateNodeAndOSins(ctx, r, os, &node, &osInstance)
count++
- node.Labels[values.LabelUpgrading] = ""
- expUpVersion := os.Spec.UpgradeConfigs.Version
- osiUpVersion := osInstance.Spec.UpgradeConfigs.Version
- if osiUpVersion != expUpVersion {
- osInstance.Spec.UpgradeConfigs = os.Spec.UpgradeConfigs
- }
- expSysVersion := os.Spec.SysConfigs.Version
- osiSysVersion := osInstance.Spec.SysConfigs.Version
- if osiSysVersion != expSysVersion {
- osInstance.Spec.SysConfigs = os.Spec.SysConfigs
- for i, config := range osInstance.Spec.SysConfigs.Configs {
- if config.Model == "grub.cmdline.current" {
- osInstance.Spec.SysConfigs.Configs[i].Model = "grub.cmdline.next"
- }
- if config.Model == "grub.cmdline.next" {
- osInstance.Spec.SysConfigs.Configs[i].Model = "grub.cmdline.current"
- }
- }
- }
- osInstance.Spec.NodeStatus = values.NodeStatusUpgrade.String()
- if err = r.Update(ctx, &osInstance); err != nil {
- log.Error(err, "unable to update", "osInstance", osInstance.Name)
+ }
+ }
+ return count, nil
+}
+
+func updateNodeAndOSins(ctx context.Context, r common.ReadStatusWriter, os *upgradev1.OS,
+ node *corev1.Node, osInstance *upgradev1.OSInstance) {
+ if osInstance.Spec.UpgradeConfigs.Version != os.Spec.UpgradeConfigs.Version {
+ osInstance.Spec.UpgradeConfigs = os.Spec.UpgradeConfigs
+ }
+ if osInstance.Spec.SysConfigs.Version != os.Spec.SysConfigs.Version {
+ osInstance.Spec.SysConfigs = os.Spec.SysConfigs
+ // exchange "grub.cmdline.current" and "grub.cmdline.next"
+ for i, config := range osInstance.Spec.SysConfigs.Configs {
+ if config.Model == "grub.cmdline.current" {
+ osInstance.Spec.SysConfigs.Configs[i].Model = "grub.cmdline.next"
}
- if err = r.Update(ctx, &node); err != nil {
- log.Error(err, "unable to label", "node", node.Name)
+ if config.Model == "grub.cmdline.next" {
+ osInstance.Spec.SysConfigs.Configs[i].Model = "grub.cmdline.current"
}
}
}
- return count >= limit, nil
+ osInstance.Spec.NodeStatus = values.NodeStatusUpgrade.String()
+ if err := r.Update(ctx, osInstance); err != nil {
+ log.Error(err, "unable to update", "osInstance", osInstance.Name)
+ }
+ node.Labels[values.LabelUpgrading] = ""
+ if err := r.Update(ctx, node); err != nil {
+ log.Error(err, "unable to label", "node", node.Name)
+ }
}
func assignConfig(ctx context.Context, r common.ReadStatusWriter, sysConfigs upgradev1.SysConfigs,
diff --git a/cmd/operator/controllers/os_controller_test.go b/cmd/operator/controllers/os_controller_test.go
index 30a773c..a391005 100644
--- a/cmd/operator/controllers/os_controller_test.go
+++ b/cmd/operator/controllers/os_controller_test.go
@@ -134,6 +134,9 @@ var _ = Describe("OsController", func() {
ObjectMeta: metav1.ObjectMeta{
Name: node1Name,
Namespace: testNamespace,
+ Labels: map[string]string{
+ values.LabelOSinstance: node1Name,
+ },
},
Spec: upgradev1.OSInstanceSpec{
SysConfigs: upgradev1.SysConfigs{
@@ -189,7 +192,7 @@ var _ = Describe("OsController", func() {
}, timeout, interval).Should(BeTrue())
Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v1"))
- time.Sleep(2 * time.Second) // sleep a while to make sure Reconcile finished
+ time.Sleep(1 * time.Second) // sleep a while to make sure Reconcile finished
osInsCRLookupKey = types.NamespacedName{Name: node1Name, Namespace: testNamespace}
createdOSIns = &upgradev1.OSInstance{}
Eventually(func() bool {
@@ -301,7 +304,7 @@ var _ = Describe("OsController", func() {
}, timeout, interval).Should(BeTrue())
Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v1"))
- time.Sleep(2 * time.Second) // sleep a while to make sure Reconcile finished
+ time.Sleep(1 * time.Second) // sleep a while to make sure Reconcile finished
configedOSIns := &upgradev1.OSInstance{}
Eventually(func() bool {
err := k8sClient.Get(ctx, osInsCRLookupKey, configedOSIns)
@@ -388,4 +391,118 @@ var _ = Describe("OsController", func() {
})
})
+ Context("When we want to upgrade and do sysconfigs which contain grub.cmd.current and .next", func() {
+ It("Should exchange .current and .next", func() {
+ ctx := context.Background()
+
+ // create Node
+ node1Name = "test-node-" + uuid.New().String()
+ node1 := &v1.Node{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node1Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ "beta.kubernetes.io/os": "linux",
+ },
+ },
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: "v1",
+ Kind: "Node",
+ },
+ Status: v1.NodeStatus{
+ NodeInfo: v1.NodeSystemInfo{
+ OSImage: "KubeOS v1",
+ },
+ },
+ }
+ err := k8sClient.Create(ctx, node1)
+ Expect(err).ToNot(HaveOccurred())
+ existingNode := &v1.Node{}
+ Eventually(func() bool {
+ err := k8sClient.Get(context.Background(),
+ types.NamespacedName{Name: node1Name, Namespace: testNamespace}, existingNode)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+
+ // create OSInstance
+ OSIns := &upgradev1.OSInstance{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "OSInstance",
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node1Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ values.LabelOSinstance: node1Name,
+ },
+ },
+ Spec: upgradev1.OSInstanceSpec{
+ SysConfigs: upgradev1.SysConfigs{
+ Version: "v1",
+ Configs: []upgradev1.SysConfig{},
+ },
+ UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}},
+ },
+ }
+ Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
+
+ // Check that the corresponding OSIns CR has been created
+ osInsCRLookupKey := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
+ createdOSIns := &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node1Name))
+
+ // create OS CR
+ OS := &upgradev1.OS{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
+ Kind: "OS",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: OSName,
+ Namespace: testNamespace,
+ },
+ Spec: upgradev1.OSSpec{
+ OpsType: "upgrade",
+ MaxUnavailable: 3,
+ OSVersion: "KubeOS v2",
+ FlagSafe: true,
+ MTLS: false,
+ EvictPodForce: true,
+ SysConfigs: upgradev1.SysConfigs{
+ Version: "v2",
+ Configs: []upgradev1.SysConfig{
+ {Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}},
+ {Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}},
+ },
+ },
+ UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}},
+ },
+ }
+ Expect(k8sClient.Create(ctx, OS)).Should(Succeed())
+
+ // Check that the corresponding OS CR has been created
+ osCRLookupKey := types.NamespacedName{Name: OSName, Namespace: testNamespace}
+ createdOS := &upgradev1.OS{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osCRLookupKey, createdOS)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v2"))
+
+ time.Sleep(1 * time.Second) // sleep a while to make sure Reconcile finished
+ osInsCRLookupKey = types.NamespacedName{Name: node1Name, Namespace: testNamespace}
+ createdOSIns = &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOSIns.Spec.SysConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
+ Expect(createdOSIns.Spec.SysConfigs.Configs[1]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}}))
+ })
+ })
})
diff --git a/cmd/proxy/controllers/os_controller.go b/cmd/proxy/controllers/os_controller.go
index a17afac..b0b17e7 100644
--- a/cmd/proxy/controllers/os_controller.go
+++ b/cmd/proxy/controllers/os_controller.go
@@ -261,7 +261,7 @@ func checkOsiExist(ctx context.Context, r common.ReadStatusWriter, nameSpace str
Namespace: nameSpace,
Name: nodeName,
Labels: map[string]string{
- "upgrade.openeuler.org/osinstance-node": nodeName,
+ values.LabelOSinstance: nodeName,
},
},
}
diff --git a/cmd/proxy/controllers/os_controller_test.go b/cmd/proxy/controllers/os_controller_test.go
index ff12f64..e6cd5b7 100644
--- a/cmd/proxy/controllers/os_controller_test.go
+++ b/cmd/proxy/controllers/os_controller_test.go
@@ -110,6 +110,9 @@ var _ = Describe("OsController", func() {
ObjectMeta: metav1.ObjectMeta{
Name: node1Name,
Namespace: testNamespace,
+ Labels: map[string]string{
+ values.LabelOSinstance: node1Name,
+ },
},
Spec: upgradev1.OSInstanceSpec{
NodeStatus: values.NodeStatusConfig.String(),
@@ -245,6 +248,9 @@ var _ = Describe("OsController", func() {
ObjectMeta: metav1.ObjectMeta{
Name: node1Name,
Namespace: testNamespace,
+ Labels: map[string]string{
+ values.LabelOSinstance: node1Name,
+ },
},
Spec: upgradev1.OSInstanceSpec{
NodeStatus: values.NodeStatusUpgrade.String(),
@@ -426,6 +432,9 @@ var _ = Describe("OsController", func() {
return err == nil
}, timeout, interval).Should(BeTrue())
Expect(createdOSIns.Spec.NodeStatus).Should(Equal(values.NodeStatusIdle.String()))
+ hostname, ok := createdOSIns.ObjectMeta.Labels[values.LabelOSinstance]
+ Expect(ok).Should(BeTrue())
+ Expect(hostname).Should(Equal(node1Name))
})
})
diff --git a/pkg/values/values.go b/pkg/values/values.go
index 30261bd..f488ae5 100644
--- a/pkg/values/values.go
+++ b/pkg/values/values.go
@@ -23,8 +23,10 @@ const (
// LabelUpgrading is the key of the upgrading label for nodes
LabelUpgrading = "upgrade.openeuler.org/upgrading"
// LabelMaster is the key of the master-node label for nodes
- LabelMaster = "node-role.kubernetes.io/control-plane"
- defaultPeriod = 15 * time.Second
+ LabelMaster = "node-role.kubernetes.io/control-plane"
+ // LabelOSinstance is used to select the osinstance with the nodeName by label
+ LabelOSinstance = "upgrade.openeuler.org/osinstance-node"
+ defaultPeriod = 15 * time.Second
// OsiStatusName is param name of nodeStatus in osInstance
OsiStatusName = "nodestatus"
// UpgradeConfigName is param name of UpgradeConfig
--
2.39.0

View File

@ -1,75 +0,0 @@
From 470e190db2de92b65e7fa720864823e7245c51e9 Mon Sep 17 00:00:00 2001
From: liyuanr <liyuanrong1@huawei.com>
Date: Mon, 7 Aug 2023 19:09:18 +0800
Subject: [PATCH 03/17] KubeOS: fix the hostshell cannot obtain the lib
Fix the hostshell cannot obtain the lib
Signed-off-by: liyuanr <liyuanrong1@huawei.com>
---
cmd/admin-container/main.go | 40 +++++++++++++++++++++++++------------
1 file changed, 27 insertions(+), 13 deletions(-)
diff --git a/cmd/admin-container/main.go b/cmd/admin-container/main.go
index f6a7293..5fa0838 100644
--- a/cmd/admin-container/main.go
+++ b/cmd/admin-container/main.go
@@ -22,28 +22,42 @@ import (
"github.com/sirupsen/logrus"
)
+const (
+ bashPath = "/usr/bin/bash"
+ usrBin = "/usr/bin"
+ usrSbin = "/usr/sbin"
+ localBin = "/usr/local/bin"
+ localSbin = "/usr/local/sbin"
+ usrLib = "/usr/lib"
+ usrLib64 = "/usr/lib64"
+ lib = "/lib"
+ lib64 = "/lib64"
+ envPathPrefix = "PATH=$PATH:"
+ envLdLibrarPathPrefix = "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"
+)
+
func main() {
EUID := os.Geteuid()
rootEUID := 0 // 0 indicates that the process has the permission of the root user.
if EUID != rootEUID {
logrus.Error("please use root to run hostshell")
- return
+
}
PPID := os.Getppid()
rootFsPath := "/proc/" + strconv.Itoa(PPID) + "/root"
- bashPath := "/usr/bin/bash"
- usrBin := "/usr/bin"
- usrSbin := "/usr/sbin"
- localBin := "/usr/local/bin"
- localSbin := "/usr/local/sbin"
- paths := []string{usrBin, usrSbin, localBin, localSbin}
- for i, p := range paths {
- paths[i] = rootFsPath + p
- }
- path := "PATH=$PATH:" + strings.Join(paths, ":")
- lib := "LD_LIBRARY_PATH=/lib:/lib64:/usr/lib:/usr/lib64:$LD_LIBRARY_PATH"
+ path := concatenateEnvPath(rootFsPath, envPathPrefix, []string{usrBin, usrSbin, localBin, localSbin})
+ libPath := concatenateEnvPath(rootFsPath, envLdLibrarPathPrefix, []string{usrLib, usrLib64, lib, lib64})
if err := syscall.Exec("/usr/bin/nsenter", []string{"nsenter", "-t", "1", "-a",
- "env", "-i", path, lib, rootFsPath + bashPath}, os.Environ()); err != nil {
+ "env", "-i", path, libPath, rootFsPath + bashPath}, os.Environ()); err != nil {
logrus.Error("nsenter excute error", err)
}
}
+
+func concatenateEnvPath(prefix string, envVarPrefix string, paths []string) string {
+ for i, p := range paths {
+ paths[i] = prefix + p
+ }
+ pathLine := envVarPrefix + strings.Join(paths, ":")
+ pathEnv := os.ExpandEnv(pathLine)
+ return pathEnv
+}
--
2.39.0

File diff suppressed because it is too large Load Diff

View File

@ -1,155 +0,0 @@
From 5c5922a922f225a9ebc5f99a5008ddcf182b7da6 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Thu, 10 Aug 2023 17:24:50 +0800
Subject: [PATCH 05/17] KubeOS: fix validate image name bug fix the bug that
incorrectly granted illegal image names path:tag@sha256
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/agent/server/utils.go | 2 +-
cmd/agent/server/utils_test.go | 109 ++++++++++++++++++++++++++++++++-
2 files changed, 109 insertions(+), 2 deletions(-)
diff --git a/cmd/agent/server/utils.go b/cmd/agent/server/utils.go
index 7134d74..b42db18 100644
--- a/cmd/agent/server/utils.go
+++ b/cmd/agent/server/utils.go
@@ -316,7 +316,7 @@ func isCommandAvailable(name string) bool {
}
func isValidImageName(image string) error {
- pattern := `^((?:[\w.-]+)(?::\d+)?\/)*(?:[\w.-]+)(?::[\w_.-]+)?(?:@sha256:[a-fA-F0-9]+)?$`
+ pattern := `^((?:[\w.-]+)(?::\d+)?\/)*(?:[\w.-]+)((?::[\w_.-]+)?|(?:@sha256:[a-fA-F0-9]+)?)$`
regEx, err := regexp.Compile(pattern)
if err != nil {
return err
diff --git a/cmd/agent/server/utils_test.go b/cmd/agent/server/utils_test.go
index 89b2c3b..0796bce 100644
--- a/cmd/agent/server/utils_test.go
+++ b/cmd/agent/server/utils_test.go
@@ -56,10 +56,16 @@ func Test_install(t *testing.T) {
args args
wantErr bool
}{
- {name: "normal", args: args{imagePath: "aa.txt", side: "/dev/sda3", next: "A"}, wantErr: false},
+ {name: "normal uefi", args: args{imagePath: "aa.txt", side: "/dev/sda3", next: "A"}, wantErr: false},
+ {name: "normal legacy", args: args{imagePath: "aa.txt", side: "/dev/sda3", next: "A"}, wantErr: false},
}
patchRunCommand := gomonkey.ApplyFuncReturn(runCommand, nil)
defer patchRunCommand.Reset()
+ patchGetBootMode := gomonkey.ApplyFuncSeq(getBootMode, []gomonkey.OutputCell{
+ {Values: gomonkey.Params{"uefi", nil}},
+ {Values: gomonkey.Params{"legacy", nil}},
+ })
+ defer patchGetBootMode.Reset()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := install(tt.args.imagePath, tt.args.side, tt.args.next); (err != nil) != tt.wantErr {
@@ -219,3 +225,104 @@ func createTmpTarFile(tarPath string) (string, error) {
}
return tempFile.Name(), nil
}
+
+func Test_getBootMode(t *testing.T) {
+ tests := []struct {
+ name string
+ want string
+ wantErr bool
+ }{
+ {
+ name: "uefi",
+ want: "uefi",
+ wantErr: false,
+ },
+ {
+ name: "legacy",
+ want: "legacy",
+ wantErr: false,
+ },
+ }
+ patchOSStat := gomonkey.ApplyFuncSeq(os.Stat, []gomonkey.OutputCell{
+ {Values: gomonkey.Params{nil, nil}},
+ {Values: gomonkey.Params{nil, os.ErrNotExist}},
+ })
+ defer patchOSStat.Reset()
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := getBootMode()
+ if (err != nil) != tt.wantErr {
+ t.Errorf("getBootMode() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if got != tt.want {
+ t.Errorf("getBootMode() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func Test_isValidImageName(t *testing.T) {
+ type args struct {
+ image string
+ }
+ tests := []struct {
+ name string
+ args args
+ wantErr bool
+ }{
+ {name: "valid", args: args{image: "alpine"}, wantErr: false},
+ {name: "valid", args: args{image: "alpine:latest"}, wantErr: false},
+ {name: "valid", args: args{image: "localhost:1234/test"}, wantErr: false},
+ {name: "valid", args: args{image: "alpine:3.7"}, wantErr: false},
+ {name: "valid", args: args{image: "docker.example.edu/gmr/alpine:3.7"}, wantErr: false},
+ {name: "valid", args: args{image: "docker.example.com:5000/gmr/alpine@sha256:11111111111111111111111111111111"}, wantErr: false},
+ {name: "valid", args: args{image: "registry.dobby.org/dobby/dobby-servers/arthound:2019-08-08"}, wantErr: false},
+ {name: "valid", args: args{image: "registry.dobby.org/dobby/dobby-servers/lerphound:latest"}, wantErr: false},
+ {name: "valid", args: args{image: "registry.dobby.org/dobby/dobby-servers/loophole@sha256:5a156ff125e5a12ac7ff43ee5120fa249cf62248337b6d04abc574c8"}, wantErr: false},
+ {name: "valid", args: args{image: "sosedoff/pgweb@sha256:5a156ff125e5a12ac7ff43ee5120fa249cf62248337b6d04574c8"}, wantErr: false},
+ {name: "valid", args: args{image: "registry.dobby.org/dobby/antique-penguin:release-production"}, wantErr: false},
+ {name: "valid", args: args{image: "dalprodictus/halcon:6.7.5"}, wantErr: false},
+ {name: "valid", args: args{image: "antigua/antigua:v31"}, wantErr: false},
+ {name: "invalid ;", args: args{image: "alpine;v1.0"}, wantErr: true},
+ {name: "invalid tag and digest1", args: args{image: "alpine:latest@sha256:11111111111111111111111111111111"}, wantErr: true},
+ {name: "invalid |", args: args{image: "alpine|v1.0"}, wantErr: true},
+ {name: "invalid &", args: args{image: "alpine&v1.0"}, wantErr: true},
+ {name: "invalid tag and digest2", args: args{image: "sosedoff/pgweb:latest@sha256:5a156ff125e5a12ac7ff43ee5120fa249cf62248337b6d04574c8"}, wantErr: true},
+ {name: "invalid tag and digest3", args: args{image: "192.168.122.123:5000/kubeos_uefi-x86_64:euleros_v2_docker-2023-01@sha256:1a1a1a1a1a1a1a1a1a1a1a1a1a1a"}, wantErr: true},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if err := isValidImageName(tt.args.image); (err != nil) != tt.wantErr {
+ t.Errorf("isValidImageName() error = %v, wantErr %v", err, tt.wantErr)
+ }
+ })
+ }
+}
+
+func Test_checkOCIImageDigestMatch(t *testing.T) {
+ type args struct {
+ containerRuntime string
+ imageName string
+ checkSum string
+ }
+ tests := []struct {
+ name string
+ args args
+ wantErr bool
+ }{
+ {name: "invalid container runtion", args: args{containerRuntime: "dockctl", imageName: "docker.io/library/hello-world:latest", checkSum: "1abf18abf9bf9baa0a4a38d1afad4abf0d7da4544e163186e036c906c09c94fe"}, wantErr: true},
+ {name: "nil image digets", args: args{containerRuntime: "crictl", imageName: "docker.io/library/hello-world:latest", checkSum: "1abf18abf9bf9baa0a4a38d1afad4abf0d7da4544e163186e036c906c09c94fe"}, wantErr: true},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if tt.name == "nil image digets" {
+ patchGetOCIImageDigest := gomonkey.ApplyFuncReturn(getOCIImageDigest, "", nil)
+ defer patchGetOCIImageDigest.Reset()
+ }
+ if err := checkOCIImageDigestMatch(tt.args.containerRuntime, tt.args.imageName, tt.args.checkSum); (err != nil) != tt.wantErr {
+ t.Errorf("checkOCIImageDigestMatch() error = %v, wantErr %v", err, tt.wantErr)
+ }
+ })
+ }
+}
--
2.39.0

View File

@ -1,156 +0,0 @@
From 911fbd04ba55a2560e8da8595ff379a742e5fa30 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Thu, 10 Aug 2023 17:47:54 +0800
Subject: [PATCH 06/17] KubeOS: fix a bug that failed to parse key with =
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/agent/server/config.go | 6 ++--
cmd/agent/server/config_test.go | 55 +++++++++++++++++++++++++++++----
2 files changed, 52 insertions(+), 9 deletions(-)
diff --git a/cmd/agent/server/config.go b/cmd/agent/server/config.go
index 653f913..bcd9fde 100644
--- a/cmd/agent/server/config.go
+++ b/cmd/agent/server/config.go
@@ -259,7 +259,7 @@ func getAndSetConfigsFromFile(expectConfigs map[string]*agent.KeyInfo, path stri
configsWrite = append(configsWrite, line)
continue
}
- configKV := strings.Split(line, "=")
+ configKV := strings.SplitN(line, "=", kvPair)
if len(configKV) != kvPair {
logrus.Errorf("could not parse systctl config %s", line)
return nil, fmt.Errorf("could not parse systctl config %s", line)
@@ -374,8 +374,8 @@ func handleUpdateKey(config []string, configInfo *agent.KeyInfo, isFound bool) s
func handleAddKey(m map[string]*agent.KeyInfo, isOnlyKeyValid bool) []string {
var configs []string
for key, keyInfo := range m {
- if key == "" {
- logrus.Warnln("Failed to add nil key")
+ if key == "" || strings.Contains(key, "=") {
+ logrus.Warnf("Failed to add nil key or key containing =, key: %s", key)
continue
}
if keyInfo.Operation == "delete" {
diff --git a/cmd/agent/server/config_test.go b/cmd/agent/server/config_test.go
index 2deb15f..ae2a2cf 100644
--- a/cmd/agent/server/config_test.go
+++ b/cmd/agent/server/config_test.go
@@ -23,7 +23,6 @@ import (
"testing"
"github.com/agiledragon/gomonkey/v2"
-
agent "openeuler.org/KubeOS/cmd/agent/api"
)
@@ -105,17 +104,27 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
wantErr bool
}{
{name: "create file", args: args{config: &agent.SysConfig{ConfigPath: persistPath}}, want: []string{comment}, wantErr: false},
+ {
+ name: "nil path",
+ args: args{
+ config: &agent.SysConfig{},
+ },
+ want: []string{},
+ wantErr: false,
+ },
{
name: "add configs",
args: args{
config: &agent.SysConfig{
ConfigPath: persistPath,
Contents: map[string]*agent.KeyInfo{
- "a": {Value: "1"},
- "b": {Value: "2"},
- "c": {Value: ""},
- "": {Value: "4"},
- "e": {Value: "5"},
+ "a": {Value: "1"},
+ "b": {Value: "2"},
+ "c": {Value: ""},
+ "": {Value: "4"},
+ "e": {Value: "5"},
+ "y=1": {Value: "26"},
+ "z": {Value: "x=1"},
},
},
},
@@ -123,6 +132,7 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
"a=1",
"b=2",
"e=5",
+ "z=x=1",
},
wantErr: false,
},
@@ -134,6 +144,7 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
Contents: map[string]*agent.KeyInfo{
"a": {Value: "2"},
"b": {Value: ""},
+ "z": {Value: "x=2"},
},
},
},
@@ -141,6 +152,7 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
"a=2",
"b=2",
"e=5",
+ "z=x=2",
},
wantErr: false,
},
@@ -155,6 +167,7 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
"c": {Value: "3", Operation: "delete"},
"e": {Value: "5", Operation: "remove"},
"f": {Value: "6", Operation: "remove"},
+ "z": {Value: "x=2", Operation: "delete"},
},
},
},
@@ -166,6 +179,8 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
wantErr: false,
},
}
+ patchGetKernelConPath := gomonkey.ApplyFuncReturn(getKernelConPath, persistPath)
+ defer patchGetKernelConPath.Reset()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
k := KerSysctlPersist{}
@@ -467,3 +482,31 @@ func Test_getConfigPartition(t *testing.T) {
})
}
}
+
+func Test_ConfigFactoryTemplate(t *testing.T) {
+ type args struct {
+ configType string
+ config *agent.SysConfig
+ }
+ tests := []struct {
+ name string
+ args args
+ wantErr bool
+ }{
+ {
+ name: "error",
+ args: args{
+ configType: "test",
+ config: &agent.SysConfig{},
+ },
+ wantErr: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if err := ConfigFactoryTemplate(tt.args.configType, tt.args.config); (err != nil) != tt.wantErr {
+ t.Errorf("ConfigFactoryTemplate() error = %v, wantErr %v", err, tt.wantErr)
+ }
+ })
+ }
+}
--
2.39.0

View File

@ -1,52 +0,0 @@
From 59473394cca1e227ec579236d71ec54deb79b068 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Thu, 10 Aug 2023 20:49:39 +0800
Subject: [PATCH 07/17] KubeOS: add warning log during config add warning log
when configuring kv with unknown operation
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/agent/server/config.go | 4 ++++
cmd/agent/server/config_test.go | 4 ++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/cmd/agent/server/config.go b/cmd/agent/server/config.go
index bcd9fde..78dfd01 100644
--- a/cmd/agent/server/config.go
+++ b/cmd/agent/server/config.go
@@ -382,6 +382,10 @@ func handleAddKey(m map[string]*agent.KeyInfo, isOnlyKeyValid bool) []string {
logrus.Warnf("Failed to delete inexistent key %s", key)
continue
}
+ if keyInfo.Operation != "" {
+ logrus.Warnf("Unknown operation %s, adding key %s with value %s by default",
+ keyInfo.Operation, key, keyInfo.Value)
+ }
k, v := strings.TrimSpace(key), strings.TrimSpace(keyInfo.Value)
if keyInfo.Value == "" && isOnlyKeyValid {
logrus.Infoln("add configuration ", k)
diff --git a/cmd/agent/server/config_test.go b/cmd/agent/server/config_test.go
index ae2a2cf..6424885 100644
--- a/cmd/agent/server/config_test.go
+++ b/cmd/agent/server/config_test.go
@@ -122,7 +122,7 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
"b": {Value: "2"},
"c": {Value: ""},
"": {Value: "4"},
- "e": {Value: "5"},
+ "e": {Value: "5", Operation: "xxx"},
"y=1": {Value: "26"},
"z": {Value: "x=1"},
},
@@ -144,7 +144,7 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
Contents: map[string]*agent.KeyInfo{
"a": {Value: "2"},
"b": {Value: ""},
- "z": {Value: "x=2"},
+ "z": {Value: "x=2", Operation: "zzz"},
},
},
},
--
2.39.0

View File

@ -1,26 +0,0 @@
From 38ed69d2ad089d124ee72a4431fcc96ef3d9cf28 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Thu, 10 Aug 2023 21:10:29 +0800
Subject: [PATCH 08/17] KubeOS: modify log level and content
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/agent/server/config.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cmd/agent/server/config.go b/cmd/agent/server/config.go
index 78dfd01..c474f59 100644
--- a/cmd/agent/server/config.go
+++ b/cmd/agent/server/config.go
@@ -57,7 +57,7 @@ func (k KernelSysctl) SetConfig(config *agent.SysConfig) error {
}
logrus.Infof("Configured kernel.sysctl %s=%s", key, keyInfo.Value)
} else {
- logrus.Errorf("Failed to parse kernel.sysctl config operation %s value %s", keyInfo.Operation, keyInfo.Value)
+ logrus.Warnf("Failed to parse kernel.sysctl key %s value %s operation %s", key, keyInfo.Value, keyInfo.Operation)
}
}
return nil
--
2.39.0

View File

@ -1,151 +0,0 @@
From dcfb6e0397e649631ec42dcf51c3e98e914f8269 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Fri, 11 Aug 2023 19:33:56 +0800
Subject: [PATCH 09/17] KubeOS: fix updating key to kv
when configuring kernel boot parameters, it should be able to update
key to kv
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/agent/server/config.go | 37 ++++++++++++++++++++++-----------
cmd/agent/server/config_test.go | 15 +++++++------
2 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/cmd/agent/server/config.go b/cmd/agent/server/config.go
index c474f59..20af267 100644
--- a/cmd/agent/server/config.go
+++ b/cmd/agent/server/config.go
@@ -57,7 +57,7 @@ func (k KernelSysctl) SetConfig(config *agent.SysConfig) error {
}
logrus.Infof("Configured kernel.sysctl %s=%s", key, keyInfo.Value)
} else {
- logrus.Warnf("Failed to parse kernel.sysctl key %s value %s operation %s", key, keyInfo.Value, keyInfo.Operation)
+ logrus.Warnf("Failed to parse kernel.sysctl key: %s value: %s operation: %s", key, keyInfo.Value, keyInfo.Operation)
}
}
return nil
@@ -317,7 +317,7 @@ func createConfigPath(configPath string) error {
if err != nil {
return err
}
- defer f.Close()
+ f.Close()
return nil
}
@@ -335,11 +335,16 @@ func getGrubCfgPath() string {
// handleDeleteKey deletes key if oldValue==newValue and returns "" string. Otherwier, it returns key=oldValue
func handleDeleteKey(config []string, configInfo *agent.KeyInfo) string {
- if len(config) == onlyKey {
- logrus.Infoln("delete configuration ", config[0])
+ key := config[0]
+ if len(config) == onlyKey && configInfo.Value == "" {
+ logrus.Infoln("delete configuration ", key)
return ""
+ } else if len(config) == onlyKey && configInfo.Value != "" {
+ logrus.Warnf("Failed to delete key %s with inconsistent values "+
+ "nil and %s", key, configInfo.Value)
+ return key
}
- key, oldValue := config[0], config[1]
+ oldValue := config[1]
if oldValue != configInfo.Value {
logrus.Warnf("Failed to delete key %s with inconsistent values "+
"%s and %s", key, oldValue, configInfo.Value)
@@ -351,22 +356,30 @@ func handleDeleteKey(config []string, configInfo *agent.KeyInfo) string {
// handleUpdateKey updates key if key is found, otherwise it returns old config.
func handleUpdateKey(config []string, configInfo *agent.KeyInfo, isFound bool) string {
- if len(config) == onlyKey {
- return config[0]
+ key := config[0]
+ if !isFound && len(config) == onlyKey {
+ return key
}
- key, oldValue := config[0], config[1]
- if !isFound {
- return key + "=" + oldValue
+ if !isFound && len(config) == kvPair {
+ return key + "=" + config[1]
}
if configInfo.Operation != "" {
logrus.Warnf("Unknown operation %s, updating key %s with value %s by default",
configInfo.Operation, key, configInfo.Value)
}
+ if len(config) == onlyKey && configInfo.Value == "" {
+ return key
+ }
+ newValue := strings.TrimSpace(configInfo.Value)
+ if len(config) == onlyKey && configInfo.Value != "" {
+ logrus.Infof("update configuration %s=%s", key, newValue)
+ return key + "=" + newValue
+ }
+ oldValue := config[1]
if configInfo.Value == "" {
logrus.Warnf("Failed to update key %s with null value", key)
return key + "=" + oldValue
}
- newValue := strings.TrimSpace(configInfo.Value)
logrus.Infof("update configuration %s=%s", key, newValue)
return key + "=" + newValue
}
@@ -388,7 +401,7 @@ func handleAddKey(m map[string]*agent.KeyInfo, isOnlyKeyValid bool) []string {
}
k, v := strings.TrimSpace(key), strings.TrimSpace(keyInfo.Value)
if keyInfo.Value == "" && isOnlyKeyValid {
- logrus.Infoln("add configuration ", k)
+ logrus.Infoln("add configuration", k)
configs = append(configs, k)
} else if keyInfo.Value == "" {
logrus.Warnf("Failed to add key %s with null value", k)
diff --git a/cmd/agent/server/config_test.go b/cmd/agent/server/config_test.go
index 6424885..08daf99 100644
--- a/cmd/agent/server/config_test.go
+++ b/cmd/agent/server/config_test.go
@@ -262,10 +262,11 @@ menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestri
"": {Value: "test"}, // warning, skip, failed to add kv with empty key
"selinux": {Value: "1", Operation: "delete"}, // failed to delete inconsistent kv
"acpi": {Value: "off", Operation: "delete"}, // failed to delete inexistent kv
+ "ro": {Value: "1"}, // update key to kv
},
},
},
- pattern: `(?m)^\s+linux\s+\/boot\/vmlinuz\s+root=UUID=[0-1]\s+ro\s+rootfstype=ext4\s+nomodeset\s+oops=panic\s+softlockup_panic=0\s+nmi_watchdog=1\s+rd\.shell=0\s+selinux=0\s+crashkernel=256M\s+panic=5\s+(debug\spci=nomis|pci=nomis\sdebug)$`,
+ pattern: `(?m)^\s+linux\s+\/boot\/vmlinuz\s+root=UUID=[0-1]\s+ro=1\s+rootfstype=ext4\s+nomodeset\s+oops=panic\s+softlockup_panic=0\s+nmi_watchdog=1\s+rd\.shell=0\s+selinux=0\s+crashkernel=256M\s+panic=5\s+(debug\spci=nomis|pci=nomis\sdebug)$`,
wantErr: false,
},
{
@@ -274,14 +275,15 @@ menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestri
args: args{
config: &agent.SysConfig{
Contents: map[string]*agent.KeyInfo{
- "debug": {Operation: "delete"}, // delete key
- "pci": {Value: "nomis", Operation: "delete"}, // delete kv
- "debugpat": {Value: "", Operation: "add"}, // passed key, operation is invalid, default to add key
- "audit": {Value: "1", Operation: "add"}, // passed kv, key is inexistent, operation is invalid, default to add kv
+ "debug": {Operation: "delete"}, // delete key
+ "pci": {Value: "nomis", Operation: "delete"}, // delete kv
+ "debugpat": {Value: "", Operation: "add"}, // passed key, operation is invalid, default to add key
+ "audit": {Value: "1", Operation: "add"}, // passed kv, key is inexistent, operation is invalid, default to add kv
+ "nomodeset": {Value: "1", Operation: "delete"}, // delete key with inconsistent value
},
},
},
- pattern: `(?m)^\s+linux\s+\/boot\/vmlinuz\s+root=UUID=[0-1]\s+ro\s+rootfstype=ext4\s+nomodeset\s+oops=panic\s+softlockup_panic=0\s+nmi_watchdog=1\s+rd\.shell=0\s+selinux=0\s+crashkernel=256M\s+panic=5\s+(debugpat\saudit=1|audit=1\sdebugpat)$`,
+ pattern: `(?m)^\s+linux\s+\/boot\/vmlinuz\s+root=UUID=[0-1]\s+ro=1\s+rootfstype=ext4\s+nomodeset\s+oops=panic\s+softlockup_panic=0\s+nmi_watchdog=1\s+rd\.shell=0\s+selinux=0\s+crashkernel=256M\s+panic=5\s+(debugpat\saudit=1|audit=1\sdebugpat)$`,
wantErr: false,
},
{
@@ -300,6 +302,7 @@ menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestri
"": {Value: "test"}, // warning, skip, failed to add kv with empty key
"selinux": {Value: "1", Operation: "delete"},
"acpi": {Value: "off", Operation: "delete"},
+ "ro": {Value: ""},
},
},
},
--
2.39.0

View File

@ -1,37 +0,0 @@
From 657e3e5c9bcc0fac3a079f51842d59a9e6b5e163 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Mon, 14 Aug 2023 09:53:16 +0800
Subject: [PATCH 10/17] KubeOS: fix proxy requeue bug
fix the bug that proxy may work after resuming normal from error status
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/proxy/controllers/os_controller.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/cmd/proxy/controllers/os_controller.go b/cmd/proxy/controllers/os_controller.go
index 09d61c0..30f9839 100644
--- a/cmd/proxy/controllers/os_controller.go
+++ b/cmd/proxy/controllers/os_controller.go
@@ -94,7 +94,7 @@ func (r *OSReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Re
if err = r.refreshNode(ctx, &node, osInstance, osCr.Spec.SysConfigs.Version, values.SysConfigName); err != nil {
return values.RequeueNow, err
}
- return values.RequeueNow, nil
+ return values.Requeue, nil
}
if configOps == values.UpdateConfig {
osInstance.Spec.SysConfigs = osCr.Spec.SysConfigs
@@ -124,7 +124,7 @@ func (r *OSReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Re
values.UpgradeConfigName); err != nil {
return values.RequeueNow, err
}
- return values.RequeueNow, nil
+ return values.Requeue, nil
}
if err := r.setConfig(ctx, osInstance, values.UpgradeConfigName); err != nil {
return values.RequeueNow, err
--
2.39.0

View File

@ -1,665 +0,0 @@
From a87666e17d729feb67f987fa7038ef83b3fa2e1b Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Mon, 14 Aug 2023 16:46:06 +0800
Subject: [PATCH 11/17] KubeOS: fix operator bug of missing deep copy
Fixed bug where operator didn't perform deep copy
add operator ut, testing in multiple nodes env
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/operator/controllers/os_controller.go | 44 +-
.../controllers/os_controller_test.go | 378 ++++++++++++++----
2 files changed, 330 insertions(+), 92 deletions(-)
diff --git a/cmd/operator/controllers/os_controller.go b/cmd/operator/controllers/os_controller.go
index 620739b..d36f15d 100644
--- a/cmd/operator/controllers/os_controller.go
+++ b/cmd/operator/controllers/os_controller.go
@@ -15,6 +15,8 @@ package controllers
import (
"context"
+ "encoding/json"
+ "fmt"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
@@ -188,7 +190,9 @@ func upgradeNodes(ctx context.Context, r common.ReadStatusWriter, os *upgradev1.
}
continue
}
- updateNodeAndOSins(ctx, r, os, &node, &osInstance)
+ if err := updateNodeAndOSins(ctx, r, os, &node, &osInstance); err != nil {
+ continue
+ }
count++
}
}
@@ -196,12 +200,16 @@ func upgradeNodes(ctx context.Context, r common.ReadStatusWriter, os *upgradev1.
}
func updateNodeAndOSins(ctx context.Context, r common.ReadStatusWriter, os *upgradev1.OS,
- node *corev1.Node, osInstance *upgradev1.OSInstance) {
+ node *corev1.Node, osInstance *upgradev1.OSInstance) error {
if osInstance.Spec.UpgradeConfigs.Version != os.Spec.UpgradeConfigs.Version {
- osInstance.Spec.UpgradeConfigs = os.Spec.UpgradeConfigs
+ if err := deepCopySpecConfigs(os, osInstance, values.UpgradeConfigName); err != nil {
+ return err
+ }
}
if osInstance.Spec.SysConfigs.Version != os.Spec.SysConfigs.Version {
- osInstance.Spec.SysConfigs = os.Spec.SysConfigs
+ if err := deepCopySpecConfigs(os, osInstance, values.SysConfigName); err != nil {
+ return err
+ }
// exchange "grub.cmdline.current" and "grub.cmdline.next"
for i, config := range osInstance.Spec.SysConfigs.Configs {
if config.Model == "grub.cmdline.current" {
@@ -215,11 +223,14 @@ func updateNodeAndOSins(ctx context.Context, r common.ReadStatusWriter, os *upgr
osInstance.Spec.NodeStatus = values.NodeStatusUpgrade.String()
if err := r.Update(ctx, osInstance); err != nil {
log.Error(err, "unable to update", "osInstance", osInstance.Name)
+ return err
}
node.Labels[values.LabelUpgrading] = ""
if err := r.Update(ctx, node); err != nil {
log.Error(err, "unable to label", "node", node.Name)
+ return err
}
+ return nil
}
func assignConfig(ctx context.Context, r common.ReadStatusWriter, sysConfigs upgradev1.SysConfigs,
@@ -307,3 +318,28 @@ func min(a, b int) int {
}
return b
}
+
+func deepCopySpecConfigs(os *upgradev1.OS, osinstance *upgradev1.OSInstance, configType string) error {
+ switch configType {
+ case values.UpgradeConfigName:
+ data, err := json.Marshal(os.Spec.UpgradeConfigs)
+ if err != nil {
+ return err
+ }
+ if err = json.Unmarshal(data, &osinstance.Spec.UpgradeConfigs); err != nil {
+ return err
+ }
+ case values.SysConfigName:
+ data, err := json.Marshal(os.Spec.SysConfigs)
+ if err != nil {
+ return err
+ }
+ if err = json.Unmarshal(data, &osinstance.Spec.SysConfigs); err != nil {
+ return err
+ }
+ default:
+ log.Error(nil, "configType "+configType+" cannot be recognized")
+ return fmt.Errorf("configType %s cannot be recognized", configType)
+ }
+ return nil
+}
diff --git a/cmd/operator/controllers/os_controller_test.go b/cmd/operator/controllers/os_controller_test.go
index 98de6d0..e59ce7e 100644
--- a/cmd/operator/controllers/os_controller_test.go
+++ b/cmd/operator/controllers/os_controller_test.go
@@ -17,19 +17,12 @@ import (
"testing"
"time"
- "github.com/agiledragon/gomonkey/v2"
"github.com/google/uuid"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
v1 "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
- "k8s.io/client-go/kubernetes/scheme"
- "k8s.io/client-go/util/workqueue"
- "sigs.k8s.io/controller-runtime/pkg/client"
- "sigs.k8s.io/controller-runtime/pkg/event"
upgradev1 "openeuler.org/KubeOS/api/v1alpha1"
"openeuler.org/KubeOS/pkg/values"
@@ -37,8 +30,7 @@ import (
var _ = Describe("OsController", func() {
const (
- OSName = "test-os"
-
+ OSName = "test-os"
timeout = time.Second * 20
interval = time.Millisecond * 500
)
@@ -72,26 +64,33 @@ var _ = Describe("OsController", func() {
})
AfterEach(func() {
- desiredTestNamespace := &v1.Namespace{
- TypeMeta: metav1.TypeMeta{
- APIVersion: "v1",
- Kind: "Namespace",
- },
- ObjectMeta: metav1.ObjectMeta{
- Name: testNamespace,
- },
+ // delete all nodes
+ nodeList := &v1.NodeList{}
+ err := k8sClient.List(context.Background(), nodeList)
+ Expect(err).ToNot(HaveOccurred())
+ for _, node := range nodeList.Items {
+ k8sClient.Delete(context.Background(), &node)
}
- // Add any teardown steps that needs to be executed after each test
- err := k8sClient.Delete(context.Background(), desiredTestNamespace,
- client.PropagationPolicy(metav1.DeletePropagationForeground))
+ nodeList = &v1.NodeList{}
+ Eventually(func() bool {
+ err = k8sClient.List(context.Background(), nodeList)
+ if err != nil || len(nodeList.Items) != 0 {
+ return false
+ }
+ return true
+ }, timeout, interval).Should(BeTrue())
+ // delete all OS CRs
+ osList := &upgradev1.OSList{}
+ err = k8sClient.List(context.Background(), osList)
Expect(err).ToNot(HaveOccurred())
-
- existingNamespace := &v1.Namespace{}
+ for _, os := range osList.Items {
+ k8sClient.Delete(context.Background(), &os)
+ }
+ osList = &upgradev1.OSList{}
Eventually(func() bool {
- err := k8sClient.Get(context.Background(), types.NamespacedName{Name: testNamespace},
- existingNamespace)
- if err != nil && errors.IsNotFound(err) {
+ err = k8sClient.List(context.Background(), osList)
+ if err != nil || len(osList.Items) != 0 {
return false
}
return true
@@ -102,7 +101,7 @@ var _ = Describe("OsController", func() {
It("Should label the osinstance's nodestatus to upgrading", func() {
ctx := context.Background()
- // create Node
+ // create Node1
node1Name = "test-node-" + uuid.New().String()
node1 := &v1.Node{
ObjectMeta: metav1.ObjectMeta{
@@ -131,7 +130,7 @@ var _ = Describe("OsController", func() {
return err == nil
}, timeout, interval).Should(BeTrue())
- // create OSInstance
+ // create OSInstance1
OSIns := &upgradev1.OSInstance{
TypeMeta: metav1.TypeMeta{
Kind: "OSInstance",
@@ -163,6 +162,67 @@ var _ = Describe("OsController", func() {
}, timeout, interval).Should(BeTrue())
Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node1Name))
+ // create Node2
+ node2Name := "test-node-" + uuid.New().String()
+ node2 := &v1.Node{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node2Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ "beta.kubernetes.io/os": "linux",
+ },
+ },
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: "v1",
+ Kind: "Node",
+ },
+ Status: v1.NodeStatus{
+ NodeInfo: v1.NodeSystemInfo{
+ OSImage: "KubeOS v2",
+ },
+ },
+ }
+ err = k8sClient.Create(ctx, node2)
+ Expect(err).ToNot(HaveOccurred())
+ existingNode = &v1.Node{}
+ Eventually(func() bool {
+ err := k8sClient.Get(context.Background(),
+ types.NamespacedName{Name: node2Name, Namespace: testNamespace}, existingNode)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+
+ // create OSInstance2
+ OSIns = &upgradev1.OSInstance{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "OSInstance",
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node2Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ values.LabelOSinstance: node2Name,
+ },
+ },
+ Spec: upgradev1.OSInstanceSpec{
+ SysConfigs: upgradev1.SysConfigs{
+ Version: "v1",
+ Configs: []upgradev1.SysConfig{},
+ },
+ UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}, Version: "v1"},
+ },
+ }
+ Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
+
+ // Check that the corresponding OSIns CR has been created
+ osInsCRLookupKey2 := types.NamespacedName{Name: node2Name, Namespace: testNamespace}
+ createdOSIns = &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node2Name))
+
// create OS CR
OS := &upgradev1.OS{
TypeMeta: metav1.TypeMeta{
@@ -206,13 +266,20 @@ var _ = Describe("OsController", func() {
return err == nil
}, timeout, interval).Should(BeTrue())
Expect(createdOSIns.Spec.NodeStatus).Should(Equal(values.NodeStatusUpgrade.String()))
+
+ createdOSIns2 := &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns2)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOSIns2.Spec.NodeStatus).Should(Equal(values.NodeStatusUpgrade.String()))
})
})
Context("When we want to configure node", func() {
It("Should update OSInstance spec and update NodeStatus to config", func() {
ctx := context.Background()
- // create Node
+ // create Node1
node1Name = "test-node-" + uuid.New().String()
node1 := &v1.Node{
ObjectMeta: metav1.ObjectMeta{
@@ -228,7 +295,7 @@ var _ = Describe("OsController", func() {
},
Status: v1.NodeStatus{
NodeInfo: v1.NodeSystemInfo{
- OSImage: "KubeOS v2",
+ OSImage: "KubeOS v1",
},
},
}
@@ -241,6 +308,7 @@ var _ = Describe("OsController", func() {
return err == nil
}, timeout, interval).Should(BeTrue())
+ // create OSInstance1
OSIns := &upgradev1.OSInstance{
TypeMeta: metav1.TypeMeta{
Kind: "OSInstance",
@@ -249,6 +317,9 @@ var _ = Describe("OsController", func() {
ObjectMeta: metav1.ObjectMeta{
Name: node1Name,
Namespace: testNamespace,
+ Labels: map[string]string{
+ values.LabelOSinstance: node1Name,
+ },
},
Spec: upgradev1.OSInstanceSpec{
SysConfigs: upgradev1.SysConfigs{
@@ -261,14 +332,76 @@ var _ = Describe("OsController", func() {
}
Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
- osInsCRLookupKey := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
+ osInsCRLookupKey1 := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
createdOSIns := &upgradev1.OSInstance{}
Eventually(func() bool {
- err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
+ err := k8sClient.Get(ctx, osInsCRLookupKey1, createdOSIns)
return err == nil
}, timeout, interval).Should(BeTrue())
Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node1Name))
+ // create Node2
+ node2Name := "test-node-" + uuid.New().String()
+ node2 := &v1.Node{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node2Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ "beta.kubernetes.io/os": "linux",
+ },
+ },
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: "v1",
+ Kind: "Node",
+ },
+ Status: v1.NodeStatus{
+ NodeInfo: v1.NodeSystemInfo{
+ OSImage: "KubeOS v1",
+ },
+ },
+ }
+ err = k8sClient.Create(ctx, node2)
+ Expect(err).ToNot(HaveOccurred())
+ existingNode = &v1.Node{}
+ Eventually(func() bool {
+ err := k8sClient.Get(context.Background(),
+ types.NamespacedName{Name: node2Name, Namespace: testNamespace}, existingNode)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+
+ // create OSInstance2
+ OSIns = &upgradev1.OSInstance{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "OSInstance",
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node2Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ values.LabelOSinstance: node2Name,
+ },
+ },
+ Spec: upgradev1.OSInstanceSpec{
+ SysConfigs: upgradev1.SysConfigs{
+ Version: "v1",
+ Configs: []upgradev1.SysConfig{},
+ },
+ UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}, Version: "v1"},
+ NodeStatus: values.NodeStatusIdle.String(),
+ },
+ }
+ Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
+
+ // Check that the corresponding OSIns CR has been created
+ osInsCRLookupKey2 := types.NamespacedName{Name: node2Name, Namespace: testNamespace}
+ createdOSIns = &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node2Name))
+
OS := &upgradev1.OS{
TypeMeta: metav1.TypeMeta{
APIVersion: "upgrade.openeuler.org/v1alpha1",
@@ -311,13 +444,21 @@ var _ = Describe("OsController", func() {
Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v1"))
time.Sleep(1 * time.Second) // sleep a while to make sure Reconcile finished
- configedOSIns := &upgradev1.OSInstance{}
+ configedOSIns1 := &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey1, configedOSIns1)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(configedOSIns1.Spec.NodeStatus).Should(Equal(values.NodeStatusConfig.String()))
+ Expect(configedOSIns1.Spec.SysConfigs.Version).Should(Equal("v2"))
+
+ configedOSIns2 := &upgradev1.OSInstance{}
Eventually(func() bool {
- err := k8sClient.Get(ctx, osInsCRLookupKey, configedOSIns)
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, configedOSIns2)
return err == nil
}, timeout, interval).Should(BeTrue())
- Expect(configedOSIns.Spec.NodeStatus).Should(Equal(values.NodeStatusConfig.String()))
- Expect(configedOSIns.Spec.SysConfigs.Version).Should(Equal("v2"))
+ Expect(configedOSIns2.Spec.NodeStatus).Should(Equal(values.NodeStatusConfig.String()))
+ Expect(configedOSIns2.Spec.SysConfigs.Version).Should(Equal("v2"))
})
})
@@ -394,6 +535,9 @@ var _ = Describe("OsController", func() {
}, timeout, interval).Should(BeTrue())
_, ok := existingNode.Labels[values.LabelUpgrading]
Expect(ok).Should(Equal(false))
+
+ createdOS.Spec.OpsType = "test"
+ Expect(k8sClient.Update(ctx, createdOS)).Should(Succeed())
})
})
@@ -401,7 +545,7 @@ var _ = Describe("OsController", func() {
It("Should exchange .current and .next", func() {
ctx := context.Background()
- // create Node
+ // create Node1
node1Name = "test-node-" + uuid.New().String()
node1 := &v1.Node{
ObjectMeta: metav1.ObjectMeta{
@@ -430,7 +574,7 @@ var _ = Describe("OsController", func() {
return err == nil
}, timeout, interval).Should(BeTrue())
- // create OSInstance
+ // create OSInstance1
OSIns := &upgradev1.OSInstance{
TypeMeta: metav1.TypeMeta{
Kind: "OSInstance",
@@ -454,14 +598,75 @@ var _ = Describe("OsController", func() {
Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
// Check that the corresponding OSIns CR has been created
- osInsCRLookupKey := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
+ osInsCRLookupKey1 := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
createdOSIns := &upgradev1.OSInstance{}
Eventually(func() bool {
- err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
+ err := k8sClient.Get(ctx, osInsCRLookupKey1, createdOSIns)
return err == nil
}, timeout, interval).Should(BeTrue())
Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node1Name))
+ // create Node2
+ node2Name := "test-node-" + uuid.New().String()
+ node2 := &v1.Node{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node2Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ "beta.kubernetes.io/os": "linux",
+ },
+ },
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: "v1",
+ Kind: "Node",
+ },
+ Status: v1.NodeStatus{
+ NodeInfo: v1.NodeSystemInfo{
+ OSImage: "KubeOS v1",
+ },
+ },
+ }
+ err = k8sClient.Create(ctx, node2)
+ Expect(err).ToNot(HaveOccurred())
+ existingNode = &v1.Node{}
+ Eventually(func() bool {
+ err := k8sClient.Get(context.Background(),
+ types.NamespacedName{Name: node2Name, Namespace: testNamespace}, existingNode)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+
+ // create OSInstance2
+ OSIns = &upgradev1.OSInstance{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "OSInstance",
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node2Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ values.LabelOSinstance: node2Name,
+ },
+ },
+ Spec: upgradev1.OSInstanceSpec{
+ SysConfigs: upgradev1.SysConfigs{
+ Version: "v1",
+ Configs: []upgradev1.SysConfig{},
+ },
+ UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}, Version: "v1"},
+ },
+ }
+ Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
+
+ // Check that the corresponding OSIns CR has been created
+ osInsCRLookupKey2 := types.NamespacedName{Name: node2Name, Namespace: testNamespace}
+ createdOSIns = &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node2Name))
+
// create OS CR
OS := &upgradev1.OS{
TypeMeta: metav1.TypeMeta{
@@ -486,7 +691,13 @@ var _ = Describe("OsController", func() {
{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}},
},
},
- UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}},
+ UpgradeConfigs: upgradev1.SysConfigs{
+ Version: "v2",
+ Configs: []upgradev1.SysConfig{
+ {Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}},
+ {Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}},
+ },
+ },
},
}
Expect(k8sClient.Create(ctx, OS)).Should(Succeed())
@@ -501,75 +712,66 @@ var _ = Describe("OsController", func() {
Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v2"))
time.Sleep(1 * time.Second) // sleep a while to make sure Reconcile finished
- osInsCRLookupKey = types.NamespacedName{Name: node1Name, Namespace: testNamespace}
+ // check node1 osinstance
createdOSIns = &upgradev1.OSInstance{}
Eventually(func() bool {
- err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
+ err := k8sClient.Get(ctx, osInsCRLookupKey1, createdOSIns)
return err == nil
}, timeout, interval).Should(BeTrue())
Expect(createdOSIns.Spec.SysConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
Expect(createdOSIns.Spec.SysConfigs.Configs[1]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}}))
+ Expect(createdOSIns.Spec.UpgradeConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
+ Expect(createdOSIns.Spec.NodeStatus).Should(Equal(values.NodeStatusUpgrade.String()))
+
+ // check node2 osinstance
+ createdOSIns2 := &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns2)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOSIns2.Spec.NodeStatus).Should(Equal(values.NodeStatusUpgrade.String()))
+ Expect(createdOSIns2.Spec.SysConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
+ Expect(createdOSIns2.Spec.SysConfigs.Configs[1]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}}))
+ Expect(createdOSIns2.Spec.UpgradeConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
+
+ // check os cr spec
+ osCRLookupKey = types.NamespacedName{Name: OSName, Namespace: testNamespace}
+ createdOS = &upgradev1.OS{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osCRLookupKey, createdOS)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOS.Spec.SysConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
+ Expect(createdOS.Spec.SysConfigs.Configs[1]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}}))
})
})
})
-func TestOSReconciler_DeleteOSInstance(t *testing.T) {
- type fields struct {
- Scheme *runtime.Scheme
- Client client.Client
- }
- kClient, _ := client.New(cfg, client.Options{Scheme: scheme.Scheme})
+func Test_deepCopySpecConfigs(t *testing.T) {
type args struct {
- e event.DeleteEvent
- q workqueue.RateLimitingInterface
+ os *upgradev1.OS
+ osinstance *upgradev1.OSInstance
+ configType string
}
tests := []struct {
- name string
- fields fields
- args args
+ name string
+ args args
+ wantErr bool
}{
{
- name: "delete osinstance",
- fields: fields{
- Scheme: nil,
- Client: kClient,
- },
+ name: "error",
args: args{
- e: event.DeleteEvent{
- Object: &upgradev1.OSInstance{
- ObjectMeta: metav1.ObjectMeta{
- Name: "test-node1",
- Namespace: "test",
- },
- },
- },
- q: nil,
- },
+ os: &upgradev1.OS{},
+ osinstance: &upgradev1.OSInstance{},
+ configType: "test"},
+ wantErr: true,
},
}
- var patchList *gomonkey.Patches
- var patchDelete *gomonkey.Patches
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- r := &OSReconciler{
- Scheme: tt.fields.Scheme,
- Client: tt.fields.Client,
+ if err := deepCopySpecConfigs(tt.args.os, tt.args.osinstance, tt.args.configType); (err != nil) != tt.wantErr {
+ t.Errorf("deepCopySpecConfigs() error = %v, wantErr %v", err, tt.wantErr)
}
- patchList = gomonkey.ApplyMethodFunc(r.Client, "List", func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
- list.(*upgradev1.OSInstanceList).Items = []upgradev1.OSInstance{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "test-node1",
- Namespace: "test",
- },
- },
- }
- return nil
- })
- patchDelete = gomonkey.ApplyMethodReturn(r.Client, "Delete", nil)
- r.DeleteOSInstance(tt.args.e, tt.args.q)
})
}
- defer patchDelete.Reset()
- defer patchList.Reset()
}
--
2.39.0

View File

@ -1,191 +0,0 @@
From 9bd13d2a1b8b7282d7247caf9ba54f11bb297cd5 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Fri, 11 Aug 2023 20:25:46 +0800
Subject: [PATCH 12/17] KubeOS: add unit test
add containerd_image and disk_image unit test
modify make test command for only testing server and controllers
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
Makefile | 2 +-
cmd/agent/server/containerd_image_test.go | 10 ++-
cmd/agent/server/disk_image_test.go | 83 +++++++++++++++++++----
3 files changed, 80 insertions(+), 15 deletions(-)
diff --git a/Makefile b/Makefile
index b5b6161..eddf9e6 100644
--- a/Makefile
+++ b/Makefile
@@ -133,7 +133,7 @@ kustomize:
$(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v3@v3.8.7)
ARCH := $(shell uname -m)
-TEST_CMD := go test ./... -race -count=1 -timeout=300s -cover -gcflags=all=-l -p 1
+TEST_CMD := go test `go list ./cmd/... | grep -E 'server|controllers'` -race -count=1 -timeout=300s -cover -gcflags=all=-l -p 1
ifeq ($(ARCH), aarch64)
TEST_CMD := ETCD_UNSUPPORTED_ARCH=arm64 $(TEST_CMD)
diff --git a/cmd/agent/server/containerd_image_test.go b/cmd/agent/server/containerd_image_test.go
index d7133c3..85347c8 100644
--- a/cmd/agent/server/containerd_image_test.go
+++ b/cmd/agent/server/containerd_image_test.go
@@ -32,7 +32,6 @@ func Test_conImageHandler_downloadImage(t *testing.T) {
want string
wantErr bool
}{
-
{
name: "pullImageError",
c: conImageHandler{},
@@ -62,6 +61,15 @@ func Test_conImageHandler_downloadImage(t *testing.T) {
want: "update-test1/upadte.img",
wantErr: false,
},
+ {
+ name: "invalid image name",
+ c: conImageHandler{},
+ args: args{
+ req: &pb.UpdateRequest{ContainerImage: "nginx;v1"},
+ },
+ want: "",
+ wantErr: true,
+ },
}
patchPrepareEnv := gomonkey.ApplyFunc(prepareEnv, func() (preparePath, error) {
return preparePath{updatePath: "update-test1/",
diff --git a/cmd/agent/server/disk_image_test.go b/cmd/agent/server/disk_image_test.go
index 71c5de7..265b323 100644
--- a/cmd/agent/server/disk_image_test.go
+++ b/cmd/agent/server/disk_image_test.go
@@ -21,6 +21,7 @@ import (
"crypto/x509/pkix"
"encoding/hex"
"encoding/pem"
+ "fmt"
"io"
"math/big"
"net/http"
@@ -52,36 +53,78 @@ func Test_download(t *testing.T) {
want string
wantErr bool
}{
- // {name: "errornil", args: args{&pb.UpdateRequest{Certs: &pb.CertsInfo{}}}, want: "", wantErr: true},
- // {name: "normal", args: args{&pb.UpdateRequest{ImageUrl: "http://www.openeuler.org/zh/", FlagSafe: true, Certs: &pb.CertsInfo{}}}, want: "/persist/update.img", wantErr: false},
- // {name: "errornodir", args: args{&pb.UpdateRequest{ImageUrl: "http://www.openeuler.org/zh/", FlagSafe: true, Certs: &pb.CertsInfo{}}}, want: "", wantErr: true},
+ {name: "errornil", args: args{&pb.UpdateRequest{Certs: &pb.CertsInfo{}}}, want: "", wantErr: true},
+ {name: "error response", args: args{&pb.UpdateRequest{ImageUrl: "http://www.openeuler.abc", FlagSafe: true, Certs: &pb.CertsInfo{}}}, want: "", wantErr: true},
{
name: "normal",
args: args{
req: &pb.UpdateRequest{
ImageUrl: "http://www.openeuler.org/zh/",
+ FlagSafe: true,
+ Certs: &pb.CertsInfo{},
},
},
want: tmpFileForDownload,
wantErr: false,
},
+ {
+ name: "disk space not enough",
+ args: args{
+ req: &pb.UpdateRequest{
+ ImageUrl: "http://www.openeuler.org/zh/",
+ FlagSafe: true,
+ Certs: &pb.CertsInfo{},
+ },
+ },
+ want: "",
+ wantErr: true,
+ },
}
- patchStatfs := gomonkey.ApplyFunc(syscall.Statfs, func(path string, stat *syscall.Statfs_t) error {
+ var patchStatfs *gomonkey.Patches
+ patchStatfs = gomonkey.ApplyFunc(syscall.Statfs, func(path string, stat *syscall.Statfs_t) error {
stat.Bfree = 3000
stat.Bsize = 4096
return nil
})
defer patchStatfs.Reset()
- patchGetImageUrl := gomonkey.ApplyFuncReturn(getImageURL, &http.Response{
- StatusCode: http.StatusOK,
- ContentLength: 5,
- Body: io.NopCloser(strings.NewReader("hello")),
- }, nil)
+ patchGetImageUrl := gomonkey.ApplyFuncSeq(getImageURL,
+ []gomonkey.OutputCell{
+ {Values: gomonkey.Params{&http.Response{}, fmt.Errorf("error")}},
+ {Values: gomonkey.Params{&http.Response{StatusCode: http.StatusBadRequest, Body: io.NopCloser(strings.NewReader(""))}, nil}},
+ {
+ Values: gomonkey.Params{
+ &http.Response{
+ StatusCode: http.StatusOK,
+ ContentLength: 5,
+ Body: io.NopCloser(strings.NewReader("hello")),
+ },
+ nil,
+ },
+ },
+ {
+ Values: gomonkey.Params{
+ &http.Response{
+ StatusCode: http.StatusOK,
+ ContentLength: 5,
+ Body: io.NopCloser(strings.NewReader("hello")),
+ },
+ nil,
+ },
+ },
+ },
+ )
defer patchGetImageUrl.Reset()
patchOSCreate := gomonkey.ApplyFuncReturn(os.Create, tmpFile, nil)
defer patchOSCreate.Reset()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+ if tt.name == "disk space not enough" {
+ patchStatfs = gomonkey.ApplyFunc(syscall.Statfs, func(path string, stat *syscall.Statfs_t) error {
+ stat.Bfree = 1
+ stat.Bsize = 4096
+ return nil
+ })
+ }
got, err := download(tt.args.req)
if (err != nil) != tt.wantErr {
t.Errorf("download() error = %v, wantErr %v", err, tt.wantErr)
@@ -160,13 +203,27 @@ func Test_getImageURL(t *testing.T) {
MTLS: false,
Certs: &pb.CertsInfo{},
}}, want: &http.Response{StatusCode: http.StatusOK}, wantErr: false},
+ {name: "httpsLoadCertsError", args: args{req: &pb.UpdateRequest{
+ ImageUrl: "https://www.openeuler.abc/zh/",
+ FlagSafe: true,
+ MTLS: false,
+ Certs: &pb.CertsInfo{},
+ }}, want: &http.Response{}, wantErr: true},
+ {name: "httpsMLTSLoadCertsError", args: args{req: &pb.UpdateRequest{
+ ImageUrl: "https://www.openeuler.abc/zh/",
+ FlagSafe: true,
+ MTLS: true,
+ Certs: &pb.CertsInfo{},
+ }}, want: &http.Response{}, wantErr: true},
}
- patchLoadClientCerts := gomonkey.ApplyFunc(loadClientCerts, func(caCert, clientCert, clientKey string) (*http.Client, error) {
- return &http.Client{}, nil
+ patchLoadClientCerts := gomonkey.ApplyFuncSeq(loadClientCerts, []gomonkey.OutputCell{
+ {Values: gomonkey.Params{&http.Client{}, nil}},
+ {Values: gomonkey.Params{&http.Client{}, fmt.Errorf("error")}},
})
defer patchLoadClientCerts.Reset()
- patchLoadCaCerts := gomonkey.ApplyFunc(loadCaCerts, func(caCert string) (*http.Client, error) {
- return &http.Client{}, nil
+ patchLoadCaCerts := gomonkey.ApplyFuncSeq(loadCaCerts, []gomonkey.OutputCell{
+ {Values: gomonkey.Params{&http.Client{}, nil}},
+ {Values: gomonkey.Params{&http.Client{}, fmt.Errorf("error")}},
})
defer patchLoadCaCerts.Reset()
patchGet := gomonkey.ApplyFunc(http.Get, func(url string) (resp *http.Response, err error) {
--
2.39.0

View File

@ -1,126 +0,0 @@
From 1bc41e7e58e99e23cd8be522cc1c2d30090975d2 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Tue, 15 Aug 2023 16:33:11 +0800
Subject: [PATCH 13/17] KubeOS: fix clean space problems
add clean space function in server
change docker rm position in docker_image
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/agent/main.go | 4 +---
cmd/agent/server/docker_image.go | 6 +++---
cmd/agent/server/server.go | 9 +++++++++
cmd/agent/server/utils.go | 27 +++++++++++++--------------
4 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/cmd/agent/main.go b/cmd/agent/main.go
index 67c7e2d..7b1ed3d 100644
--- a/cmd/agent/main.go
+++ b/cmd/agent/main.go
@@ -13,8 +13,6 @@
package main
import (
- "fmt"
-
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
@@ -24,7 +22,7 @@ import (
)
func main() {
- fmt.Println("Version is:", version.Version)
+ logrus.Infoln("Version is:", version.Version)
l, err := server.NewListener(server.SockDir, server.SockName)
if err != nil {
logrus.Errorln("listen error" + err.Error())
diff --git a/cmd/agent/server/docker_image.go b/cmd/agent/server/docker_image.go
index 0b6ee35..16bcea5 100644
--- a/cmd/agent/server/docker_image.go
+++ b/cmd/agent/server/docker_image.go
@@ -61,13 +61,13 @@ func (d dockerImageHandler) getRootfsArchive(req *pb.UpdateRequest, neededPath p
if err != nil {
return "", err
}
- if err := runCommand("docker", "cp", containerId+":/"+neededPath.rootfsFile, neededPath.updatePath); err != nil {
- return "", err
- }
defer func() {
if err := runCommand("docker", "rm", containerId); err != nil {
logrus.Errorln("remove kubeos-temp container error", err)
}
}()
+ if err := runCommand("docker", "cp", containerId+":/"+neededPath.rootfsFile, neededPath.updatePath); err != nil {
+ return "", err
+ }
return neededPath.tarPath, nil
}
diff --git a/cmd/agent/server/server.go b/cmd/agent/server/server.go
index 8ac6ffd..f8cbb41 100644
--- a/cmd/agent/server/server.go
+++ b/cmd/agent/server/server.go
@@ -112,6 +112,15 @@ func (s *Server) update(req *pb.UpdateRequest) error {
return fmt.Errorf("image type %s cannot be recognized", action)
}
imagePath, err := handler.downloadImage(req)
+ defer func() {
+ if err != nil {
+ path := newPreparePath()
+ if err := cleanSpace(path.updatePath, path.mountPath, path.imagePath); err != nil {
+ logrus.Errorln("clean space error " + err.Error())
+ }
+ logrus.Infoln("clean space success")
+ }
+ }()
if err != nil {
return err
}
diff --git a/cmd/agent/server/utils.go b/cmd/agent/server/utils.go
index b42db18..d2d0946 100644
--- a/cmd/agent/server/utils.go
+++ b/cmd/agent/server/utils.go
@@ -190,26 +190,25 @@ func prepareEnv() (preparePath, error) {
if err := checkDiskSize(needGBSize, PersistDir); err != nil {
return preparePath{}, err
}
- rootfsFile := rootfsArchive
- updatePath := splicePath(PersistDir, updateDir)
- mountPath := splicePath(updatePath, mountDir)
- tarPath := splicePath(updatePath, rootfsFile)
- imagePath := splicePath(PersistDir, osImageName)
-
- if err := cleanSpace(updatePath, mountPath, imagePath); err != nil {
+ upgradePath := newPreparePath()
+ if err := cleanSpace(upgradePath.updatePath, upgradePath.mountPath, upgradePath.imagePath); err != nil {
return preparePath{}, err
}
- if err := os.MkdirAll(mountPath, imgPermission); err != nil {
+ if err := os.MkdirAll(upgradePath.mountPath, imgPermission); err != nil {
return preparePath{}, err
}
- upgradePath := preparePath{
+ return upgradePath, nil
+}
+
+func newPreparePath() preparePath {
+ updatePath := splicePath(PersistDir, updateDir)
+ return preparePath{
updatePath: updatePath,
- mountPath: mountPath,
- tarPath: tarPath,
- imagePath: imagePath,
- rootfsFile: rootfsFile,
+ mountPath: splicePath(updatePath, mountDir),
+ tarPath: splicePath(updatePath, rootfsArchive),
+ imagePath: splicePath(PersistDir, osImageName),
+ rootfsFile: rootfsArchive,
}
- return upgradePath, nil
}
func checkDiskSize(needGBSize int, path string) error {
--
2.39.0

View File

@ -1,20 +0,0 @@
From 9f0f03251a1bd0449f4e7e7ab5699e4771fbaa56 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Fri, 18 Aug 2023 17:19:53 +0800
Subject: [PATCH 15/17] KubeOS: update version
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
VERSION | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/VERSION b/VERSION
index 7dea76e..ee90284 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.1
+1.0.4
--
2.39.0

View File

@ -1,36 +0,0 @@
From 235a13b34e65b8d4ec4bde59e36247445b0778e8 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Tue, 15 Aug 2023 16:24:25 +0800
Subject: [PATCH] KubeOS: add line breaks
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
scripts/admin-container/set-ssh-pub-key.service | 2 +-
scripts/admin-container/set-ssh-pub-key.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/admin-container/set-ssh-pub-key.service b/scripts/admin-container/set-ssh-pub-key.service
index cf21406..84dd12d 100644
--- a/scripts/admin-container/set-ssh-pub-key.service
+++ b/scripts/admin-container/set-ssh-pub-key.service
@@ -12,4 +12,4 @@
Description="set ssh authorized keys according to the secret which is set by user"
[Service]
-ExecStart="/usr/local/bin/set-ssh-pub-key.sh"
\ No newline at end of file
+ExecStart="/usr/local/bin/set-ssh-pub-key.sh"
diff --git a/scripts/admin-container/set-ssh-pub-key.sh b/scripts/admin-container/set-ssh-pub-key.sh
index aa706c2..e91a15d 100755
--- a/scripts/admin-container/set-ssh-pub-key.sh
+++ b/scripts/admin-container/set-ssh-pub-key.sh
@@ -23,4 +23,4 @@ if [ ! -f "$authorized_file" ]; then
chmod 600 "$authorized_file"
fi
-echo "$ssh_pub" >> "$authorized_file"
\ No newline at end of file
+echo "$ssh_pub" >> "$authorized_file"
--
2.39.0

View File

@ -1,46 +0,0 @@
From a01e5ebfd9c314b840eb3a652cda71e33954a403 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Wed, 16 Aug 2023 22:41:44 +0800
Subject: [PATCH 16/17] KubeOS: modify code for clean code
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/agent/server/config.go | 4 ++++
cmd/operator/controllers/os_controller.go | 6 +++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/cmd/agent/server/config.go b/cmd/agent/server/config.go
index 20af267..a96370d 100644
--- a/cmd/agent/server/config.go
+++ b/cmd/agent/server/config.go
@@ -317,6 +317,10 @@ func createConfigPath(configPath string) error {
if err != nil {
return err
}
+ err = f.Chmod(defaultKernelConPermission)
+ if err != nil {
+ return err
+ }
f.Close()
return nil
}
diff --git a/cmd/operator/controllers/os_controller.go b/cmd/operator/controllers/os_controller.go
index 620739b..e152681 100644
--- a/cmd/operator/controllers/os_controller.go
+++ b/cmd/operator/controllers/os_controller.go
@@ -94,7 +94,11 @@ func Reconcile(ctx context.Context, r common.ReadStatusWriter, req ctrl.Request)
func (r *OSReconciler) SetupWithManager(mgr ctrl.Manager) error {
if err := mgr.GetFieldIndexer().IndexField(context.Background(), &upgradev1.OSInstance{}, values.OsiStatusName,
func(rawObj client.Object) []string {
- osi := rawObj.(*upgradev1.OSInstance)
+ osi, ok := rawObj.(*upgradev1.OSInstance)
+ if !ok {
+ log.Error(nil, "failed to convert to osInstance")
+ return []string{}
+ }
return []string{osi.Spec.NodeStatus}
}); err != nil {
return err
--
2.39.0

View File

@ -1,176 +0,0 @@
From 0c0f3c7ef5749b8806511d9e3312f6cacd4cca04 Mon Sep 17 00:00:00 2001
From: liyuanr <liyuanrong1@huawei.com>
Date: Tue, 15 Aug 2023 12:29:11 +0000
Subject: [PATCH 17/17] KubeOS: fix the issue that osinstance is not updated in
time during proxy upgrade.
Fix the problem that osinstance is not updated in time during proxy upgrade,
but the node upgrade tag has been added. As a result, the configuration is skipped
and the upgrade is directly performed.
Signed-off-by: liyuanr <liyuanrong1@huawei.com>
---
cmd/proxy/controllers/os_controller.go | 11 ++
cmd/proxy/controllers/os_controller_test.go | 126 ++++++++++++++++++++
2 files changed, 137 insertions(+)
diff --git a/cmd/proxy/controllers/os_controller.go b/cmd/proxy/controllers/os_controller.go
index 30f9839..b8d0f80 100644
--- a/cmd/proxy/controllers/os_controller.go
+++ b/cmd/proxy/controllers/os_controller.go
@@ -126,6 +126,17 @@ func (r *OSReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Re
}
return values.Requeue, nil
}
+ if _, ok := node.Labels[values.LabelUpgrading]; ok &&
+ osInstance.Spec.NodeStatus == values.NodeStatusIdle.String() {
+ log.Info("node has upgrade label, but osInstance.spec.nodestaus idle ",
+ "operation:", "refesh node and wait opetaot reassgin")
+ if err = r.refreshNode(ctx, &node, osInstance, osCr.Spec.UpgradeConfigs.Version,
+ values.UpgradeConfigName); err != nil {
+ return values.RequeueNow, err
+ }
+ return values.Requeue, nil
+ }
+
if err := r.setConfig(ctx, osInstance, values.UpgradeConfigName); err != nil {
return values.RequeueNow, err
}
diff --git a/cmd/proxy/controllers/os_controller_test.go b/cmd/proxy/controllers/os_controller_test.go
index d63f176..27cb0cd 100644
--- a/cmd/proxy/controllers/os_controller_test.go
+++ b/cmd/proxy/controllers/os_controller_test.go
@@ -1098,4 +1098,130 @@ var _ = Describe("OsController", func() {
Expect(ok).Should(Equal(false))
})
})
+
+ Context("When node has upgrade label but osinstance.spec.nodestatus is idle", func() {
+ It("Should be able to refresh node and wait operator reassgin upgrade", func() {
+ ctx := context.Background()
+ By("Creating a worker node")
+ node1Name = "test-node-" + uuid.New().String()
+ node1 := &v1.Node{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node1Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ "beta.kubernetes.io/os": "linux",
+ values.LabelUpgrading: "",
+ },
+ },
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: "v1",
+ Kind: "Node",
+ },
+ Status: v1.NodeStatus{
+ NodeInfo: v1.NodeSystemInfo{
+ OSImage: "KubeOS v2",
+ },
+ },
+ }
+ err := k8sClient.Create(ctx, node1)
+ Expect(err).ToNot(HaveOccurred())
+ existingNode := &v1.Node{}
+ Eventually(func() bool {
+ err := k8sClient.Get(context.Background(),
+ types.NamespacedName{Name: node1Name, Namespace: testNamespace}, existingNode)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ reconciler.hostName = node1Name
+
+ By("Creating the corresponding OSInstance")
+ OSIns := &upgradev1.OSInstance{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "OSInstance",
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: node1Name,
+ Namespace: testNamespace,
+ Labels: map[string]string{
+ values.LabelOSinstance: node1Name,
+ },
+ },
+ Spec: upgradev1.OSInstanceSpec{
+ NodeStatus: values.NodeStatusIdle.String(),
+ },
+ Status: upgradev1.OSInstanceStatus{},
+ }
+ Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
+
+ // Check that the corresponding OSIns CR has been created
+ osInsCRLookupKey := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
+ createdOSIns := &upgradev1.OSInstance{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node1Name))
+ By("Creating a OS custom resource")
+ OS := &upgradev1.OS{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
+ Kind: "OS",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: OSName,
+ Namespace: testNamespace,
+ },
+ Spec: upgradev1.OSSpec{
+ OpsType: "upgrade",
+ MaxUnavailable: 3,
+ OSVersion: "KubeOS v2",
+ FlagSafe: true,
+ MTLS: false,
+ EvictPodForce: true,
+ SysConfigs: upgradev1.SysConfigs{
+ Version: "v2",
+ Configs: []upgradev1.SysConfig{
+ {
+ Model: "kernel.sysctl",
+ Contents: []upgradev1.Content{
+ {Key: "key1", Value: "c"},
+ {Key: "key2", Value: "d"},
+ },
+ },
+ },
+ },
+ UpgradeConfigs: upgradev1.SysConfigs{
+ Version: "v2",
+ Configs: []upgradev1.SysConfig{
+ {
+ Model: "kernel.sysctl",
+ Contents: []upgradev1.Content{
+ {Key: "key1", Value: "a"},
+ {Key: "key2", Value: "b"},
+ },
+ },
+ },
+ },
+ },
+ }
+ Expect(k8sClient.Create(ctx, OS)).Should(Succeed())
+ osCRLookupKey := types.NamespacedName{Name: OSName, Namespace: testNamespace}
+ createdOS := &upgradev1.OS{}
+ Eventually(func() bool {
+ err := k8sClient.Get(ctx, osCRLookupKey, createdOS)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v2"))
+
+ time.Sleep(2 * time.Second) // sleep a while to make sure Reconcile finished
+ existingNode = &v1.Node{}
+ Eventually(func() bool {
+ err := k8sClient.Get(context.Background(),
+ types.NamespacedName{Name: node1Name, Namespace: testNamespace}, existingNode)
+ return err == nil
+ }, timeout, interval).Should(BeTrue())
+ _, ok := existingNode.Labels[values.LabelUpgrading]
+ Expect(ok).Should(Equal(false))
+ })
+ })
})
--
2.39.0

View File

@ -1,39 +0,0 @@
From 662f68aa131c09154bb91085e4657beaee00d1d6 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Mon, 21 Aug 2023 09:58:45 +0800
Subject: [PATCH 1/5] KubeOS: update config log contents
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/agent/server/config.go | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/cmd/agent/server/config.go b/cmd/agent/server/config.go
index a96370d..f186ee6 100644
--- a/cmd/agent/server/config.go
+++ b/cmd/agent/server/config.go
@@ -57,7 +57,7 @@ func (k KernelSysctl) SetConfig(config *agent.SysConfig) error {
}
logrus.Infof("Configured kernel.sysctl %s=%s", key, keyInfo.Value)
} else {
- logrus.Warnf("Failed to parse kernel.sysctl key: %s value: %s operation: %s", key, keyInfo.Value, keyInfo.Operation)
+ logrus.Warnf("Failed to parse kernel.sysctl, key: %s, value: %s, operation: %s", key, keyInfo.Value, keyInfo.Operation)
}
}
return nil
@@ -97,7 +97,11 @@ type GrubCmdline struct {
// SetConfig sets grub.cmdline configuration
func (g GrubCmdline) SetConfig(config *agent.SysConfig) error {
- logrus.Info("start set grub.cmdline configuration")
+ if g.isCurPartition {
+ logrus.Info("start set grub.cmdline.current configuration")
+ } else {
+ logrus.Info("start set grub.cmdline.next configuration")
+ }
fileExist, err := checkFileExist(getGrubCfgPath())
if err != nil {
logrus.Errorf("Failed to find config path: %v", err)
--
2.39.0

File diff suppressed because it is too large Load Diff

View File

@ -1,86 +0,0 @@
From a9220ad3175c38979a052cd595efd34888d886c6 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Thu, 24 Aug 2023 11:00:04 +0800
Subject: [PATCH 3/5] KubeOS: modify code for clean code
add err handler in NewControllerManager
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/operator/main.go | 6 +++++-
cmd/proxy/main.go | 8 ++++++--
pkg/common/common.go | 7 +++----
3 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/cmd/operator/main.go b/cmd/operator/main.go
index 17b74e1..8249ad2 100644
--- a/cmd/operator/main.go
+++ b/cmd/operator/main.go
@@ -41,7 +41,11 @@ func init() {
}
func main() {
- mgr := common.NewControllerManager(setupLog, scheme)
+ mgr, err := common.NewControllerManager(setupLog, scheme)
+ if err != nil {
+ setupLog.Error(err, "unable to start manager")
+ os.Exit(1)
+ }
if err := (&controllers.OSReconciler{
Client: mgr.GetClient(),
diff --git a/cmd/proxy/main.go b/cmd/proxy/main.go
index ce1f58d..3a537d9 100644
--- a/cmd/proxy/main.go
+++ b/cmd/proxy/main.go
@@ -44,10 +44,14 @@ func init() {
}
func main() {
- mgr := common.NewControllerManager(setupLog, scheme)
+ var err error
+ mgr, err := common.NewControllerManager(setupLog, scheme)
+ if err != nil {
+ setupLog.Error(err, "unable to start manager")
+ os.Exit(1)
+ }
reconciler := controllers.NewOSReconciler(mgr)
- var err error
if reconciler.Connection, err = agentclient.New("unix://" + filepath.Join(server.SockDir, server.SockName)); err != nil {
setupLog.Error(err, "Error running proxy")
}
diff --git a/pkg/common/common.go b/pkg/common/common.go
index 4653a61..e888179 100644
--- a/pkg/common/common.go
+++ b/pkg/common/common.go
@@ -15,7 +15,6 @@ package common
import (
"flag"
- "os"
"github.com/go-logr/logr"
"k8s.io/apimachinery/pkg/runtime"
@@ -33,7 +32,7 @@ type ReadStatusWriter interface {
}
// NewControllerManager configure and return a manager
-func NewControllerManager(setupLog logr.Logger, scheme *runtime.Scheme) manager.Manager {
+func NewControllerManager(setupLog logr.Logger, scheme *runtime.Scheme) (manager.Manager, error) {
opts := zap.Options{}
opts.BindFlags(flag.CommandLine)
@@ -46,7 +45,7 @@ func NewControllerManager(setupLog logr.Logger, scheme *runtime.Scheme) manager.
})
if err != nil {
setupLog.Error(err, "unable to start manager")
- os.Exit(1)
+ return nil, err
}
- return mgr
+ return mgr, nil
}
--
2.39.0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +0,0 @@
From 9a92903712509e32b9ea84f97e35c50b2152389d Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Tue, 5 Sep 2023 12:38:18 +0800
Subject: [PATCH 1/3] KubeOS: fix proxy upgrade requeue bug
fix the bug that proxy doesnt forget ratelimit after updating config
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/proxy/controllers/os_controller.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cmd/proxy/controllers/os_controller.go b/cmd/proxy/controllers/os_controller.go
index d7da343..1153419 100644
--- a/cmd/proxy/controllers/os_controller.go
+++ b/cmd/proxy/controllers/os_controller.go
@@ -101,7 +101,7 @@ func (r *OSReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Re
if err = r.Update(ctx, osInstance); err != nil {
return values.RequeueNow, err
}
- return values.RequeueNow, nil
+ return values.Requeue, nil
}
if err := r.setConfig(ctx, osInstance, values.SysConfigName); err != nil {
return values.RequeueNow, err
--
2.34.1

View File

@ -1,40 +0,0 @@
From 5fce81aeda6498425772d3af2bfa858ba8923140 Mon Sep 17 00:00:00 2001
From: Yuhang Wei <weiyuhang3@huawei.com>
Date: Tue, 5 Sep 2023 17:01:41 +0800
Subject: [PATCH 2/3] KubeOS: fix label changed after upgrade
When upgrading, the label of the new root partition are changed to the original disk information
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
---
cmd/agent/server/utils.go | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/cmd/agent/server/utils.go b/cmd/agent/server/utils.go
index d2d0946..b4a19ff 100644
--- a/cmd/agent/server/utils.go
+++ b/cmd/agent/server/utils.go
@@ -75,6 +75,9 @@ func deleteNewline(out string) string {
}
func install(imagePath string, side string, next string) error {
+ if err := modifyImageLabel(imagePath, side, next); err != nil {
+ return err
+ }
if err := runCommand("dd", "if="+imagePath, "of="+side, "bs=8M"); err != nil {
return err
}
@@ -370,3 +373,10 @@ func getOCIImageDigest(containerRuntime string, imageName string) (string, error
}
return imageDigests, nil
}
+
+func modifyImageLabel(imagePath, side, next string) error {
+ if err := runCommand("e2label", imagePath, "ROOT-"+next); err != nil {
+ return err
+ }
+ return nil
+}
--
2.34.1

View File

@ -1,39 +1,17 @@
# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
Name: KubeOS
Version: 1.0.4
Release: 4
Version: 1.0.5
Release: 1
Summary: O&M platform used to update the whole OS as an entirety
License: Mulan PSL v2
Source0: https://gitee.com/openeuler/KubeOS/repository/archive/v%{version}.tar.gz
Patch1: 0001-KubeOS-add-unit-tests-of-containerd-and-docker-modif.patch
Patch2: 0002-KubeOS-refactor-assignUpgrade-function.patch
Patch3: 0003-KubeOS-fix-the-hostshell-cannot-obtain-the-lib.patch
Patch4: 0004-KubeOS-add-agent-proxy-and-operator-ut.patch
Patch5: 0005-KubeOS-fix-validate-image-name-bug.patch
Patch6: 0006-KubeOS-fix-a-bug-that-failed-to-parse-key-with.patch
Patch7: 0007-KubeOS-add-warning-log-during-config.patch
Patch8: 0008-KubeOS-modify-log-level-and-content.patch
Patch9: 0009-KubeOS-fix-updating-key-to-kv.patch
Patch10: 0010-KubeOS-fix-proxy-requeue-bug.patch
Patch11: 0011-KubeOS-fix-operator-bug-of-missing-deep-copy.patch
Patch12: 0012-KubeOS-add-unit-test.patch
Patch13: 0013-KubeOS-fix-clean-space-problems.patch
Patch14: 0014-KubeOS-update-version.patch
Patch15: 0015-KubeOS-add-line-breaks.patch
Patch16: 0016-KubeOS-modify-code-for-clean-code.patch
Patch17: 0017-KubeOS-fix-the-issue-that-osinstance-is-not-updated-.patch
Patch18: 0018-KubeOS-update-config-log-contents.patch
Patch19: 0019-KubeOS-add-unit-tests.patch
Patch20: 0020-KubeOS-modify-code-for-clean-code.patch
Patch21: 0021-KubeOS-delete-raw-and-docker-image-upgrade.patch
Patch22: 0022-KubeOS-delete-scripts-except-admin-container.patch
Patch23: 0023-KubeOS-fix-proxy-upgrade-requeue-bug.patch
Patch24: 0024-KubeOS-fix-label-changed-after-upgrade.patch
Patch1: 0001-build-rust-os-agent-remove-useless-dependency.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: make
BuildRequires: make rust cargo openssl-devel
BuildRequires: golang >= 1.13
%description
This is an O&M platform used to update the whole OS as an entirety,
it should be running in kubernetes environment.
@ -41,15 +19,11 @@ it should be running in kubernetes environment.
%prep
%autosetup -n %{name}-v%{version} -p1
%package agent
Summary: agent provides os-agent and related service files which are needed on nodes
%description agent
The agent package includes os-agent and service files
%package admin-container
Summary: admin-container contains hostshell and set-ssh-pub-key script and service file
%description admin-container
The agent package includes hostshell and set-ssh-pub-key script and service file
%package scripts
Summary: Scripts to build the os image and binaries of os-proxy and os-operator
Requires: qemu-img, parted, bc, tar, docker, dosfstools
%description scripts
The scripts package includes scripts which could build the os image and binaries of os-proxy and os-operator
%define debug_package %{nil}
%define __debug_install_post \
@ -57,55 +31,110 @@ The agent package includes hostshell and set-ssh-pub-key script and service file
%{nil}
%build
mkdir ./KubeOS-Rust/.cargo
cat << EOF >> ./KubeOS-Rust/.cargo/config
[source.crates-io]
replace-with = "vendored-sources"
[source.vendored-sources]
directory = "vendor"
EOF
make
%install
install -d -m 0740 %{buildroot}/opt/kubeOS/bin
install -p -m 0500 ./bin/proxy %{buildroot}/opt/kubeOS/bin
install -p -m 0500 ./bin/operator %{buildroot}/opt/kubeOS/bin
#kubeos-agent
install -d %{buildroot}%{_bindir}
install -d %{buildroot}%{_prefix}/lib/systemd/system
install -p -m 0500 ./bin/os-agent %{buildroot}%{_bindir}
install -p -m 0600 ./files/boot-efi.mount %{buildroot}%{_prefix}/lib/systemd/system
install -p -m 0600 ./files/etc.mount %{buildroot}%{_prefix}/lib/systemd/system
install -p -m 0600 ./files/persist.mount %{buildroot}%{_prefix}/lib/systemd/system
install -p -m 0600 ./files/var.mount %{buildroot}%{_prefix}/lib/systemd/system
install -p -m 0600 ./files/os-agent.service %{buildroot}%{_prefix}/lib/systemd/system
install -p -m 0600 ./files/os-release %{buildroot}%{_prefix}/lib/
#install binary
install -d -m 0740 %{buildroot}/opt/kubeOS/bin
install -p -m 0500 ./bin/rust/release/os-agent %{buildroot}/opt/kubeOS/bin
install -p -m 0500 ./bin/rust/release/proxy %{buildroot}/opt/kubeOS/bin
install -p -m 0500 ./bin/operator %{buildroot}/opt/kubeOS/bin
install -p -m 0500 ./bin/hostshell %{buildroot}/opt/kubeOS/bin
#kubeos-admin-container
install -p -m 0500 ./bin/hostshell %{buildroot}%{_bindir}
install -d %{buildroot}%{_prefix}/local/bin
install -p -m 0500 ./scripts/admin-container/set-ssh-pub-key.sh %{buildroot}%{_prefix}/local/bin
install -d %{buildroot}%{_prefix}/lib/sysmaster
install -p -m 0600 ./scripts/admin-container/set-ssh-pub-key.service %{buildroot}%{_prefix}/lib/sysmaster
#install artifacts
install -d -m 0740 %{buildroot}/opt/kubeOS/scripts
install -p -m 0600 ./scripts/rpmlist %{buildroot}/opt/kubeOS/scripts
install -p -m 0500 ./scripts/kbimg.sh %{buildroot}/opt/kubeOS/scripts
install -p -m 0500 ./scripts/set_in_chroot.sh %{buildroot}/opt/kubeOS/scripts
install -p -m 0600 ./scripts/grub.cfg %{buildroot}/opt/kubeOS/scripts
install -p -m 0500 ./scripts/bootloader.sh %{buildroot}/opt/kubeOS/scripts
install -p -m 0500 ./scripts/Dockerfile %{buildroot}/opt/kubeOS/scripts
install -d -m 0740 %{buildroot}/opt/kubeOS/scripts/common
install -p -m 0500 ./scripts/common/globalVariables.sh %{buildroot}/opt/kubeOS/scripts/common
install -p -m 0500 ./scripts/common/log.sh %{buildroot}/opt/kubeOS/scripts/common
install -p -m 0500 ./scripts/common/utils.sh %{buildroot}/opt/kubeOS/scripts/common
install -d -m 0740 %{buildroot}/opt/kubeOS/scripts/create
install -p -m 0500 ./scripts/create/imageCreate.sh %{buildroot}/opt/kubeOS/scripts/create
install -p -m 0500 ./scripts/create/rootfsCreate.sh %{buildroot}/opt/kubeOS/scripts/create
install -d -m 0740 %{buildroot}/opt/kubeOS/scripts/00bootup
install -p -m 0600 ./scripts/00bootup/Global.cfg %{buildroot}/opt/kubeOS/scripts/00bootup
install -p -m 0500 ./scripts/00bootup/module-setup.sh %{buildroot}/opt/kubeOS/scripts/00bootup
install -p -m 0500 ./scripts/00bootup/mount.sh %{buildroot}/opt/kubeOS/scripts/00bootup
install -d -m 0740 %{buildroot}/opt/kubeOS/scripts/admin-container
install -p -m 0500 ./scripts/admin-container/set-ssh-pub-key.sh %{buildroot}/opt/kubeOS/scripts/admin-container
install -p -m 0600 ./scripts/admin-container/set-ssh-pub-key.service %{buildroot}/opt/kubeOS/scripts/admin-container
install -p -m 0500 ./scripts/admin-container/Dockerfile %{buildroot}/opt/kubeOS/scripts/admin-container
install -d -m 0740 %{buildroot}/opt/kubeOS/files
install -p -m 0600 ./files/boot-efi.mount %{buildroot}/opt/kubeOS/files
install -p -m 0600 ./files/etc.mount %{buildroot}/opt/kubeOS/files
install -p -m 0600 ./files/persist.mount %{buildroot}/opt/kubeOS/files
install -p -m 0600 ./files/var.mount %{buildroot}/opt/kubeOS/files
install -p -m 0600 ./files/os-agent.service %{buildroot}/opt/kubeOS/files
install -p -m 0600 ./files/os-release %{buildroot}/opt/kubeOS/files
%files
%defattr(-,root,root,0500)
%attr(0500,root,root) /opt/kubeOS/bin/os-agent
%attr(0500,root,root) /opt/kubeOS/bin/hostshell
%attr(0500,root,root) /opt/kubeOS/bin/proxy
%attr(0500,root,root) /opt/kubeOS/bin/operator
%attr(0600,root,root) /opt/kubeOS/files/boot-efi.mount
%attr(0600,root,root) /opt/kubeOS/files/etc.mount
%attr(0600,root,root) /opt/kubeOS/files/persist.mount
%attr(0600,root,root) /opt/kubeOS/files/var.mount
%attr(0600,root,root) /opt/kubeOS/files/os-agent.service
%attr(0600,root,root) /opt/kubeOS/files/os-release
%files agent
%attr(0500,root,root) %{_bindir}/os-agent
%files scripts
%defattr(-,root,root,0500)
%attr(0600,root,root) %{_prefix}/lib/systemd/system/boot-efi.mount
%attr(0600,root,root) %{_prefix}/lib/systemd/system/etc.mount
%attr(0600,root,root) %{_prefix}/lib/systemd/system/persist.mount
%attr(0600,root,root) %{_prefix}/lib/systemd/system/var.mount
%attr(0600,root,root) %{_prefix}/lib/systemd/system/os-agent.service
%attr(0600,root,root) %{_prefix}/lib/os-release
%attr(0600,root,root) /opt/kubeOS/scripts/rpmlist
%attr(0500,root,root) /opt/kubeOS/scripts/kbimg.sh
%attr(0500,root,root) /opt/kubeOS/scripts/set_in_chroot.sh
%attr(0600,root,root) /opt/kubeOS/scripts/grub.cfg
%attr(0500,root,root) /opt/kubeOS/scripts/bootloader.sh
%attr(0500,root,root) /opt/kubeOS/scripts/Dockerfile
%files admin-container
%attr(0500,root,root) %{_bindir}/hostshell
%defattr(-,root,root,0500)
%attr(0500,root,root) %{_prefix}/local/bin/set-ssh-pub-key.sh
%attr(0600,root,root) %{_prefix}/lib/sysmaster/set-ssh-pub-key.service
%attr(0500,root,root) /opt/kubeOS/scripts/common/globalVariables.sh
%attr(0500,root,root) /opt/kubeOS/scripts/common/log.sh
%attr(0500,root,root) /opt/kubeOS/scripts/common/utils.sh
%attr(0500,root,root) /opt/kubeOS/scripts/create/imageCreate.sh
%attr(0500,root,root) /opt/kubeOS/scripts/create/rootfsCreate.sh
%attr(0600,root,root) /opt/kubeOS/scripts/00bootup/Global.cfg
%attr(0500,root,root) /opt/kubeOS/scripts/00bootup/module-setup.sh
%attr(0500,root,root) /opt/kubeOS/scripts/00bootup/mount.sh
%attr(0500,root,root) /opt/kubeOS/scripts/admin-container/set-ssh-pub-key.sh
%attr(0500,root,root) /opt/kubeOS/scripts/admin-container/Dockerfile
%attr(0600,root,root) /opt/kubeOS/scripts/admin-container/set-ssh-pub-key.service
%clean
rm -rfv %{buildroot}
%changelog
* Wed Jan 10 2024 Yuhang Wei<weiyuhang3@huawei.com> - 1.0.5-1
- Type:requirement
- CVE:NA
- SUG:restart
- DESC:update version to 1.0.5.1
* Tue Sep 05 2023 Yuhang Wei<weiyuhang3@huawei.com> - 1.0.4-4
- Type:requirement
- CVE:NA

Binary file not shown.

BIN
v1.0.5.tar.gz Normal file

Binary file not shown.