KubeOS:sync code from source master branch
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
This commit is contained in:
parent
fbb9b2debd
commit
1d36b74685
479
0001-KubeOS-add-unit-tests-of-containerd-and-docker-modif.patch
Normal file
479
0001-KubeOS-add-unit-tests-of-containerd-and-docker-modif.patch
Normal file
@ -0,0 +1,479 @@
|
|||||||
|
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
|
||||||
|
|
||||||
346
0002-KubeOS-refactor-assignUpgrade-function.patch
Normal file
346
0002-KubeOS-refactor-assignUpgrade-function.patch
Normal file
@ -0,0 +1,346 @@
|
|||||||
|
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
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
From 470e190db2de92b65e7fa720864823e7245c51e9 Mon Sep 17 00:00:00 2001
|
From 470e190db2de92b65e7fa720864823e7245c51e9 Mon Sep 17 00:00:00 2001
|
||||||
From: liyuanr <liyuanrong1@huawei.com>
|
From: liyuanr <liyuanrong1@huawei.com>
|
||||||
Date: Mon, 7 Aug 2023 19:09:18 +0800
|
Date: Mon, 7 Aug 2023 19:09:18 +0800
|
||||||
Subject: [PATCH] KubeOS: fix the hostshell cannot obtain the lib
|
Subject: [PATCH 03/17] KubeOS: fix the hostshell cannot obtain the lib
|
||||||
|
|
||||||
Fix the hostshell cannot obtain the lib
|
Fix the hostshell cannot obtain the lib
|
||||||
|
|
||||||
@ -71,5 +71,5 @@ index f6a7293..5fa0838 100644
|
|||||||
+ return pathEnv
|
+ return pathEnv
|
||||||
+}
|
+}
|
||||||
--
|
--
|
||||||
2.33.0.windows.2
|
2.39.0
|
||||||
|
|
||||||
1413
0004-KubeOS-add-agent-proxy-and-operator-ut.patch
Normal file
1413
0004-KubeOS-add-agent-proxy-and-operator-ut.patch
Normal file
File diff suppressed because it is too large
Load Diff
155
0005-KubeOS-fix-validate-image-name-bug.patch
Normal file
155
0005-KubeOS-fix-validate-image-name-bug.patch
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
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
|
||||||
|
|
||||||
156
0006-KubeOS-fix-a-bug-that-failed-to-parse-key-with.patch
Normal file
156
0006-KubeOS-fix-a-bug-that-failed-to-parse-key-with.patch
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
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
|
||||||
|
|
||||||
52
0007-KubeOS-add-warning-log-during-config.patch
Normal file
52
0007-KubeOS-add-warning-log-during-config.patch
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
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
|
||||||
|
|
||||||
26
0008-KubeOS-modify-log-level-and-content.patch
Normal file
26
0008-KubeOS-modify-log-level-and-content.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
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
|
||||||
|
|
||||||
151
0009-KubeOS-fix-updating-key-to-kv.patch
Normal file
151
0009-KubeOS-fix-updating-key-to-kv.patch
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
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
|
||||||
|
|
||||||
37
0010-KubeOS-fix-proxy-requeue-bug.patch
Normal file
37
0010-KubeOS-fix-proxy-requeue-bug.patch
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
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
|
||||||
|
|
||||||
665
0011-KubeOS-fix-operator-bug-of-missing-deep-copy.patch
Normal file
665
0011-KubeOS-fix-operator-bug-of-missing-deep-copy.patch
Normal file
@ -0,0 +1,665 @@
|
|||||||
|
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
|
||||||
|
|
||||||
191
0012-KubeOS-add-unit-test.patch
Normal file
191
0012-KubeOS-add-unit-test.patch
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
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
|
||||||
|
|
||||||
126
0013-KubeOS-fix-clean-space-problems.patch
Normal file
126
0013-KubeOS-fix-clean-space-problems.patch
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
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
|
||||||
|
|
||||||
20
0014-KubeOS-update-version.patch
Normal file
20
0014-KubeOS-update-version.patch
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
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
|
||||||
|
|
||||||
36
0015-KubeOS-add-line-breaks.patch
Normal file
36
0015-KubeOS-add-line-breaks.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
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
|
||||||
|
|
||||||
46
0016-KubeOS-modify-code-for-clean-code.patch
Normal file
46
0016-KubeOS-modify-code-for-clean-code.patch
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
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
|
||||||
|
|
||||||
176
0017-KubeOS-fix-the-issue-that-osinstance-is-not-updated-.patch
Normal file
176
0017-KubeOS-fix-the-issue-that-osinstance-is-not-updated-.patch
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
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
|
||||||
|
|
||||||
39
0018-KubeOS-update-config-log-contents.patch
Normal file
39
0018-KubeOS-update-config-log-contents.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
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
|
||||||
|
|
||||||
1069
0019-KubeOS-add-unit-tests.patch
Normal file
1069
0019-KubeOS-add-unit-tests.patch
Normal file
File diff suppressed because it is too large
Load Diff
86
0020-KubeOS-modify-code-for-clean-code.patch
Normal file
86
0020-KubeOS-modify-code-for-clean-code.patch
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
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
|
||||||
|
|
||||||
1867
0021-KubeOS-delete-raw-and-docker-image-upgrade.patch
Normal file
1867
0021-KubeOS-delete-raw-and-docker-image-upgrade.patch
Normal file
File diff suppressed because it is too large
Load Diff
1671
0022-KubeOS-delete-scripts-except-admin-container.patch
Normal file
1671
0022-KubeOS-delete-scripts-except-admin-container.patch
Normal file
File diff suppressed because it is too large
Load Diff
31
KubeOS.spec
31
KubeOS.spec
@ -2,11 +2,32 @@
|
|||||||
|
|
||||||
Name: KubeOS
|
Name: KubeOS
|
||||||
Version: 1.0.4
|
Version: 1.0.4
|
||||||
Release: 2
|
Release: 3
|
||||||
Summary: O&M platform used to update the whole OS as an entirety
|
Summary: O&M platform used to update the whole OS as an entirety
|
||||||
License: Mulan PSL v2
|
License: Mulan PSL v2
|
||||||
Source0: https://gitee.com/openeuler/KubeOS/repository/archive/v%{version}.tar.gz
|
Source0: https://gitee.com/openeuler/KubeOS/repository/archive/v%{version}.tar.gz
|
||||||
Patch1: 0001-KubeOS-fix-the-hostshell-cannot-obtain-the-lib.patch
|
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
|
||||||
|
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
BuildRequires: make
|
BuildRequires: make
|
||||||
@ -83,6 +104,12 @@ install -p -m 0600 ./scripts/admin-container/set-ssh-pub-key.service %{buildroot
|
|||||||
rm -rfv %{buildroot}
|
rm -rfv %{buildroot}
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Aug 24 2023 Yuhang Wei<weiyuhang3@huawei.com> - 1.0.4-3
|
||||||
|
- Type:requirement
|
||||||
|
- CVE:NA
|
||||||
|
- SUG:restart
|
||||||
|
- DESC:sync code from source master branch
|
||||||
|
|
||||||
* Mon Aug 07 2023 liyuanrong<liyuanrong1@huawei.com> - 1.0.4-2
|
* Mon Aug 07 2023 liyuanrong<liyuanrong1@huawei.com> - 1.0.4-2
|
||||||
- Type:requirement
|
- Type:requirement
|
||||||
- CVE:NA
|
- CVE:NA
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user