KubeOS: update to new release 1.0.5
update KubeOS to v1.0.5 Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
This commit is contained in:
parent
db4b835145
commit
07641b4290
@ -1,479 +0,0 @@
|
|||||||
From 790d53dc581874575aef1777122856a59bcdbf8b Mon Sep 17 00:00:00 2001
|
|
||||||
From: liyuanr <liyuanrong1@huawei.com>
|
|
||||||
Date: Thu, 3 Aug 2023 22:18:23 +0800
|
|
||||||
Subject: [PATCH 01/17] KubeOS:add unit tests of containerd and docker,modify
|
|
||||||
code for cleancode
|
|
||||||
|
|
||||||
Add unit tests of using containerd or docker to upgrade.
|
|
||||||
Modify code for cleancode and fix issue of ctr images pull
|
|
||||||
|
|
||||||
Signed-off-by: liyuanr <liyuanrong1@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/agent/server/containerd_image.go | 8 +-
|
|
||||||
cmd/agent/server/containerd_image_test.go | 139 ++++++++++++++++++++++
|
|
||||||
cmd/agent/server/docker_image.go | 2 +-
|
|
||||||
cmd/agent/server/docker_image_test.go | 88 ++++++++++++--
|
|
||||||
cmd/agent/server/utils.go | 102 ++++++++--------
|
|
||||||
5 files changed, 272 insertions(+), 67 deletions(-)
|
|
||||||
create mode 100644 cmd/agent/server/containerd_image_test.go
|
|
||||||
|
|
||||||
diff --git a/cmd/agent/server/containerd_image.go b/cmd/agent/server/containerd_image.go
|
|
||||||
index f180fb5..fd61274 100644
|
|
||||||
--- a/cmd/agent/server/containerd_image.go
|
|
||||||
+++ b/cmd/agent/server/containerd_image.go
|
|
||||||
@@ -23,9 +23,7 @@ import (
|
|
||||||
pb "openeuler.org/KubeOS/cmd/agent/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
-var (
|
|
||||||
- defaultNamespace = "k8s.io"
|
|
||||||
-)
|
|
||||||
+const defaultNamespace = "k8s.io"
|
|
||||||
|
|
||||||
type conImageHandler struct{}
|
|
||||||
|
|
||||||
@@ -56,7 +54,7 @@ func (c conImageHandler) getRootfsArchive(req *pb.UpdateRequest, neededPath prep
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
containerdCommand = "ctr"
|
|
||||||
- if err := runCommand("ctr", "-n", defaultNamespace, "images", "pull", "--host-dir",
|
|
||||||
+ if err := runCommand("ctr", "-n", defaultNamespace, "images", "pull", "--hosts-dir",
|
|
||||||
"/etc/containerd/certs.d", imageName); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
@@ -76,7 +74,7 @@ func (c conImageHandler) getRootfsArchive(req *pb.UpdateRequest, neededPath prep
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer checkAndCleanMount(mountPath)
|
|
||||||
- if err := copyFile(neededPath.tarPath, mountPath+"/"+rootfsArchive); err != nil {
|
|
||||||
+ if err := copyFile(neededPath.tarPath, mountPath+"/"+neededPath.rootfsFile); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return "", nil
|
|
||||||
diff --git a/cmd/agent/server/containerd_image_test.go b/cmd/agent/server/containerd_image_test.go
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..d7133c3
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/cmd/agent/server/containerd_image_test.go
|
|
||||||
@@ -0,0 +1,139 @@
|
|
||||||
+/*
|
|
||||||
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
|
|
||||||
+ * KubeOS is licensed under the Mulan PSL v2.
|
|
||||||
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
+ * You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
+ * http://license.coscl.org.cn/MulanPSL2
|
|
||||||
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
|
||||||
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
|
||||||
+ * PURPOSE.
|
|
||||||
+ * See the Mulan PSL v2 for more details.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+// Package server implements server of os-agent and listener of os-agent server. The server uses gRPC interface.
|
|
||||||
+package server
|
|
||||||
+
|
|
||||||
+import (
|
|
||||||
+ "os"
|
|
||||||
+ "testing"
|
|
||||||
+
|
|
||||||
+ "github.com/agiledragon/gomonkey/v2"
|
|
||||||
+ pb "openeuler.org/KubeOS/cmd/agent/api"
|
|
||||||
+)
|
|
||||||
+
|
|
||||||
+func Test_conImageHandler_downloadImage(t *testing.T) {
|
|
||||||
+ type args struct {
|
|
||||||
+ req *pb.UpdateRequest
|
|
||||||
+ }
|
|
||||||
+ tests := []struct {
|
|
||||||
+ name string
|
|
||||||
+ c conImageHandler
|
|
||||||
+ args args
|
|
||||||
+ want string
|
|
||||||
+ wantErr bool
|
|
||||||
+ }{
|
|
||||||
+
|
|
||||||
+ {
|
|
||||||
+ name: "pullImageError",
|
|
||||||
+ c: conImageHandler{},
|
|
||||||
+ args: args{
|
|
||||||
+ req: &pb.UpdateRequest{ContainerImage: "testError"},
|
|
||||||
+ },
|
|
||||||
+ want: "",
|
|
||||||
+ wantErr: true,
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ name: "checkSumError",
|
|
||||||
+ c: conImageHandler{},
|
|
||||||
+ args: args{
|
|
||||||
+ req: &pb.UpdateRequest{ContainerImage: "docker.io/library/hello-world:latest"},
|
|
||||||
+ },
|
|
||||||
+ want: "",
|
|
||||||
+ wantErr: true,
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ name: "normal",
|
|
||||||
+ c: conImageHandler{},
|
|
||||||
+ args: args{
|
|
||||||
+ req: &pb.UpdateRequest{
|
|
||||||
+ ContainerImage: "docker.io/library/hello-world:latest",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ want: "update-test1/upadte.img",
|
|
||||||
+ wantErr: false,
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ patchPrepareEnv := gomonkey.ApplyFunc(prepareEnv, func() (preparePath, error) {
|
|
||||||
+ return preparePath{updatePath: "update-test1/",
|
|
||||||
+ mountPath: "update-test1/mountPath",
|
|
||||||
+ tarPath: "update-test1/mountPath/hello",
|
|
||||||
+ imagePath: "update-test1/upadte.img",
|
|
||||||
+ rootfsFile: "hello"}, nil
|
|
||||||
+ })
|
|
||||||
+ defer patchPrepareEnv.Reset()
|
|
||||||
+ patchCreateOSImage := gomonkey.ApplyFunc(createOSImage, func(neededPath preparePath) (string, error) {
|
|
||||||
+ return "update-test1/upadte.img", nil
|
|
||||||
+ })
|
|
||||||
+ defer patchCreateOSImage.Reset()
|
|
||||||
+
|
|
||||||
+ if err := os.MkdirAll("update-test1/mountPath", os.ModePerm); err != nil {
|
|
||||||
+ t.Errorf("create test dir error = %v", err)
|
|
||||||
+ return
|
|
||||||
+ }
|
|
||||||
+ for _, tt := range tests {
|
|
||||||
+ t.Run(tt.name, func(t *testing.T) {
|
|
||||||
+ c := conImageHandler{}
|
|
||||||
+ if tt.name == "normal" {
|
|
||||||
+ imageDigests, err := getOCIImageDigest("crictl", "docker.io/library/hello-world:latest")
|
|
||||||
+ if err != nil {
|
|
||||||
+ t.Errorf("conImageHandler.getRootfsArchive() get oci image digests error = %v", err)
|
|
||||||
+ }
|
|
||||||
+ tt.args.req.CheckSum = imageDigests
|
|
||||||
+ }
|
|
||||||
+ got, err := c.downloadImage(tt.args.req)
|
|
||||||
+ if (err != nil) != tt.wantErr {
|
|
||||||
+ t.Errorf("conImageHandler.downloadImage() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
+ return
|
|
||||||
+ }
|
|
||||||
+ if got != tt.want {
|
|
||||||
+ t.Errorf("conImageHandler.downloadImage() = %v, want %v", got, tt.want)
|
|
||||||
+ }
|
|
||||||
+ })
|
|
||||||
+ }
|
|
||||||
+ defer func() {
|
|
||||||
+ if err := runCommand("crictl", "rmi", "docker.io/library/hello-world:latest"); err != nil {
|
|
||||||
+ t.Errorf("remove kubeos-temp container error = %v", err)
|
|
||||||
+ }
|
|
||||||
+ if err := os.RemoveAll("update-test1"); err != nil {
|
|
||||||
+ t.Errorf("remove update-test error = %v", err)
|
|
||||||
+ }
|
|
||||||
+ }()
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+func Test_copyFile(t *testing.T) {
|
|
||||||
+ type args struct {
|
|
||||||
+ dstFileName string
|
|
||||||
+ srcFileName string
|
|
||||||
+ }
|
|
||||||
+ tests := []struct {
|
|
||||||
+ name string
|
|
||||||
+ args args
|
|
||||||
+ wantErr bool
|
|
||||||
+ }{
|
|
||||||
+ {
|
|
||||||
+ name: "srcFileNotExist",
|
|
||||||
+ args: args{
|
|
||||||
+ dstFileName: "bbb.txt",
|
|
||||||
+ srcFileName: "aaa.txt",
|
|
||||||
+ },
|
|
||||||
+ wantErr: true,
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ for _, tt := range tests {
|
|
||||||
+ t.Run(tt.name, func(t *testing.T) {
|
|
||||||
+ if err := copyFile(tt.args.dstFileName, tt.args.srcFileName); (err != nil) != tt.wantErr {
|
|
||||||
+ t.Errorf("copyFile() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
+ }
|
|
||||||
+ })
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
diff --git a/cmd/agent/server/docker_image.go b/cmd/agent/server/docker_image.go
|
|
||||||
index 23e596b..0b6ee35 100644
|
|
||||||
--- a/cmd/agent/server/docker_image.go
|
|
||||||
+++ b/cmd/agent/server/docker_image.go
|
|
||||||
@@ -61,7 +61,7 @@ func (d dockerImageHandler) getRootfsArchive(req *pb.UpdateRequest, neededPath p
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
- if err := runCommand("docker", "cp", containerId+":/"+rootfsArchive, neededPath.updatePath); err != nil {
|
|
||||||
+ if err := runCommand("docker", "cp", containerId+":/"+neededPath.rootfsFile, neededPath.updatePath); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
diff --git a/cmd/agent/server/docker_image_test.go b/cmd/agent/server/docker_image_test.go
|
|
||||||
index 9987939..2dbf337 100644
|
|
||||||
--- a/cmd/agent/server/docker_image_test.go
|
|
||||||
+++ b/cmd/agent/server/docker_image_test.go
|
|
||||||
@@ -17,38 +17,102 @@ import (
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
+ "github.com/agiledragon/gomonkey/v2"
|
|
||||||
pb "openeuler.org/KubeOS/cmd/agent/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
-func TestpullOSImage(t *testing.T) {
|
|
||||||
+func Test_dockerImageHandler_downloadImage(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
req *pb.UpdateRequest
|
|
||||||
}
|
|
||||||
- os.Mkdir("/persist", os.ModePerm)
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
+ d dockerImageHandler
|
|
||||||
args args
|
|
||||||
want string
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
- {name: "pull image error", args: args{req: &pb.UpdateRequest{
|
|
||||||
- DockerImage: "test",
|
|
||||||
- }}, want: "", wantErr: true},
|
|
||||||
- {name: "normal", args: args{req: &pb.UpdateRequest{
|
|
||||||
- DockerImage: "centos",
|
|
||||||
- }}, want: "/persist/update.img", wantErr: false},
|
|
||||||
+ {
|
|
||||||
+ name: "pullImageError",
|
|
||||||
+ d: dockerImageHandler{},
|
|
||||||
+ args: args{
|
|
||||||
+ req: &pb.UpdateRequest{ContainerImage: "testError"},
|
|
||||||
+ },
|
|
||||||
+ want: "",
|
|
||||||
+ wantErr: true,
|
|
||||||
+ },
|
|
||||||
+
|
|
||||||
+ {
|
|
||||||
+ name: "checkSumError",
|
|
||||||
+ d: dockerImageHandler{},
|
|
||||||
+ args: args{
|
|
||||||
+ req: &pb.UpdateRequest{ContainerImage: "hello-world", CheckSum: "aaaaaa"},
|
|
||||||
+ },
|
|
||||||
+ want: "",
|
|
||||||
+ wantErr: true,
|
|
||||||
+ },
|
|
||||||
+
|
|
||||||
+ {
|
|
||||||
+ name: "normal",
|
|
||||||
+ d: dockerImageHandler{},
|
|
||||||
+ args: args{
|
|
||||||
+ req: &pb.UpdateRequest{ContainerImage: "hello-world"},
|
|
||||||
+ },
|
|
||||||
+ want: "update-test/upadte.img",
|
|
||||||
+ wantErr: false,
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ patchPrepareEnv := gomonkey.ApplyFunc(prepareEnv, func() (preparePath, error) {
|
|
||||||
+ return preparePath{updatePath: "update-test/",
|
|
||||||
+ mountPath: "update-test/mountPath",
|
|
||||||
+ tarPath: "update-test/mountPath/hello",
|
|
||||||
+ imagePath: "update-test/upadte.img",
|
|
||||||
+ rootfsFile: "hello"}, nil
|
|
||||||
+ })
|
|
||||||
+ defer patchPrepareEnv.Reset()
|
|
||||||
+
|
|
||||||
+ patchCreateOSImage := gomonkey.ApplyFunc(createOSImage, func(neededPath preparePath) (string, error) {
|
|
||||||
+ return "update-test/upadte.img", nil
|
|
||||||
+ })
|
|
||||||
+ defer patchCreateOSImage.Reset()
|
|
||||||
+
|
|
||||||
+ if err := os.MkdirAll("update-test/mountPath", os.ModePerm); err != nil {
|
|
||||||
+ t.Errorf("create test dir error = %v", err)
|
|
||||||
+ return
|
|
||||||
}
|
|
||||||
+
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
- got, err := pullOSImage(tt.args.req)
|
|
||||||
+ if tt.name == "normal" {
|
|
||||||
+ _, err := runCommandWithOut("docker", "create", "--name", "kubeos-temp", "hello-world")
|
|
||||||
+ if err != nil {
|
|
||||||
+ t.Errorf("Test_dockerImageHandler_getRootfsArchive create container error = %v", err)
|
|
||||||
+ return
|
|
||||||
+ }
|
|
||||||
+ imageDigests, err := getOCIImageDigest("docker", "hello-world")
|
|
||||||
+
|
|
||||||
+ if err != nil {
|
|
||||||
+ t.Errorf("Test_dockerImageHandler_getRootfsArchive get oci image digests error = %v", err)
|
|
||||||
+ }
|
|
||||||
+ tt.args.req.CheckSum = imageDigests
|
|
||||||
+ }
|
|
||||||
+ d := dockerImageHandler{}
|
|
||||||
+ got, err := d.downloadImage(tt.args.req)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
- t.Errorf("pullOSImage() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
+ t.Errorf("dockerImageHandler.downloadImage() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if got != tt.want {
|
|
||||||
- t.Errorf("pullOSImage() = %v, want %v", got, tt.want)
|
|
||||||
+ t.Errorf("dockerImageHandler.downloadImage() = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
- defer os.RemoveAll("/persist")
|
|
||||||
+ defer func() {
|
|
||||||
+ if err := runCommand("docker", "rmi", "hello-world"); err != nil {
|
|
||||||
+ t.Errorf("remove kubeos-temp container error = %v", err)
|
|
||||||
+ }
|
|
||||||
+ if err := os.RemoveAll("update-test"); err != nil {
|
|
||||||
+ t.Errorf("remove update-test error = %v", err)
|
|
||||||
+ }
|
|
||||||
+ }()
|
|
||||||
}
|
|
||||||
diff --git a/cmd/agent/server/utils.go b/cmd/agent/server/utils.go
|
|
||||||
index c8a72c3..7134d74 100644
|
|
||||||
--- a/cmd/agent/server/utils.go
|
|
||||||
+++ b/cmd/agent/server/utils.go
|
|
||||||
@@ -31,10 +31,7 @@ import (
|
|
||||||
const (
|
|
||||||
needGBSize = 3 // the max size of update files needed
|
|
||||||
// KB is 1024 B
|
|
||||||
- KB = 1024
|
|
||||||
-)
|
|
||||||
-
|
|
||||||
-var (
|
|
||||||
+ KB = 1024
|
|
||||||
rootfsArchive = "os.tar"
|
|
||||||
updateDir = "KubeOS-Update"
|
|
||||||
mountDir = "kubeos-update"
|
|
||||||
@@ -51,6 +48,7 @@ type preparePath struct {
|
|
||||||
mountPath string
|
|
||||||
tarPath string
|
|
||||||
imagePath string
|
|
||||||
+ rootfsFile string
|
|
||||||
}
|
|
||||||
|
|
||||||
func runCommand(name string, args ...string) error {
|
|
||||||
@@ -192,9 +190,10 @@ func prepareEnv() (preparePath, error) {
|
|
||||||
if err := checkDiskSize(needGBSize, PersistDir); err != nil {
|
|
||||||
return preparePath{}, err
|
|
||||||
}
|
|
||||||
+ rootfsFile := rootfsArchive
|
|
||||||
updatePath := splicePath(PersistDir, updateDir)
|
|
||||||
mountPath := splicePath(updatePath, mountDir)
|
|
||||||
- tarPath := splicePath(updatePath, rootfsArchive)
|
|
||||||
+ tarPath := splicePath(updatePath, rootfsFile)
|
|
||||||
imagePath := splicePath(PersistDir, osImageName)
|
|
||||||
|
|
||||||
if err := cleanSpace(updatePath, mountPath, imagePath); err != nil {
|
|
||||||
@@ -208,6 +207,7 @@ func prepareEnv() (preparePath, error) {
|
|
||||||
mountPath: mountPath,
|
|
||||||
tarPath: tarPath,
|
|
||||||
imagePath: imagePath,
|
|
||||||
+ rootfsFile: rootfsFile,
|
|
||||||
}
|
|
||||||
return upgradePath, nil
|
|
||||||
}
|
|
||||||
@@ -284,50 +284,9 @@ func checkFileExist(path string) (bool, error) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkOCIImageDigestMatch(containerRuntime string, imageName string, checkSum string) error {
|
|
||||||
- var cmdOutput string
|
|
||||||
- var err error
|
|
||||||
- switch containerRuntime {
|
|
||||||
- case "crictl":
|
|
||||||
- cmdOutput, err = runCommandWithOut("crictl", "inspecti", "--output", "go-template",
|
|
||||||
- "--template", "{{.status.repoDigests}}", imageName)
|
|
||||||
- if err != nil {
|
|
||||||
- return err
|
|
||||||
- }
|
|
||||||
- case "docker":
|
|
||||||
- cmdOutput, err = runCommandWithOut("docker", "inspect", "--format", "{{.RepoDigests}}", imageName)
|
|
||||||
- if err != nil {
|
|
||||||
- return err
|
|
||||||
- }
|
|
||||||
- case "ctr":
|
|
||||||
- cmdOutput, err = runCommandWithOut("ctr", "-n", "k8s.io", "images", "ls", "name=="+imageName)
|
|
||||||
- if err != nil {
|
|
||||||
- return err
|
|
||||||
- }
|
|
||||||
- // after Fields, we get slice like [REF TYPE DIGEST SIZE PLATFORMS LABELS x x x x x x]
|
|
||||||
- // the digest is the position 8 element
|
|
||||||
- imageDigest := strings.Split(strings.Fields(cmdOutput)[8], ":")[1]
|
|
||||||
- if imageDigest != checkSum {
|
|
||||||
- logrus.Errorln("checkSumFailed ", imageDigest, " mismatch to ", checkSum)
|
|
||||||
- return fmt.Errorf("checkSumFailed %s mismatch to %s", imageDigest, checkSum)
|
|
||||||
- }
|
|
||||||
- return nil
|
|
||||||
- default:
|
|
||||||
- logrus.Errorln("containerRuntime ", containerRuntime, " cannot be recognized")
|
|
||||||
- return fmt.Errorf("containerRuntime %s cannot be recognized", containerRuntime)
|
|
||||||
- }
|
|
||||||
- // cmdOutput format is as follows:
|
|
||||||
- // [imageRepository/imageName:imageTag@sha256:digests]
|
|
||||||
- // parse the output and get digest
|
|
||||||
- var imageDigests string
|
|
||||||
- outArray := strings.Split(cmdOutput, "@")
|
|
||||||
- if strings.HasPrefix(outArray[len(outArray)-1], "sha256") {
|
|
||||||
- pasredArray := strings.Split(strings.TrimSuffix(outArray[len(outArray)-1], "]"), ":")
|
|
||||||
- // 2 is the expected length of the array after dividing "imageName:imageTag@sha256:digests" based on ':'
|
|
||||||
- rightLen := 2
|
|
||||||
- if len(pasredArray) == rightLen {
|
|
||||||
- digestIndex := 1 // 1 is the index of digest data in pasredArray
|
|
||||||
- imageDigests = pasredArray[digestIndex]
|
|
||||||
- }
|
|
||||||
+ imageDigests, err := getOCIImageDigest(containerRuntime, imageName)
|
|
||||||
+ if err != nil {
|
|
||||||
+ return err
|
|
||||||
}
|
|
||||||
if imageDigests == "" {
|
|
||||||
logrus.Errorln("error when get ", imageName, " digests")
|
|
||||||
@@ -367,3 +326,48 @@ func isValidImageName(image string) error {
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+func getOCIImageDigest(containerRuntime string, imageName string) (string, error) {
|
|
||||||
+ var cmdOutput string
|
|
||||||
+ var err error
|
|
||||||
+ var imageDigests string
|
|
||||||
+ switch containerRuntime {
|
|
||||||
+ case "crictl":
|
|
||||||
+ cmdOutput, err = runCommandWithOut("crictl", "inspecti", "--output", "go-template",
|
|
||||||
+ "--template", "{{.status.repoDigests}}", imageName)
|
|
||||||
+ if err != nil {
|
|
||||||
+ return "", err
|
|
||||||
+ }
|
|
||||||
+ case "docker":
|
|
||||||
+ cmdOutput, err = runCommandWithOut("docker", "inspect", "--format", "{{.RepoDigests}}", imageName)
|
|
||||||
+ if err != nil {
|
|
||||||
+ return "", err
|
|
||||||
+ }
|
|
||||||
+ case "ctr":
|
|
||||||
+ cmdOutput, err = runCommandWithOut("ctr", "-n", "k8s.io", "images", "ls", "name=="+imageName)
|
|
||||||
+ if err != nil {
|
|
||||||
+ return "", err
|
|
||||||
+ }
|
|
||||||
+ // after Fields, we get slice like [REF TYPE DIGEST SIZE PLATFORMS LABELS x x x x x x]
|
|
||||||
+ // the digest is the position 8 element
|
|
||||||
+ imageDigest := strings.Split(strings.Fields(cmdOutput)[8], ":")[1]
|
|
||||||
+ return imageDigest, nil
|
|
||||||
+ default:
|
|
||||||
+ logrus.Errorln("containerRuntime ", containerRuntime, " cannot be recognized")
|
|
||||||
+ return "", fmt.Errorf("containerRuntime %s cannot be recognized", containerRuntime)
|
|
||||||
+ }
|
|
||||||
+ // cmdOutput format is as follows:
|
|
||||||
+ // [imageRepository/imageName:imageTag@sha256:digests]
|
|
||||||
+ // parse the output and get digest
|
|
||||||
+ outArray := strings.Split(cmdOutput, "@")
|
|
||||||
+ if strings.HasPrefix(outArray[len(outArray)-1], "sha256") {
|
|
||||||
+ pasredArray := strings.Split(strings.TrimSuffix(outArray[len(outArray)-1], "]"), ":")
|
|
||||||
+ // 2 is the expected length of the array after dividing "imageName:imageTag@sha256:digests" based on ':'
|
|
||||||
+ rightLen := 2
|
|
||||||
+ if len(pasredArray) == rightLen {
|
|
||||||
+ digestIndex := 1 // 1 is the index of digest data in pasredArray
|
|
||||||
+ imageDigests = pasredArray[digestIndex]
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return imageDigests, nil
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
56
0001-build-rust-os-agent-remove-useless-dependency.patch
Normal file
56
0001-build-rust-os-agent-remove-useless-dependency.patch
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
From 6e62adfa80c33d9b1fc4445487cc15e721db07bc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yuhang Wei <weiyuhang3@huawei.com>
|
||||||
|
Date: Wed, 10 Jan 2024 15:53:26 +0800
|
||||||
|
Subject: [PATCH] build(rust os-agent): remove useless dependency
|
||||||
|
|
||||||
|
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
||||||
|
---
|
||||||
|
KubeOS-Rust/Cargo.lock | 11 -----------
|
||||||
|
KubeOS-Rust/manager/Cargo.toml | 2 +-
|
||||||
|
2 files changed, 1 insertion(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/KubeOS-Rust/Cargo.lock b/KubeOS-Rust/Cargo.lock
|
||||||
|
index 4b7fc12..2087339 100644
|
||||||
|
--- a/KubeOS-Rust/Cargo.lock
|
||||||
|
+++ b/KubeOS-Rust/Cargo.lock
|
||||||
|
@@ -199,16 +199,6 @@ dependencies = [
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
-[[package]]
|
||||||
|
-name = "colored"
|
||||||
|
-version = "2.1.0"
|
||||||
|
-source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
-checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
|
||||||
|
-dependencies = [
|
||||||
|
- "lazy_static",
|
||||||
|
- "windows-sys",
|
||||||
|
-]
|
||||||
|
-
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation"
|
||||||
|
version = "0.9.3"
|
||||||
|
@@ -1209,7 +1199,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "80f9fece9bd97ab74339fe19f4bcaf52b76dcc18e5364c7977c1838f76b38de9"
|
||||||
|
dependencies = [
|
||||||
|
"assert-json-diff",
|
||||||
|
- "colored",
|
||||||
|
"httparse",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
diff --git a/KubeOS-Rust/manager/Cargo.toml b/KubeOS-Rust/manager/Cargo.toml
|
||||||
|
index 40672cc..9431fba 100644
|
||||||
|
--- a/KubeOS-Rust/manager/Cargo.toml
|
||||||
|
+++ b/KubeOS-Rust/manager/Cargo.toml
|
||||||
|
@@ -8,7 +8,7 @@ version = "0.1.0"
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
[dev-dependencies]
|
||||||
|
mockall = { version = "=0.11.3" }
|
||||||
|
-mockito = { version = "0.31.1" }
|
||||||
|
+mockito = { version = "0.31.1", default-features = false }
|
||||||
|
predicates = { version = "=2.0.1" }
|
||||||
|
tempfile = { version = "3.6.0" }
|
||||||
|
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
||||||
@ -1,346 +0,0 @@
|
|||||||
From 64e36143591c014609fc517bcd6ee0f3ae1087fc Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Thu, 3 Aug 2023 11:01:22 +0800
|
|
||||||
Subject: [PATCH 02/17] KubeOS: refactor assignUpgrade function the
|
|
||||||
assignUpgrade function is refactored for maintainability replace
|
|
||||||
"osinstance-node" to variable
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/operator/controllers/os_controller.go | 73 ++++++-----
|
|
||||||
.../controllers/os_controller_test.go | 121 +++++++++++++++++-
|
|
||||||
cmd/proxy/controllers/os_controller.go | 2 +-
|
|
||||||
cmd/proxy/controllers/os_controller_test.go | 9 ++
|
|
||||||
pkg/values/values.go | 6 +-
|
|
||||||
5 files changed, 176 insertions(+), 35 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/operator/controllers/os_controller.go b/cmd/operator/controllers/os_controller.go
|
|
||||||
index f86a0b2..620739b 100644
|
|
||||||
--- a/cmd/operator/controllers/os_controller.go
|
|
||||||
+++ b/cmd/operator/controllers/os_controller.go
|
|
||||||
@@ -109,7 +109,7 @@ func (r *OSReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
|
||||||
func (r *OSReconciler) DeleteOSInstance(e event.DeleteEvent, q workqueue.RateLimitingInterface) {
|
|
||||||
ctx := context.Background()
|
|
||||||
hostname := e.Object.GetName()
|
|
||||||
- labelSelector := labels.SelectorFromSet(labels.Set{"upgrade.openeuler.org/osinstance-node": hostname})
|
|
||||||
+ labelSelector := labels.SelectorFromSet(labels.Set{values.LabelOSinstance: hostname})
|
|
||||||
osInstanceList := &upgradev1.OSInstanceList{}
|
|
||||||
if err := r.List(ctx, osInstanceList, client.MatchingLabelsSelector{Selector: labelSelector}); err != nil {
|
|
||||||
log.Error(err, "unable to list osInstances")
|
|
||||||
@@ -157,12 +157,23 @@ func assignUpgrade(ctx context.Context, r common.ReadStatusWriter, os upgradev1.
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
- nodes, err := getNodes(ctx, r, limit+1, *requirement, *reqMaster) // one more to see if all node updated
|
|
||||||
+ nodes, err := getNodes(ctx, r, limit+1, *requirement, *reqMaster) // one more to see if all nodes updated
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
- var count = 0
|
|
||||||
+ // Upgrade OS for selected nodes
|
|
||||||
+ count, err := upgradeNodes(ctx, r, &os, nodes, limit)
|
|
||||||
+ if err != nil {
|
|
||||||
+ return false, err
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return count >= limit, nil
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+func upgradeNodes(ctx context.Context, r common.ReadStatusWriter, os *upgradev1.OS,
|
|
||||||
+ nodes []corev1.Node, limit int) (int, error) {
|
|
||||||
+ var count int
|
|
||||||
for _, node := range nodes {
|
|
||||||
if count >= limit {
|
|
||||||
break
|
|
||||||
@@ -170,43 +181,45 @@ func assignUpgrade(ctx context.Context, r common.ReadStatusWriter, os upgradev1.
|
|
||||||
osVersionNode := node.Status.NodeInfo.OSImage
|
|
||||||
if os.Spec.OSVersion != osVersionNode {
|
|
||||||
var osInstance upgradev1.OSInstance
|
|
||||||
- if err = r.Get(ctx, types.NamespacedName{Namespace: nameSpace, Name: node.Name}, &osInstance); err != nil {
|
|
||||||
+ if err := r.Get(ctx, types.NamespacedName{Namespace: os.GetObjectMeta().GetNamespace(), Name: node.Name}, &osInstance); err != nil {
|
|
||||||
if err = client.IgnoreNotFound(err); err != nil {
|
|
||||||
log.Error(err, "failed to get osInstance "+node.Name)
|
|
||||||
- return false, err
|
|
||||||
+ return count, err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
+ updateNodeAndOSins(ctx, r, os, &node, &osInstance)
|
|
||||||
count++
|
|
||||||
- node.Labels[values.LabelUpgrading] = ""
|
|
||||||
- expUpVersion := os.Spec.UpgradeConfigs.Version
|
|
||||||
- osiUpVersion := osInstance.Spec.UpgradeConfigs.Version
|
|
||||||
- if osiUpVersion != expUpVersion {
|
|
||||||
- osInstance.Spec.UpgradeConfigs = os.Spec.UpgradeConfigs
|
|
||||||
- }
|
|
||||||
- expSysVersion := os.Spec.SysConfigs.Version
|
|
||||||
- osiSysVersion := osInstance.Spec.SysConfigs.Version
|
|
||||||
- if osiSysVersion != expSysVersion {
|
|
||||||
- osInstance.Spec.SysConfigs = os.Spec.SysConfigs
|
|
||||||
- for i, config := range osInstance.Spec.SysConfigs.Configs {
|
|
||||||
- if config.Model == "grub.cmdline.current" {
|
|
||||||
- osInstance.Spec.SysConfigs.Configs[i].Model = "grub.cmdline.next"
|
|
||||||
- }
|
|
||||||
- if config.Model == "grub.cmdline.next" {
|
|
||||||
- osInstance.Spec.SysConfigs.Configs[i].Model = "grub.cmdline.current"
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
- osInstance.Spec.NodeStatus = values.NodeStatusUpgrade.String()
|
|
||||||
- if err = r.Update(ctx, &osInstance); err != nil {
|
|
||||||
- log.Error(err, "unable to update", "osInstance", osInstance.Name)
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return count, nil
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+func updateNodeAndOSins(ctx context.Context, r common.ReadStatusWriter, os *upgradev1.OS,
|
|
||||||
+ node *corev1.Node, osInstance *upgradev1.OSInstance) {
|
|
||||||
+ if osInstance.Spec.UpgradeConfigs.Version != os.Spec.UpgradeConfigs.Version {
|
|
||||||
+ osInstance.Spec.UpgradeConfigs = os.Spec.UpgradeConfigs
|
|
||||||
+ }
|
|
||||||
+ if osInstance.Spec.SysConfigs.Version != os.Spec.SysConfigs.Version {
|
|
||||||
+ osInstance.Spec.SysConfigs = os.Spec.SysConfigs
|
|
||||||
+ // exchange "grub.cmdline.current" and "grub.cmdline.next"
|
|
||||||
+ for i, config := range osInstance.Spec.SysConfigs.Configs {
|
|
||||||
+ if config.Model == "grub.cmdline.current" {
|
|
||||||
+ osInstance.Spec.SysConfigs.Configs[i].Model = "grub.cmdline.next"
|
|
||||||
}
|
|
||||||
- if err = r.Update(ctx, &node); err != nil {
|
|
||||||
- log.Error(err, "unable to label", "node", node.Name)
|
|
||||||
+ if config.Model == "grub.cmdline.next" {
|
|
||||||
+ osInstance.Spec.SysConfigs.Configs[i].Model = "grub.cmdline.current"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- return count >= limit, nil
|
|
||||||
+ osInstance.Spec.NodeStatus = values.NodeStatusUpgrade.String()
|
|
||||||
+ if err := r.Update(ctx, osInstance); err != nil {
|
|
||||||
+ log.Error(err, "unable to update", "osInstance", osInstance.Name)
|
|
||||||
+ }
|
|
||||||
+ node.Labels[values.LabelUpgrading] = ""
|
|
||||||
+ if err := r.Update(ctx, node); err != nil {
|
|
||||||
+ log.Error(err, "unable to label", "node", node.Name)
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
func assignConfig(ctx context.Context, r common.ReadStatusWriter, sysConfigs upgradev1.SysConfigs,
|
|
||||||
diff --git a/cmd/operator/controllers/os_controller_test.go b/cmd/operator/controllers/os_controller_test.go
|
|
||||||
index 30a773c..a391005 100644
|
|
||||||
--- a/cmd/operator/controllers/os_controller_test.go
|
|
||||||
+++ b/cmd/operator/controllers/os_controller_test.go
|
|
||||||
@@ -134,6 +134,9 @@ var _ = Describe("OsController", func() {
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: node1Name,
|
|
||||||
Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ values.LabelOSinstance: node1Name,
|
|
||||||
+ },
|
|
||||||
},
|
|
||||||
Spec: upgradev1.OSInstanceSpec{
|
|
||||||
SysConfigs: upgradev1.SysConfigs{
|
|
||||||
@@ -189,7 +192,7 @@ var _ = Describe("OsController", func() {
|
|
||||||
}, timeout, interval).Should(BeTrue())
|
|
||||||
Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v1"))
|
|
||||||
|
|
||||||
- time.Sleep(2 * time.Second) // sleep a while to make sure Reconcile finished
|
|
||||||
+ time.Sleep(1 * time.Second) // sleep a while to make sure Reconcile finished
|
|
||||||
osInsCRLookupKey = types.NamespacedName{Name: node1Name, Namespace: testNamespace}
|
|
||||||
createdOSIns = &upgradev1.OSInstance{}
|
|
||||||
Eventually(func() bool {
|
|
||||||
@@ -301,7 +304,7 @@ var _ = Describe("OsController", func() {
|
|
||||||
}, timeout, interval).Should(BeTrue())
|
|
||||||
Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v1"))
|
|
||||||
|
|
||||||
- time.Sleep(2 * time.Second) // sleep a while to make sure Reconcile finished
|
|
||||||
+ time.Sleep(1 * time.Second) // sleep a while to make sure Reconcile finished
|
|
||||||
configedOSIns := &upgradev1.OSInstance{}
|
|
||||||
Eventually(func() bool {
|
|
||||||
err := k8sClient.Get(ctx, osInsCRLookupKey, configedOSIns)
|
|
||||||
@@ -388,4 +391,118 @@ var _ = Describe("OsController", func() {
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
+ Context("When we want to upgrade and do sysconfigs which contain grub.cmd.current and .next", func() {
|
|
||||||
+ It("Should exchange .current and .next", func() {
|
|
||||||
+ ctx := context.Background()
|
|
||||||
+
|
|
||||||
+ // create Node
|
|
||||||
+ node1Name = "test-node-" + uuid.New().String()
|
|
||||||
+ node1 := &v1.Node{
|
|
||||||
+ ObjectMeta: metav1.ObjectMeta{
|
|
||||||
+ Name: node1Name,
|
|
||||||
+ Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ "beta.kubernetes.io/os": "linux",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ TypeMeta: metav1.TypeMeta{
|
|
||||||
+ APIVersion: "v1",
|
|
||||||
+ Kind: "Node",
|
|
||||||
+ },
|
|
||||||
+ Status: v1.NodeStatus{
|
|
||||||
+ NodeInfo: v1.NodeSystemInfo{
|
|
||||||
+ OSImage: "KubeOS v1",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ err := k8sClient.Create(ctx, node1)
|
|
||||||
+ Expect(err).ToNot(HaveOccurred())
|
|
||||||
+ existingNode := &v1.Node{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(context.Background(),
|
|
||||||
+ types.NamespacedName{Name: node1Name, Namespace: testNamespace}, existingNode)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+
|
|
||||||
+ // create OSInstance
|
|
||||||
+ OSIns := &upgradev1.OSInstance{
|
|
||||||
+ TypeMeta: metav1.TypeMeta{
|
|
||||||
+ Kind: "OSInstance",
|
|
||||||
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
|
|
||||||
+ },
|
|
||||||
+ ObjectMeta: metav1.ObjectMeta{
|
|
||||||
+ Name: node1Name,
|
|
||||||
+ Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ values.LabelOSinstance: node1Name,
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ Spec: upgradev1.OSInstanceSpec{
|
|
||||||
+ SysConfigs: upgradev1.SysConfigs{
|
|
||||||
+ Version: "v1",
|
|
||||||
+ Configs: []upgradev1.SysConfig{},
|
|
||||||
+ },
|
|
||||||
+ UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}},
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
|
|
||||||
+
|
|
||||||
+ // Check that the corresponding OSIns CR has been created
|
|
||||||
+ osInsCRLookupKey := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
|
|
||||||
+ createdOSIns := &upgradev1.OSInstance{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node1Name))
|
|
||||||
+
|
|
||||||
+ // create OS CR
|
|
||||||
+ OS := &upgradev1.OS{
|
|
||||||
+ TypeMeta: metav1.TypeMeta{
|
|
||||||
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
|
|
||||||
+ Kind: "OS",
|
|
||||||
+ },
|
|
||||||
+ ObjectMeta: metav1.ObjectMeta{
|
|
||||||
+ Name: OSName,
|
|
||||||
+ Namespace: testNamespace,
|
|
||||||
+ },
|
|
||||||
+ Spec: upgradev1.OSSpec{
|
|
||||||
+ OpsType: "upgrade",
|
|
||||||
+ MaxUnavailable: 3,
|
|
||||||
+ OSVersion: "KubeOS v2",
|
|
||||||
+ FlagSafe: true,
|
|
||||||
+ MTLS: false,
|
|
||||||
+ EvictPodForce: true,
|
|
||||||
+ SysConfigs: upgradev1.SysConfigs{
|
|
||||||
+ Version: "v2",
|
|
||||||
+ Configs: []upgradev1.SysConfig{
|
|
||||||
+ {Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}},
|
|
||||||
+ {Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}},
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}},
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ Expect(k8sClient.Create(ctx, OS)).Should(Succeed())
|
|
||||||
+
|
|
||||||
+ // Check that the corresponding OS CR has been created
|
|
||||||
+ osCRLookupKey := types.NamespacedName{Name: OSName, Namespace: testNamespace}
|
|
||||||
+ createdOS := &upgradev1.OS{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(ctx, osCRLookupKey, createdOS)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v2"))
|
|
||||||
+
|
|
||||||
+ time.Sleep(1 * time.Second) // sleep a while to make sure Reconcile finished
|
|
||||||
+ osInsCRLookupKey = types.NamespacedName{Name: node1Name, Namespace: testNamespace}
|
|
||||||
+ createdOSIns = &upgradev1.OSInstance{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ Expect(createdOSIns.Spec.SysConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
|
|
||||||
+ Expect(createdOSIns.Spec.SysConfigs.Configs[1]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}}))
|
|
||||||
+ })
|
|
||||||
+ })
|
|
||||||
})
|
|
||||||
diff --git a/cmd/proxy/controllers/os_controller.go b/cmd/proxy/controllers/os_controller.go
|
|
||||||
index a17afac..b0b17e7 100644
|
|
||||||
--- a/cmd/proxy/controllers/os_controller.go
|
|
||||||
+++ b/cmd/proxy/controllers/os_controller.go
|
|
||||||
@@ -261,7 +261,7 @@ func checkOsiExist(ctx context.Context, r common.ReadStatusWriter, nameSpace str
|
|
||||||
Namespace: nameSpace,
|
|
||||||
Name: nodeName,
|
|
||||||
Labels: map[string]string{
|
|
||||||
- "upgrade.openeuler.org/osinstance-node": nodeName,
|
|
||||||
+ values.LabelOSinstance: nodeName,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
diff --git a/cmd/proxy/controllers/os_controller_test.go b/cmd/proxy/controllers/os_controller_test.go
|
|
||||||
index ff12f64..e6cd5b7 100644
|
|
||||||
--- a/cmd/proxy/controllers/os_controller_test.go
|
|
||||||
+++ b/cmd/proxy/controllers/os_controller_test.go
|
|
||||||
@@ -110,6 +110,9 @@ var _ = Describe("OsController", func() {
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: node1Name,
|
|
||||||
Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ values.LabelOSinstance: node1Name,
|
|
||||||
+ },
|
|
||||||
},
|
|
||||||
Spec: upgradev1.OSInstanceSpec{
|
|
||||||
NodeStatus: values.NodeStatusConfig.String(),
|
|
||||||
@@ -245,6 +248,9 @@ var _ = Describe("OsController", func() {
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: node1Name,
|
|
||||||
Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ values.LabelOSinstance: node1Name,
|
|
||||||
+ },
|
|
||||||
},
|
|
||||||
Spec: upgradev1.OSInstanceSpec{
|
|
||||||
NodeStatus: values.NodeStatusUpgrade.String(),
|
|
||||||
@@ -426,6 +432,9 @@ var _ = Describe("OsController", func() {
|
|
||||||
return err == nil
|
|
||||||
}, timeout, interval).Should(BeTrue())
|
|
||||||
Expect(createdOSIns.Spec.NodeStatus).Should(Equal(values.NodeStatusIdle.String()))
|
|
||||||
+ hostname, ok := createdOSIns.ObjectMeta.Labels[values.LabelOSinstance]
|
|
||||||
+ Expect(ok).Should(BeTrue())
|
|
||||||
+ Expect(hostname).Should(Equal(node1Name))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
diff --git a/pkg/values/values.go b/pkg/values/values.go
|
|
||||||
index 30261bd..f488ae5 100644
|
|
||||||
--- a/pkg/values/values.go
|
|
||||||
+++ b/pkg/values/values.go
|
|
||||||
@@ -23,8 +23,10 @@ const (
|
|
||||||
// LabelUpgrading is the key of the upgrading label for nodes
|
|
||||||
LabelUpgrading = "upgrade.openeuler.org/upgrading"
|
|
||||||
// LabelMaster is the key of the master-node label for nodes
|
|
||||||
- LabelMaster = "node-role.kubernetes.io/control-plane"
|
|
||||||
- defaultPeriod = 15 * time.Second
|
|
||||||
+ LabelMaster = "node-role.kubernetes.io/control-plane"
|
|
||||||
+ // LabelOSinstance is used to select the osinstance with the nodeName by label
|
|
||||||
+ LabelOSinstance = "upgrade.openeuler.org/osinstance-node"
|
|
||||||
+ defaultPeriod = 15 * time.Second
|
|
||||||
// OsiStatusName is param name of nodeStatus in osInstance
|
|
||||||
OsiStatusName = "nodestatus"
|
|
||||||
// UpgradeConfigName is param name of UpgradeConfig
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
From 470e190db2de92b65e7fa720864823e7245c51e9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: liyuanr <liyuanrong1@huawei.com>
|
|
||||||
Date: Mon, 7 Aug 2023 19:09:18 +0800
|
|
||||||
Subject: [PATCH 03/17] KubeOS: fix the hostshell cannot obtain the lib
|
|
||||||
|
|
||||||
Fix the hostshell cannot obtain the lib
|
|
||||||
|
|
||||||
Signed-off-by: liyuanr <liyuanrong1@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/admin-container/main.go | 40 +++++++++++++++++++++++++------------
|
|
||||||
1 file changed, 27 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/admin-container/main.go b/cmd/admin-container/main.go
|
|
||||||
index f6a7293..5fa0838 100644
|
|
||||||
--- a/cmd/admin-container/main.go
|
|
||||||
+++ b/cmd/admin-container/main.go
|
|
||||||
@@ -22,28 +22,42 @@ import (
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
+const (
|
|
||||||
+ bashPath = "/usr/bin/bash"
|
|
||||||
+ usrBin = "/usr/bin"
|
|
||||||
+ usrSbin = "/usr/sbin"
|
|
||||||
+ localBin = "/usr/local/bin"
|
|
||||||
+ localSbin = "/usr/local/sbin"
|
|
||||||
+ usrLib = "/usr/lib"
|
|
||||||
+ usrLib64 = "/usr/lib64"
|
|
||||||
+ lib = "/lib"
|
|
||||||
+ lib64 = "/lib64"
|
|
||||||
+ envPathPrefix = "PATH=$PATH:"
|
|
||||||
+ envLdLibrarPathPrefix = "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"
|
|
||||||
+)
|
|
||||||
+
|
|
||||||
func main() {
|
|
||||||
EUID := os.Geteuid()
|
|
||||||
rootEUID := 0 // 0 indicates that the process has the permission of the root user.
|
|
||||||
if EUID != rootEUID {
|
|
||||||
logrus.Error("please use root to run hostshell")
|
|
||||||
- return
|
|
||||||
+
|
|
||||||
}
|
|
||||||
PPID := os.Getppid()
|
|
||||||
rootFsPath := "/proc/" + strconv.Itoa(PPID) + "/root"
|
|
||||||
- bashPath := "/usr/bin/bash"
|
|
||||||
- usrBin := "/usr/bin"
|
|
||||||
- usrSbin := "/usr/sbin"
|
|
||||||
- localBin := "/usr/local/bin"
|
|
||||||
- localSbin := "/usr/local/sbin"
|
|
||||||
- paths := []string{usrBin, usrSbin, localBin, localSbin}
|
|
||||||
- for i, p := range paths {
|
|
||||||
- paths[i] = rootFsPath + p
|
|
||||||
- }
|
|
||||||
- path := "PATH=$PATH:" + strings.Join(paths, ":")
|
|
||||||
- lib := "LD_LIBRARY_PATH=/lib:/lib64:/usr/lib:/usr/lib64:$LD_LIBRARY_PATH"
|
|
||||||
+ path := concatenateEnvPath(rootFsPath, envPathPrefix, []string{usrBin, usrSbin, localBin, localSbin})
|
|
||||||
+ libPath := concatenateEnvPath(rootFsPath, envLdLibrarPathPrefix, []string{usrLib, usrLib64, lib, lib64})
|
|
||||||
if err := syscall.Exec("/usr/bin/nsenter", []string{"nsenter", "-t", "1", "-a",
|
|
||||||
- "env", "-i", path, lib, rootFsPath + bashPath}, os.Environ()); err != nil {
|
|
||||||
+ "env", "-i", path, libPath, rootFsPath + bashPath}, os.Environ()); err != nil {
|
|
||||||
logrus.Error("nsenter excute error", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+func concatenateEnvPath(prefix string, envVarPrefix string, paths []string) string {
|
|
||||||
+ for i, p := range paths {
|
|
||||||
+ paths[i] = prefix + p
|
|
||||||
+ }
|
|
||||||
+ pathLine := envVarPrefix + strings.Join(paths, ":")
|
|
||||||
+ pathEnv := os.ExpandEnv(pathLine)
|
|
||||||
+ return pathEnv
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,155 +0,0 @@
|
|||||||
From 5c5922a922f225a9ebc5f99a5008ddcf182b7da6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Thu, 10 Aug 2023 17:24:50 +0800
|
|
||||||
Subject: [PATCH 05/17] KubeOS: fix validate image name bug fix the bug that
|
|
||||||
incorrectly granted illegal image names path:tag@sha256
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/agent/server/utils.go | 2 +-
|
|
||||||
cmd/agent/server/utils_test.go | 109 ++++++++++++++++++++++++++++++++-
|
|
||||||
2 files changed, 109 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/agent/server/utils.go b/cmd/agent/server/utils.go
|
|
||||||
index 7134d74..b42db18 100644
|
|
||||||
--- a/cmd/agent/server/utils.go
|
|
||||||
+++ b/cmd/agent/server/utils.go
|
|
||||||
@@ -316,7 +316,7 @@ func isCommandAvailable(name string) bool {
|
|
||||||
}
|
|
||||||
|
|
||||||
func isValidImageName(image string) error {
|
|
||||||
- pattern := `^((?:[\w.-]+)(?::\d+)?\/)*(?:[\w.-]+)(?::[\w_.-]+)?(?:@sha256:[a-fA-F0-9]+)?$`
|
|
||||||
+ pattern := `^((?:[\w.-]+)(?::\d+)?\/)*(?:[\w.-]+)((?::[\w_.-]+)?|(?:@sha256:[a-fA-F0-9]+)?)$`
|
|
||||||
regEx, err := regexp.Compile(pattern)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
diff --git a/cmd/agent/server/utils_test.go b/cmd/agent/server/utils_test.go
|
|
||||||
index 89b2c3b..0796bce 100644
|
|
||||||
--- a/cmd/agent/server/utils_test.go
|
|
||||||
+++ b/cmd/agent/server/utils_test.go
|
|
||||||
@@ -56,10 +56,16 @@ func Test_install(t *testing.T) {
|
|
||||||
args args
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
- {name: "normal", args: args{imagePath: "aa.txt", side: "/dev/sda3", next: "A"}, wantErr: false},
|
|
||||||
+ {name: "normal uefi", args: args{imagePath: "aa.txt", side: "/dev/sda3", next: "A"}, wantErr: false},
|
|
||||||
+ {name: "normal legacy", args: args{imagePath: "aa.txt", side: "/dev/sda3", next: "A"}, wantErr: false},
|
|
||||||
}
|
|
||||||
patchRunCommand := gomonkey.ApplyFuncReturn(runCommand, nil)
|
|
||||||
defer patchRunCommand.Reset()
|
|
||||||
+ patchGetBootMode := gomonkey.ApplyFuncSeq(getBootMode, []gomonkey.OutputCell{
|
|
||||||
+ {Values: gomonkey.Params{"uefi", nil}},
|
|
||||||
+ {Values: gomonkey.Params{"legacy", nil}},
|
|
||||||
+ })
|
|
||||||
+ defer patchGetBootMode.Reset()
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if err := install(tt.args.imagePath, tt.args.side, tt.args.next); (err != nil) != tt.wantErr {
|
|
||||||
@@ -219,3 +225,104 @@ func createTmpTarFile(tarPath string) (string, error) {
|
|
||||||
}
|
|
||||||
return tempFile.Name(), nil
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+func Test_getBootMode(t *testing.T) {
|
|
||||||
+ tests := []struct {
|
|
||||||
+ name string
|
|
||||||
+ want string
|
|
||||||
+ wantErr bool
|
|
||||||
+ }{
|
|
||||||
+ {
|
|
||||||
+ name: "uefi",
|
|
||||||
+ want: "uefi",
|
|
||||||
+ wantErr: false,
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ name: "legacy",
|
|
||||||
+ want: "legacy",
|
|
||||||
+ wantErr: false,
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ patchOSStat := gomonkey.ApplyFuncSeq(os.Stat, []gomonkey.OutputCell{
|
|
||||||
+ {Values: gomonkey.Params{nil, nil}},
|
|
||||||
+ {Values: gomonkey.Params{nil, os.ErrNotExist}},
|
|
||||||
+ })
|
|
||||||
+ defer patchOSStat.Reset()
|
|
||||||
+ for _, tt := range tests {
|
|
||||||
+ t.Run(tt.name, func(t *testing.T) {
|
|
||||||
+ got, err := getBootMode()
|
|
||||||
+ if (err != nil) != tt.wantErr {
|
|
||||||
+ t.Errorf("getBootMode() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
+ return
|
|
||||||
+ }
|
|
||||||
+ if got != tt.want {
|
|
||||||
+ t.Errorf("getBootMode() = %v, want %v", got, tt.want)
|
|
||||||
+ }
|
|
||||||
+ })
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+func Test_isValidImageName(t *testing.T) {
|
|
||||||
+ type args struct {
|
|
||||||
+ image string
|
|
||||||
+ }
|
|
||||||
+ tests := []struct {
|
|
||||||
+ name string
|
|
||||||
+ args args
|
|
||||||
+ wantErr bool
|
|
||||||
+ }{
|
|
||||||
+ {name: "valid", args: args{image: "alpine"}, wantErr: false},
|
|
||||||
+ {name: "valid", args: args{image: "alpine:latest"}, wantErr: false},
|
|
||||||
+ {name: "valid", args: args{image: "localhost:1234/test"}, wantErr: false},
|
|
||||||
+ {name: "valid", args: args{image: "alpine:3.7"}, wantErr: false},
|
|
||||||
+ {name: "valid", args: args{image: "docker.example.edu/gmr/alpine:3.7"}, wantErr: false},
|
|
||||||
+ {name: "valid", args: args{image: "docker.example.com:5000/gmr/alpine@sha256:11111111111111111111111111111111"}, wantErr: false},
|
|
||||||
+ {name: "valid", args: args{image: "registry.dobby.org/dobby/dobby-servers/arthound:2019-08-08"}, wantErr: false},
|
|
||||||
+ {name: "valid", args: args{image: "registry.dobby.org/dobby/dobby-servers/lerphound:latest"}, wantErr: false},
|
|
||||||
+ {name: "valid", args: args{image: "registry.dobby.org/dobby/dobby-servers/loophole@sha256:5a156ff125e5a12ac7ff43ee5120fa249cf62248337b6d04abc574c8"}, wantErr: false},
|
|
||||||
+ {name: "valid", args: args{image: "sosedoff/pgweb@sha256:5a156ff125e5a12ac7ff43ee5120fa249cf62248337b6d04574c8"}, wantErr: false},
|
|
||||||
+ {name: "valid", args: args{image: "registry.dobby.org/dobby/antique-penguin:release-production"}, wantErr: false},
|
|
||||||
+ {name: "valid", args: args{image: "dalprodictus/halcon:6.7.5"}, wantErr: false},
|
|
||||||
+ {name: "valid", args: args{image: "antigua/antigua:v31"}, wantErr: false},
|
|
||||||
+ {name: "invalid ;", args: args{image: "alpine;v1.0"}, wantErr: true},
|
|
||||||
+ {name: "invalid tag and digest1", args: args{image: "alpine:latest@sha256:11111111111111111111111111111111"}, wantErr: true},
|
|
||||||
+ {name: "invalid |", args: args{image: "alpine|v1.0"}, wantErr: true},
|
|
||||||
+ {name: "invalid &", args: args{image: "alpine&v1.0"}, wantErr: true},
|
|
||||||
+ {name: "invalid tag and digest2", args: args{image: "sosedoff/pgweb:latest@sha256:5a156ff125e5a12ac7ff43ee5120fa249cf62248337b6d04574c8"}, wantErr: true},
|
|
||||||
+ {name: "invalid tag and digest3", args: args{image: "192.168.122.123:5000/kubeos_uefi-x86_64:euleros_v2_docker-2023-01@sha256:1a1a1a1a1a1a1a1a1a1a1a1a1a1a"}, wantErr: true},
|
|
||||||
+ }
|
|
||||||
+ for _, tt := range tests {
|
|
||||||
+ t.Run(tt.name, func(t *testing.T) {
|
|
||||||
+ if err := isValidImageName(tt.args.image); (err != nil) != tt.wantErr {
|
|
||||||
+ t.Errorf("isValidImageName() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
+ }
|
|
||||||
+ })
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+func Test_checkOCIImageDigestMatch(t *testing.T) {
|
|
||||||
+ type args struct {
|
|
||||||
+ containerRuntime string
|
|
||||||
+ imageName string
|
|
||||||
+ checkSum string
|
|
||||||
+ }
|
|
||||||
+ tests := []struct {
|
|
||||||
+ name string
|
|
||||||
+ args args
|
|
||||||
+ wantErr bool
|
|
||||||
+ }{
|
|
||||||
+ {name: "invalid container runtion", args: args{containerRuntime: "dockctl", imageName: "docker.io/library/hello-world:latest", checkSum: "1abf18abf9bf9baa0a4a38d1afad4abf0d7da4544e163186e036c906c09c94fe"}, wantErr: true},
|
|
||||||
+ {name: "nil image digets", args: args{containerRuntime: "crictl", imageName: "docker.io/library/hello-world:latest", checkSum: "1abf18abf9bf9baa0a4a38d1afad4abf0d7da4544e163186e036c906c09c94fe"}, wantErr: true},
|
|
||||||
+ }
|
|
||||||
+ for _, tt := range tests {
|
|
||||||
+ t.Run(tt.name, func(t *testing.T) {
|
|
||||||
+ if tt.name == "nil image digets" {
|
|
||||||
+ patchGetOCIImageDigest := gomonkey.ApplyFuncReturn(getOCIImageDigest, "", nil)
|
|
||||||
+ defer patchGetOCIImageDigest.Reset()
|
|
||||||
+ }
|
|
||||||
+ if err := checkOCIImageDigestMatch(tt.args.containerRuntime, tt.args.imageName, tt.args.checkSum); (err != nil) != tt.wantErr {
|
|
||||||
+ t.Errorf("checkOCIImageDigestMatch() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
+ }
|
|
||||||
+ })
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,156 +0,0 @@
|
|||||||
From 911fbd04ba55a2560e8da8595ff379a742e5fa30 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Thu, 10 Aug 2023 17:47:54 +0800
|
|
||||||
Subject: [PATCH 06/17] KubeOS: fix a bug that failed to parse key with =
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/agent/server/config.go | 6 ++--
|
|
||||||
cmd/agent/server/config_test.go | 55 +++++++++++++++++++++++++++++----
|
|
||||||
2 files changed, 52 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/agent/server/config.go b/cmd/agent/server/config.go
|
|
||||||
index 653f913..bcd9fde 100644
|
|
||||||
--- a/cmd/agent/server/config.go
|
|
||||||
+++ b/cmd/agent/server/config.go
|
|
||||||
@@ -259,7 +259,7 @@ func getAndSetConfigsFromFile(expectConfigs map[string]*agent.KeyInfo, path stri
|
|
||||||
configsWrite = append(configsWrite, line)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
- configKV := strings.Split(line, "=")
|
|
||||||
+ configKV := strings.SplitN(line, "=", kvPair)
|
|
||||||
if len(configKV) != kvPair {
|
|
||||||
logrus.Errorf("could not parse systctl config %s", line)
|
|
||||||
return nil, fmt.Errorf("could not parse systctl config %s", line)
|
|
||||||
@@ -374,8 +374,8 @@ func handleUpdateKey(config []string, configInfo *agent.KeyInfo, isFound bool) s
|
|
||||||
func handleAddKey(m map[string]*agent.KeyInfo, isOnlyKeyValid bool) []string {
|
|
||||||
var configs []string
|
|
||||||
for key, keyInfo := range m {
|
|
||||||
- if key == "" {
|
|
||||||
- logrus.Warnln("Failed to add nil key")
|
|
||||||
+ if key == "" || strings.Contains(key, "=") {
|
|
||||||
+ logrus.Warnf("Failed to add nil key or key containing =, key: %s", key)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if keyInfo.Operation == "delete" {
|
|
||||||
diff --git a/cmd/agent/server/config_test.go b/cmd/agent/server/config_test.go
|
|
||||||
index 2deb15f..ae2a2cf 100644
|
|
||||||
--- a/cmd/agent/server/config_test.go
|
|
||||||
+++ b/cmd/agent/server/config_test.go
|
|
||||||
@@ -23,7 +23,6 @@ import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/agiledragon/gomonkey/v2"
|
|
||||||
-
|
|
||||||
agent "openeuler.org/KubeOS/cmd/agent/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
@@ -105,17 +104,27 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{name: "create file", args: args{config: &agent.SysConfig{ConfigPath: persistPath}}, want: []string{comment}, wantErr: false},
|
|
||||||
+ {
|
|
||||||
+ name: "nil path",
|
|
||||||
+ args: args{
|
|
||||||
+ config: &agent.SysConfig{},
|
|
||||||
+ },
|
|
||||||
+ want: []string{},
|
|
||||||
+ wantErr: false,
|
|
||||||
+ },
|
|
||||||
{
|
|
||||||
name: "add configs",
|
|
||||||
args: args{
|
|
||||||
config: &agent.SysConfig{
|
|
||||||
ConfigPath: persistPath,
|
|
||||||
Contents: map[string]*agent.KeyInfo{
|
|
||||||
- "a": {Value: "1"},
|
|
||||||
- "b": {Value: "2"},
|
|
||||||
- "c": {Value: ""},
|
|
||||||
- "": {Value: "4"},
|
|
||||||
- "e": {Value: "5"},
|
|
||||||
+ "a": {Value: "1"},
|
|
||||||
+ "b": {Value: "2"},
|
|
||||||
+ "c": {Value: ""},
|
|
||||||
+ "": {Value: "4"},
|
|
||||||
+ "e": {Value: "5"},
|
|
||||||
+ "y=1": {Value: "26"},
|
|
||||||
+ "z": {Value: "x=1"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
@@ -123,6 +132,7 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
|
|
||||||
"a=1",
|
|
||||||
"b=2",
|
|
||||||
"e=5",
|
|
||||||
+ "z=x=1",
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
@@ -134,6 +144,7 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
|
|
||||||
Contents: map[string]*agent.KeyInfo{
|
|
||||||
"a": {Value: "2"},
|
|
||||||
"b": {Value: ""},
|
|
||||||
+ "z": {Value: "x=2"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
@@ -141,6 +152,7 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
|
|
||||||
"a=2",
|
|
||||||
"b=2",
|
|
||||||
"e=5",
|
|
||||||
+ "z=x=2",
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
@@ -155,6 +167,7 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
|
|
||||||
"c": {Value: "3", Operation: "delete"},
|
|
||||||
"e": {Value: "5", Operation: "remove"},
|
|
||||||
"f": {Value: "6", Operation: "remove"},
|
|
||||||
+ "z": {Value: "x=2", Operation: "delete"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
@@ -166,6 +179,8 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
+ patchGetKernelConPath := gomonkey.ApplyFuncReturn(getKernelConPath, persistPath)
|
|
||||||
+ defer patchGetKernelConPath.Reset()
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
k := KerSysctlPersist{}
|
|
||||||
@@ -467,3 +482,31 @@ func Test_getConfigPartition(t *testing.T) {
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+func Test_ConfigFactoryTemplate(t *testing.T) {
|
|
||||||
+ type args struct {
|
|
||||||
+ configType string
|
|
||||||
+ config *agent.SysConfig
|
|
||||||
+ }
|
|
||||||
+ tests := []struct {
|
|
||||||
+ name string
|
|
||||||
+ args args
|
|
||||||
+ wantErr bool
|
|
||||||
+ }{
|
|
||||||
+ {
|
|
||||||
+ name: "error",
|
|
||||||
+ args: args{
|
|
||||||
+ configType: "test",
|
|
||||||
+ config: &agent.SysConfig{},
|
|
||||||
+ },
|
|
||||||
+ wantErr: true,
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ for _, tt := range tests {
|
|
||||||
+ t.Run(tt.name, func(t *testing.T) {
|
|
||||||
+ if err := ConfigFactoryTemplate(tt.args.configType, tt.args.config); (err != nil) != tt.wantErr {
|
|
||||||
+ t.Errorf("ConfigFactoryTemplate() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
+ }
|
|
||||||
+ })
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
From 59473394cca1e227ec579236d71ec54deb79b068 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Thu, 10 Aug 2023 20:49:39 +0800
|
|
||||||
Subject: [PATCH 07/17] KubeOS: add warning log during config add warning log
|
|
||||||
when configuring kv with unknown operation
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/agent/server/config.go | 4 ++++
|
|
||||||
cmd/agent/server/config_test.go | 4 ++--
|
|
||||||
2 files changed, 6 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/agent/server/config.go b/cmd/agent/server/config.go
|
|
||||||
index bcd9fde..78dfd01 100644
|
|
||||||
--- a/cmd/agent/server/config.go
|
|
||||||
+++ b/cmd/agent/server/config.go
|
|
||||||
@@ -382,6 +382,10 @@ func handleAddKey(m map[string]*agent.KeyInfo, isOnlyKeyValid bool) []string {
|
|
||||||
logrus.Warnf("Failed to delete inexistent key %s", key)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
+ if keyInfo.Operation != "" {
|
|
||||||
+ logrus.Warnf("Unknown operation %s, adding key %s with value %s by default",
|
|
||||||
+ keyInfo.Operation, key, keyInfo.Value)
|
|
||||||
+ }
|
|
||||||
k, v := strings.TrimSpace(key), strings.TrimSpace(keyInfo.Value)
|
|
||||||
if keyInfo.Value == "" && isOnlyKeyValid {
|
|
||||||
logrus.Infoln("add configuration ", k)
|
|
||||||
diff --git a/cmd/agent/server/config_test.go b/cmd/agent/server/config_test.go
|
|
||||||
index ae2a2cf..6424885 100644
|
|
||||||
--- a/cmd/agent/server/config_test.go
|
|
||||||
+++ b/cmd/agent/server/config_test.go
|
|
||||||
@@ -122,7 +122,7 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
|
|
||||||
"b": {Value: "2"},
|
|
||||||
"c": {Value: ""},
|
|
||||||
"": {Value: "4"},
|
|
||||||
- "e": {Value: "5"},
|
|
||||||
+ "e": {Value: "5", Operation: "xxx"},
|
|
||||||
"y=1": {Value: "26"},
|
|
||||||
"z": {Value: "x=1"},
|
|
||||||
},
|
|
||||||
@@ -144,7 +144,7 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) {
|
|
||||||
Contents: map[string]*agent.KeyInfo{
|
|
||||||
"a": {Value: "2"},
|
|
||||||
"b": {Value: ""},
|
|
||||||
- "z": {Value: "x=2"},
|
|
||||||
+ "z": {Value: "x=2", Operation: "zzz"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
From 38ed69d2ad089d124ee72a4431fcc96ef3d9cf28 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Thu, 10 Aug 2023 21:10:29 +0800
|
|
||||||
Subject: [PATCH 08/17] KubeOS: modify log level and content
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/agent/server/config.go | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/agent/server/config.go b/cmd/agent/server/config.go
|
|
||||||
index 78dfd01..c474f59 100644
|
|
||||||
--- a/cmd/agent/server/config.go
|
|
||||||
+++ b/cmd/agent/server/config.go
|
|
||||||
@@ -57,7 +57,7 @@ func (k KernelSysctl) SetConfig(config *agent.SysConfig) error {
|
|
||||||
}
|
|
||||||
logrus.Infof("Configured kernel.sysctl %s=%s", key, keyInfo.Value)
|
|
||||||
} else {
|
|
||||||
- logrus.Errorf("Failed to parse kernel.sysctl config operation %s value %s", keyInfo.Operation, keyInfo.Value)
|
|
||||||
+ logrus.Warnf("Failed to parse kernel.sysctl key %s value %s operation %s", key, keyInfo.Value, keyInfo.Operation)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,151 +0,0 @@
|
|||||||
From dcfb6e0397e649631ec42dcf51c3e98e914f8269 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Fri, 11 Aug 2023 19:33:56 +0800
|
|
||||||
Subject: [PATCH 09/17] KubeOS: fix updating key to kv
|
|
||||||
|
|
||||||
when configuring kernel boot parameters, it should be able to update
|
|
||||||
key to kv
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/agent/server/config.go | 37 ++++++++++++++++++++++-----------
|
|
||||||
cmd/agent/server/config_test.go | 15 +++++++------
|
|
||||||
2 files changed, 34 insertions(+), 18 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/agent/server/config.go b/cmd/agent/server/config.go
|
|
||||||
index c474f59..20af267 100644
|
|
||||||
--- a/cmd/agent/server/config.go
|
|
||||||
+++ b/cmd/agent/server/config.go
|
|
||||||
@@ -57,7 +57,7 @@ func (k KernelSysctl) SetConfig(config *agent.SysConfig) error {
|
|
||||||
}
|
|
||||||
logrus.Infof("Configured kernel.sysctl %s=%s", key, keyInfo.Value)
|
|
||||||
} else {
|
|
||||||
- logrus.Warnf("Failed to parse kernel.sysctl key %s value %s operation %s", key, keyInfo.Value, keyInfo.Operation)
|
|
||||||
+ logrus.Warnf("Failed to parse kernel.sysctl key: %s value: %s operation: %s", key, keyInfo.Value, keyInfo.Operation)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
@@ -317,7 +317,7 @@ func createConfigPath(configPath string) error {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
- defer f.Close()
|
|
||||||
+ f.Close()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -335,11 +335,16 @@ func getGrubCfgPath() string {
|
|
||||||
|
|
||||||
// handleDeleteKey deletes key if oldValue==newValue and returns "" string. Otherwier, it returns key=oldValue
|
|
||||||
func handleDeleteKey(config []string, configInfo *agent.KeyInfo) string {
|
|
||||||
- if len(config) == onlyKey {
|
|
||||||
- logrus.Infoln("delete configuration ", config[0])
|
|
||||||
+ key := config[0]
|
|
||||||
+ if len(config) == onlyKey && configInfo.Value == "" {
|
|
||||||
+ logrus.Infoln("delete configuration ", key)
|
|
||||||
return ""
|
|
||||||
+ } else if len(config) == onlyKey && configInfo.Value != "" {
|
|
||||||
+ logrus.Warnf("Failed to delete key %s with inconsistent values "+
|
|
||||||
+ "nil and %s", key, configInfo.Value)
|
|
||||||
+ return key
|
|
||||||
}
|
|
||||||
- key, oldValue := config[0], config[1]
|
|
||||||
+ oldValue := config[1]
|
|
||||||
if oldValue != configInfo.Value {
|
|
||||||
logrus.Warnf("Failed to delete key %s with inconsistent values "+
|
|
||||||
"%s and %s", key, oldValue, configInfo.Value)
|
|
||||||
@@ -351,22 +356,30 @@ func handleDeleteKey(config []string, configInfo *agent.KeyInfo) string {
|
|
||||||
|
|
||||||
// handleUpdateKey updates key if key is found, otherwise it returns old config.
|
|
||||||
func handleUpdateKey(config []string, configInfo *agent.KeyInfo, isFound bool) string {
|
|
||||||
- if len(config) == onlyKey {
|
|
||||||
- return config[0]
|
|
||||||
+ key := config[0]
|
|
||||||
+ if !isFound && len(config) == onlyKey {
|
|
||||||
+ return key
|
|
||||||
}
|
|
||||||
- key, oldValue := config[0], config[1]
|
|
||||||
- if !isFound {
|
|
||||||
- return key + "=" + oldValue
|
|
||||||
+ if !isFound && len(config) == kvPair {
|
|
||||||
+ return key + "=" + config[1]
|
|
||||||
}
|
|
||||||
if configInfo.Operation != "" {
|
|
||||||
logrus.Warnf("Unknown operation %s, updating key %s with value %s by default",
|
|
||||||
configInfo.Operation, key, configInfo.Value)
|
|
||||||
}
|
|
||||||
+ if len(config) == onlyKey && configInfo.Value == "" {
|
|
||||||
+ return key
|
|
||||||
+ }
|
|
||||||
+ newValue := strings.TrimSpace(configInfo.Value)
|
|
||||||
+ if len(config) == onlyKey && configInfo.Value != "" {
|
|
||||||
+ logrus.Infof("update configuration %s=%s", key, newValue)
|
|
||||||
+ return key + "=" + newValue
|
|
||||||
+ }
|
|
||||||
+ oldValue := config[1]
|
|
||||||
if configInfo.Value == "" {
|
|
||||||
logrus.Warnf("Failed to update key %s with null value", key)
|
|
||||||
return key + "=" + oldValue
|
|
||||||
}
|
|
||||||
- newValue := strings.TrimSpace(configInfo.Value)
|
|
||||||
logrus.Infof("update configuration %s=%s", key, newValue)
|
|
||||||
return key + "=" + newValue
|
|
||||||
}
|
|
||||||
@@ -388,7 +401,7 @@ func handleAddKey(m map[string]*agent.KeyInfo, isOnlyKeyValid bool) []string {
|
|
||||||
}
|
|
||||||
k, v := strings.TrimSpace(key), strings.TrimSpace(keyInfo.Value)
|
|
||||||
if keyInfo.Value == "" && isOnlyKeyValid {
|
|
||||||
- logrus.Infoln("add configuration ", k)
|
|
||||||
+ logrus.Infoln("add configuration", k)
|
|
||||||
configs = append(configs, k)
|
|
||||||
} else if keyInfo.Value == "" {
|
|
||||||
logrus.Warnf("Failed to add key %s with null value", k)
|
|
||||||
diff --git a/cmd/agent/server/config_test.go b/cmd/agent/server/config_test.go
|
|
||||||
index 6424885..08daf99 100644
|
|
||||||
--- a/cmd/agent/server/config_test.go
|
|
||||||
+++ b/cmd/agent/server/config_test.go
|
|
||||||
@@ -262,10 +262,11 @@ menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestri
|
|
||||||
"": {Value: "test"}, // warning, skip, failed to add kv with empty key
|
|
||||||
"selinux": {Value: "1", Operation: "delete"}, // failed to delete inconsistent kv
|
|
||||||
"acpi": {Value: "off", Operation: "delete"}, // failed to delete inexistent kv
|
|
||||||
+ "ro": {Value: "1"}, // update key to kv
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
- pattern: `(?m)^\s+linux\s+\/boot\/vmlinuz\s+root=UUID=[0-1]\s+ro\s+rootfstype=ext4\s+nomodeset\s+oops=panic\s+softlockup_panic=0\s+nmi_watchdog=1\s+rd\.shell=0\s+selinux=0\s+crashkernel=256M\s+panic=5\s+(debug\spci=nomis|pci=nomis\sdebug)$`,
|
|
||||||
+ pattern: `(?m)^\s+linux\s+\/boot\/vmlinuz\s+root=UUID=[0-1]\s+ro=1\s+rootfstype=ext4\s+nomodeset\s+oops=panic\s+softlockup_panic=0\s+nmi_watchdog=1\s+rd\.shell=0\s+selinux=0\s+crashkernel=256M\s+panic=5\s+(debug\spci=nomis|pci=nomis\sdebug)$`,
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
@@ -274,14 +275,15 @@ menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestri
|
|
||||||
args: args{
|
|
||||||
config: &agent.SysConfig{
|
|
||||||
Contents: map[string]*agent.KeyInfo{
|
|
||||||
- "debug": {Operation: "delete"}, // delete key
|
|
||||||
- "pci": {Value: "nomis", Operation: "delete"}, // delete kv
|
|
||||||
- "debugpat": {Value: "", Operation: "add"}, // passed key, operation is invalid, default to add key
|
|
||||||
- "audit": {Value: "1", Operation: "add"}, // passed kv, key is inexistent, operation is invalid, default to add kv
|
|
||||||
+ "debug": {Operation: "delete"}, // delete key
|
|
||||||
+ "pci": {Value: "nomis", Operation: "delete"}, // delete kv
|
|
||||||
+ "debugpat": {Value: "", Operation: "add"}, // passed key, operation is invalid, default to add key
|
|
||||||
+ "audit": {Value: "1", Operation: "add"}, // passed kv, key is inexistent, operation is invalid, default to add kv
|
|
||||||
+ "nomodeset": {Value: "1", Operation: "delete"}, // delete key with inconsistent value
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
- pattern: `(?m)^\s+linux\s+\/boot\/vmlinuz\s+root=UUID=[0-1]\s+ro\s+rootfstype=ext4\s+nomodeset\s+oops=panic\s+softlockup_panic=0\s+nmi_watchdog=1\s+rd\.shell=0\s+selinux=0\s+crashkernel=256M\s+panic=5\s+(debugpat\saudit=1|audit=1\sdebugpat)$`,
|
|
||||||
+ pattern: `(?m)^\s+linux\s+\/boot\/vmlinuz\s+root=UUID=[0-1]\s+ro=1\s+rootfstype=ext4\s+nomodeset\s+oops=panic\s+softlockup_panic=0\s+nmi_watchdog=1\s+rd\.shell=0\s+selinux=0\s+crashkernel=256M\s+panic=5\s+(debugpat\saudit=1|audit=1\sdebugpat)$`,
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
@@ -300,6 +302,7 @@ menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestri
|
|
||||||
"": {Value: "test"}, // warning, skip, failed to add kv with empty key
|
|
||||||
"selinux": {Value: "1", Operation: "delete"},
|
|
||||||
"acpi": {Value: "off", Operation: "delete"},
|
|
||||||
+ "ro": {Value: ""},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
From 657e3e5c9bcc0fac3a079f51842d59a9e6b5e163 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Mon, 14 Aug 2023 09:53:16 +0800
|
|
||||||
Subject: [PATCH 10/17] KubeOS: fix proxy requeue bug
|
|
||||||
|
|
||||||
fix the bug that proxy may work after resuming normal from error status
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/proxy/controllers/os_controller.go | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/proxy/controllers/os_controller.go b/cmd/proxy/controllers/os_controller.go
|
|
||||||
index 09d61c0..30f9839 100644
|
|
||||||
--- a/cmd/proxy/controllers/os_controller.go
|
|
||||||
+++ b/cmd/proxy/controllers/os_controller.go
|
|
||||||
@@ -94,7 +94,7 @@ func (r *OSReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Re
|
|
||||||
if err = r.refreshNode(ctx, &node, osInstance, osCr.Spec.SysConfigs.Version, values.SysConfigName); err != nil {
|
|
||||||
return values.RequeueNow, err
|
|
||||||
}
|
|
||||||
- return values.RequeueNow, nil
|
|
||||||
+ return values.Requeue, nil
|
|
||||||
}
|
|
||||||
if configOps == values.UpdateConfig {
|
|
||||||
osInstance.Spec.SysConfigs = osCr.Spec.SysConfigs
|
|
||||||
@@ -124,7 +124,7 @@ func (r *OSReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Re
|
|
||||||
values.UpgradeConfigName); err != nil {
|
|
||||||
return values.RequeueNow, err
|
|
||||||
}
|
|
||||||
- return values.RequeueNow, nil
|
|
||||||
+ return values.Requeue, nil
|
|
||||||
}
|
|
||||||
if err := r.setConfig(ctx, osInstance, values.UpgradeConfigName); err != nil {
|
|
||||||
return values.RequeueNow, err
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,665 +0,0 @@
|
|||||||
From a87666e17d729feb67f987fa7038ef83b3fa2e1b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Mon, 14 Aug 2023 16:46:06 +0800
|
|
||||||
Subject: [PATCH 11/17] KubeOS: fix operator bug of missing deep copy
|
|
||||||
|
|
||||||
Fixed bug where operator didn't perform deep copy
|
|
||||||
add operator ut, testing in multiple nodes env
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/operator/controllers/os_controller.go | 44 +-
|
|
||||||
.../controllers/os_controller_test.go | 378 ++++++++++++++----
|
|
||||||
2 files changed, 330 insertions(+), 92 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/operator/controllers/os_controller.go b/cmd/operator/controllers/os_controller.go
|
|
||||||
index 620739b..d36f15d 100644
|
|
||||||
--- a/cmd/operator/controllers/os_controller.go
|
|
||||||
+++ b/cmd/operator/controllers/os_controller.go
|
|
||||||
@@ -15,6 +15,8 @@ package controllers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
+ "encoding/json"
|
|
||||||
+ "fmt"
|
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
|
||||||
@@ -188,7 +190,9 @@ func upgradeNodes(ctx context.Context, r common.ReadStatusWriter, os *upgradev1.
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
- updateNodeAndOSins(ctx, r, os, &node, &osInstance)
|
|
||||||
+ if err := updateNodeAndOSins(ctx, r, os, &node, &osInstance); err != nil {
|
|
||||||
+ continue
|
|
||||||
+ }
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -196,12 +200,16 @@ func upgradeNodes(ctx context.Context, r common.ReadStatusWriter, os *upgradev1.
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateNodeAndOSins(ctx context.Context, r common.ReadStatusWriter, os *upgradev1.OS,
|
|
||||||
- node *corev1.Node, osInstance *upgradev1.OSInstance) {
|
|
||||||
+ node *corev1.Node, osInstance *upgradev1.OSInstance) error {
|
|
||||||
if osInstance.Spec.UpgradeConfigs.Version != os.Spec.UpgradeConfigs.Version {
|
|
||||||
- osInstance.Spec.UpgradeConfigs = os.Spec.UpgradeConfigs
|
|
||||||
+ if err := deepCopySpecConfigs(os, osInstance, values.UpgradeConfigName); err != nil {
|
|
||||||
+ return err
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
if osInstance.Spec.SysConfigs.Version != os.Spec.SysConfigs.Version {
|
|
||||||
- osInstance.Spec.SysConfigs = os.Spec.SysConfigs
|
|
||||||
+ if err := deepCopySpecConfigs(os, osInstance, values.SysConfigName); err != nil {
|
|
||||||
+ return err
|
|
||||||
+ }
|
|
||||||
// exchange "grub.cmdline.current" and "grub.cmdline.next"
|
|
||||||
for i, config := range osInstance.Spec.SysConfigs.Configs {
|
|
||||||
if config.Model == "grub.cmdline.current" {
|
|
||||||
@@ -215,11 +223,14 @@ func updateNodeAndOSins(ctx context.Context, r common.ReadStatusWriter, os *upgr
|
|
||||||
osInstance.Spec.NodeStatus = values.NodeStatusUpgrade.String()
|
|
||||||
if err := r.Update(ctx, osInstance); err != nil {
|
|
||||||
log.Error(err, "unable to update", "osInstance", osInstance.Name)
|
|
||||||
+ return err
|
|
||||||
}
|
|
||||||
node.Labels[values.LabelUpgrading] = ""
|
|
||||||
if err := r.Update(ctx, node); err != nil {
|
|
||||||
log.Error(err, "unable to label", "node", node.Name)
|
|
||||||
+ return err
|
|
||||||
}
|
|
||||||
+ return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func assignConfig(ctx context.Context, r common.ReadStatusWriter, sysConfigs upgradev1.SysConfigs,
|
|
||||||
@@ -307,3 +318,28 @@ func min(a, b int) int {
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+func deepCopySpecConfigs(os *upgradev1.OS, osinstance *upgradev1.OSInstance, configType string) error {
|
|
||||||
+ switch configType {
|
|
||||||
+ case values.UpgradeConfigName:
|
|
||||||
+ data, err := json.Marshal(os.Spec.UpgradeConfigs)
|
|
||||||
+ if err != nil {
|
|
||||||
+ return err
|
|
||||||
+ }
|
|
||||||
+ if err = json.Unmarshal(data, &osinstance.Spec.UpgradeConfigs); err != nil {
|
|
||||||
+ return err
|
|
||||||
+ }
|
|
||||||
+ case values.SysConfigName:
|
|
||||||
+ data, err := json.Marshal(os.Spec.SysConfigs)
|
|
||||||
+ if err != nil {
|
|
||||||
+ return err
|
|
||||||
+ }
|
|
||||||
+ if err = json.Unmarshal(data, &osinstance.Spec.SysConfigs); err != nil {
|
|
||||||
+ return err
|
|
||||||
+ }
|
|
||||||
+ default:
|
|
||||||
+ log.Error(nil, "configType "+configType+" cannot be recognized")
|
|
||||||
+ return fmt.Errorf("configType %s cannot be recognized", configType)
|
|
||||||
+ }
|
|
||||||
+ return nil
|
|
||||||
+}
|
|
||||||
diff --git a/cmd/operator/controllers/os_controller_test.go b/cmd/operator/controllers/os_controller_test.go
|
|
||||||
index 98de6d0..e59ce7e 100644
|
|
||||||
--- a/cmd/operator/controllers/os_controller_test.go
|
|
||||||
+++ b/cmd/operator/controllers/os_controller_test.go
|
|
||||||
@@ -17,19 +17,12 @@ import (
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
- "github.com/agiledragon/gomonkey/v2"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
. "github.com/onsi/ginkgo/v2"
|
|
||||||
. "github.com/onsi/gomega"
|
|
||||||
v1 "k8s.io/api/core/v1"
|
|
||||||
- "k8s.io/apimachinery/pkg/api/errors"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
- "k8s.io/apimachinery/pkg/runtime"
|
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
- "k8s.io/client-go/kubernetes/scheme"
|
|
||||||
- "k8s.io/client-go/util/workqueue"
|
|
||||||
- "sigs.k8s.io/controller-runtime/pkg/client"
|
|
||||||
- "sigs.k8s.io/controller-runtime/pkg/event"
|
|
||||||
|
|
||||||
upgradev1 "openeuler.org/KubeOS/api/v1alpha1"
|
|
||||||
"openeuler.org/KubeOS/pkg/values"
|
|
||||||
@@ -37,8 +30,7 @@ import (
|
|
||||||
|
|
||||||
var _ = Describe("OsController", func() {
|
|
||||||
const (
|
|
||||||
- OSName = "test-os"
|
|
||||||
-
|
|
||||||
+ OSName = "test-os"
|
|
||||||
timeout = time.Second * 20
|
|
||||||
interval = time.Millisecond * 500
|
|
||||||
)
|
|
||||||
@@ -72,26 +64,33 @@ var _ = Describe("OsController", func() {
|
|
||||||
})
|
|
||||||
|
|
||||||
AfterEach(func() {
|
|
||||||
- desiredTestNamespace := &v1.Namespace{
|
|
||||||
- TypeMeta: metav1.TypeMeta{
|
|
||||||
- APIVersion: "v1",
|
|
||||||
- Kind: "Namespace",
|
|
||||||
- },
|
|
||||||
- ObjectMeta: metav1.ObjectMeta{
|
|
||||||
- Name: testNamespace,
|
|
||||||
- },
|
|
||||||
+ // delete all nodes
|
|
||||||
+ nodeList := &v1.NodeList{}
|
|
||||||
+ err := k8sClient.List(context.Background(), nodeList)
|
|
||||||
+ Expect(err).ToNot(HaveOccurred())
|
|
||||||
+ for _, node := range nodeList.Items {
|
|
||||||
+ k8sClient.Delete(context.Background(), &node)
|
|
||||||
}
|
|
||||||
- // Add any teardown steps that needs to be executed after each test
|
|
||||||
- err := k8sClient.Delete(context.Background(), desiredTestNamespace,
|
|
||||||
- client.PropagationPolicy(metav1.DeletePropagationForeground))
|
|
||||||
+ nodeList = &v1.NodeList{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err = k8sClient.List(context.Background(), nodeList)
|
|
||||||
+ if err != nil || len(nodeList.Items) != 0 {
|
|
||||||
+ return false
|
|
||||||
+ }
|
|
||||||
+ return true
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
|
|
||||||
+ // delete all OS CRs
|
|
||||||
+ osList := &upgradev1.OSList{}
|
|
||||||
+ err = k8sClient.List(context.Background(), osList)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
-
|
|
||||||
- existingNamespace := &v1.Namespace{}
|
|
||||||
+ for _, os := range osList.Items {
|
|
||||||
+ k8sClient.Delete(context.Background(), &os)
|
|
||||||
+ }
|
|
||||||
+ osList = &upgradev1.OSList{}
|
|
||||||
Eventually(func() bool {
|
|
||||||
- err := k8sClient.Get(context.Background(), types.NamespacedName{Name: testNamespace},
|
|
||||||
- existingNamespace)
|
|
||||||
- if err != nil && errors.IsNotFound(err) {
|
|
||||||
+ err = k8sClient.List(context.Background(), osList)
|
|
||||||
+ if err != nil || len(osList.Items) != 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
@@ -102,7 +101,7 @@ var _ = Describe("OsController", func() {
|
|
||||||
It("Should label the osinstance's nodestatus to upgrading", func() {
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
- // create Node
|
|
||||||
+ // create Node1
|
|
||||||
node1Name = "test-node-" + uuid.New().String()
|
|
||||||
node1 := &v1.Node{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
@@ -131,7 +130,7 @@ var _ = Describe("OsController", func() {
|
|
||||||
return err == nil
|
|
||||||
}, timeout, interval).Should(BeTrue())
|
|
||||||
|
|
||||||
- // create OSInstance
|
|
||||||
+ // create OSInstance1
|
|
||||||
OSIns := &upgradev1.OSInstance{
|
|
||||||
TypeMeta: metav1.TypeMeta{
|
|
||||||
Kind: "OSInstance",
|
|
||||||
@@ -163,6 +162,67 @@ var _ = Describe("OsController", func() {
|
|
||||||
}, timeout, interval).Should(BeTrue())
|
|
||||||
Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node1Name))
|
|
||||||
|
|
||||||
+ // create Node2
|
|
||||||
+ node2Name := "test-node-" + uuid.New().String()
|
|
||||||
+ node2 := &v1.Node{
|
|
||||||
+ ObjectMeta: metav1.ObjectMeta{
|
|
||||||
+ Name: node2Name,
|
|
||||||
+ Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ "beta.kubernetes.io/os": "linux",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ TypeMeta: metav1.TypeMeta{
|
|
||||||
+ APIVersion: "v1",
|
|
||||||
+ Kind: "Node",
|
|
||||||
+ },
|
|
||||||
+ Status: v1.NodeStatus{
|
|
||||||
+ NodeInfo: v1.NodeSystemInfo{
|
|
||||||
+ OSImage: "KubeOS v2",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ err = k8sClient.Create(ctx, node2)
|
|
||||||
+ Expect(err).ToNot(HaveOccurred())
|
|
||||||
+ existingNode = &v1.Node{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(context.Background(),
|
|
||||||
+ types.NamespacedName{Name: node2Name, Namespace: testNamespace}, existingNode)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+
|
|
||||||
+ // create OSInstance2
|
|
||||||
+ OSIns = &upgradev1.OSInstance{
|
|
||||||
+ TypeMeta: metav1.TypeMeta{
|
|
||||||
+ Kind: "OSInstance",
|
|
||||||
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
|
|
||||||
+ },
|
|
||||||
+ ObjectMeta: metav1.ObjectMeta{
|
|
||||||
+ Name: node2Name,
|
|
||||||
+ Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ values.LabelOSinstance: node2Name,
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ Spec: upgradev1.OSInstanceSpec{
|
|
||||||
+ SysConfigs: upgradev1.SysConfigs{
|
|
||||||
+ Version: "v1",
|
|
||||||
+ Configs: []upgradev1.SysConfig{},
|
|
||||||
+ },
|
|
||||||
+ UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}, Version: "v1"},
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
|
|
||||||
+
|
|
||||||
+ // Check that the corresponding OSIns CR has been created
|
|
||||||
+ osInsCRLookupKey2 := types.NamespacedName{Name: node2Name, Namespace: testNamespace}
|
|
||||||
+ createdOSIns = &upgradev1.OSInstance{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node2Name))
|
|
||||||
+
|
|
||||||
// create OS CR
|
|
||||||
OS := &upgradev1.OS{
|
|
||||||
TypeMeta: metav1.TypeMeta{
|
|
||||||
@@ -206,13 +266,20 @@ var _ = Describe("OsController", func() {
|
|
||||||
return err == nil
|
|
||||||
}, timeout, interval).Should(BeTrue())
|
|
||||||
Expect(createdOSIns.Spec.NodeStatus).Should(Equal(values.NodeStatusUpgrade.String()))
|
|
||||||
+
|
|
||||||
+ createdOSIns2 := &upgradev1.OSInstance{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns2)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ Expect(createdOSIns2.Spec.NodeStatus).Should(Equal(values.NodeStatusUpgrade.String()))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Context("When we want to configure node", func() {
|
|
||||||
It("Should update OSInstance spec and update NodeStatus to config", func() {
|
|
||||||
ctx := context.Background()
|
|
||||||
- // create Node
|
|
||||||
+ // create Node1
|
|
||||||
node1Name = "test-node-" + uuid.New().String()
|
|
||||||
node1 := &v1.Node{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
@@ -228,7 +295,7 @@ var _ = Describe("OsController", func() {
|
|
||||||
},
|
|
||||||
Status: v1.NodeStatus{
|
|
||||||
NodeInfo: v1.NodeSystemInfo{
|
|
||||||
- OSImage: "KubeOS v2",
|
|
||||||
+ OSImage: "KubeOS v1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -241,6 +308,7 @@ var _ = Describe("OsController", func() {
|
|
||||||
return err == nil
|
|
||||||
}, timeout, interval).Should(BeTrue())
|
|
||||||
|
|
||||||
+ // create OSInstance1
|
|
||||||
OSIns := &upgradev1.OSInstance{
|
|
||||||
TypeMeta: metav1.TypeMeta{
|
|
||||||
Kind: "OSInstance",
|
|
||||||
@@ -249,6 +317,9 @@ var _ = Describe("OsController", func() {
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: node1Name,
|
|
||||||
Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ values.LabelOSinstance: node1Name,
|
|
||||||
+ },
|
|
||||||
},
|
|
||||||
Spec: upgradev1.OSInstanceSpec{
|
|
||||||
SysConfigs: upgradev1.SysConfigs{
|
|
||||||
@@ -261,14 +332,76 @@ var _ = Describe("OsController", func() {
|
|
||||||
}
|
|
||||||
Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
|
|
||||||
|
|
||||||
- osInsCRLookupKey := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
|
|
||||||
+ osInsCRLookupKey1 := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
|
|
||||||
createdOSIns := &upgradev1.OSInstance{}
|
|
||||||
Eventually(func() bool {
|
|
||||||
- err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
|
|
||||||
+ err := k8sClient.Get(ctx, osInsCRLookupKey1, createdOSIns)
|
|
||||||
return err == nil
|
|
||||||
}, timeout, interval).Should(BeTrue())
|
|
||||||
Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node1Name))
|
|
||||||
|
|
||||||
+ // create Node2
|
|
||||||
+ node2Name := "test-node-" + uuid.New().String()
|
|
||||||
+ node2 := &v1.Node{
|
|
||||||
+ ObjectMeta: metav1.ObjectMeta{
|
|
||||||
+ Name: node2Name,
|
|
||||||
+ Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ "beta.kubernetes.io/os": "linux",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ TypeMeta: metav1.TypeMeta{
|
|
||||||
+ APIVersion: "v1",
|
|
||||||
+ Kind: "Node",
|
|
||||||
+ },
|
|
||||||
+ Status: v1.NodeStatus{
|
|
||||||
+ NodeInfo: v1.NodeSystemInfo{
|
|
||||||
+ OSImage: "KubeOS v1",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ err = k8sClient.Create(ctx, node2)
|
|
||||||
+ Expect(err).ToNot(HaveOccurred())
|
|
||||||
+ existingNode = &v1.Node{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(context.Background(),
|
|
||||||
+ types.NamespacedName{Name: node2Name, Namespace: testNamespace}, existingNode)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+
|
|
||||||
+ // create OSInstance2
|
|
||||||
+ OSIns = &upgradev1.OSInstance{
|
|
||||||
+ TypeMeta: metav1.TypeMeta{
|
|
||||||
+ Kind: "OSInstance",
|
|
||||||
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
|
|
||||||
+ },
|
|
||||||
+ ObjectMeta: metav1.ObjectMeta{
|
|
||||||
+ Name: node2Name,
|
|
||||||
+ Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ values.LabelOSinstance: node2Name,
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ Spec: upgradev1.OSInstanceSpec{
|
|
||||||
+ SysConfigs: upgradev1.SysConfigs{
|
|
||||||
+ Version: "v1",
|
|
||||||
+ Configs: []upgradev1.SysConfig{},
|
|
||||||
+ },
|
|
||||||
+ UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}, Version: "v1"},
|
|
||||||
+ NodeStatus: values.NodeStatusIdle.String(),
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
|
|
||||||
+
|
|
||||||
+ // Check that the corresponding OSIns CR has been created
|
|
||||||
+ osInsCRLookupKey2 := types.NamespacedName{Name: node2Name, Namespace: testNamespace}
|
|
||||||
+ createdOSIns = &upgradev1.OSInstance{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node2Name))
|
|
||||||
+
|
|
||||||
OS := &upgradev1.OS{
|
|
||||||
TypeMeta: metav1.TypeMeta{
|
|
||||||
APIVersion: "upgrade.openeuler.org/v1alpha1",
|
|
||||||
@@ -311,13 +444,21 @@ var _ = Describe("OsController", func() {
|
|
||||||
Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v1"))
|
|
||||||
|
|
||||||
time.Sleep(1 * time.Second) // sleep a while to make sure Reconcile finished
|
|
||||||
- configedOSIns := &upgradev1.OSInstance{}
|
|
||||||
+ configedOSIns1 := &upgradev1.OSInstance{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(ctx, osInsCRLookupKey1, configedOSIns1)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ Expect(configedOSIns1.Spec.NodeStatus).Should(Equal(values.NodeStatusConfig.String()))
|
|
||||||
+ Expect(configedOSIns1.Spec.SysConfigs.Version).Should(Equal("v2"))
|
|
||||||
+
|
|
||||||
+ configedOSIns2 := &upgradev1.OSInstance{}
|
|
||||||
Eventually(func() bool {
|
|
||||||
- err := k8sClient.Get(ctx, osInsCRLookupKey, configedOSIns)
|
|
||||||
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, configedOSIns2)
|
|
||||||
return err == nil
|
|
||||||
}, timeout, interval).Should(BeTrue())
|
|
||||||
- Expect(configedOSIns.Spec.NodeStatus).Should(Equal(values.NodeStatusConfig.String()))
|
|
||||||
- Expect(configedOSIns.Spec.SysConfigs.Version).Should(Equal("v2"))
|
|
||||||
+ Expect(configedOSIns2.Spec.NodeStatus).Should(Equal(values.NodeStatusConfig.String()))
|
|
||||||
+ Expect(configedOSIns2.Spec.SysConfigs.Version).Should(Equal("v2"))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
@@ -394,6 +535,9 @@ var _ = Describe("OsController", func() {
|
|
||||||
}, timeout, interval).Should(BeTrue())
|
|
||||||
_, ok := existingNode.Labels[values.LabelUpgrading]
|
|
||||||
Expect(ok).Should(Equal(false))
|
|
||||||
+
|
|
||||||
+ createdOS.Spec.OpsType = "test"
|
|
||||||
+ Expect(k8sClient.Update(ctx, createdOS)).Should(Succeed())
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
@@ -401,7 +545,7 @@ var _ = Describe("OsController", func() {
|
|
||||||
It("Should exchange .current and .next", func() {
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
- // create Node
|
|
||||||
+ // create Node1
|
|
||||||
node1Name = "test-node-" + uuid.New().String()
|
|
||||||
node1 := &v1.Node{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
@@ -430,7 +574,7 @@ var _ = Describe("OsController", func() {
|
|
||||||
return err == nil
|
|
||||||
}, timeout, interval).Should(BeTrue())
|
|
||||||
|
|
||||||
- // create OSInstance
|
|
||||||
+ // create OSInstance1
|
|
||||||
OSIns := &upgradev1.OSInstance{
|
|
||||||
TypeMeta: metav1.TypeMeta{
|
|
||||||
Kind: "OSInstance",
|
|
||||||
@@ -454,14 +598,75 @@ var _ = Describe("OsController", func() {
|
|
||||||
Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
|
|
||||||
|
|
||||||
// Check that the corresponding OSIns CR has been created
|
|
||||||
- osInsCRLookupKey := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
|
|
||||||
+ osInsCRLookupKey1 := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
|
|
||||||
createdOSIns := &upgradev1.OSInstance{}
|
|
||||||
Eventually(func() bool {
|
|
||||||
- err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
|
|
||||||
+ err := k8sClient.Get(ctx, osInsCRLookupKey1, createdOSIns)
|
|
||||||
return err == nil
|
|
||||||
}, timeout, interval).Should(BeTrue())
|
|
||||||
Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node1Name))
|
|
||||||
|
|
||||||
+ // create Node2
|
|
||||||
+ node2Name := "test-node-" + uuid.New().String()
|
|
||||||
+ node2 := &v1.Node{
|
|
||||||
+ ObjectMeta: metav1.ObjectMeta{
|
|
||||||
+ Name: node2Name,
|
|
||||||
+ Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ "beta.kubernetes.io/os": "linux",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ TypeMeta: metav1.TypeMeta{
|
|
||||||
+ APIVersion: "v1",
|
|
||||||
+ Kind: "Node",
|
|
||||||
+ },
|
|
||||||
+ Status: v1.NodeStatus{
|
|
||||||
+ NodeInfo: v1.NodeSystemInfo{
|
|
||||||
+ OSImage: "KubeOS v1",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ err = k8sClient.Create(ctx, node2)
|
|
||||||
+ Expect(err).ToNot(HaveOccurred())
|
|
||||||
+ existingNode = &v1.Node{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(context.Background(),
|
|
||||||
+ types.NamespacedName{Name: node2Name, Namespace: testNamespace}, existingNode)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+
|
|
||||||
+ // create OSInstance2
|
|
||||||
+ OSIns = &upgradev1.OSInstance{
|
|
||||||
+ TypeMeta: metav1.TypeMeta{
|
|
||||||
+ Kind: "OSInstance",
|
|
||||||
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
|
|
||||||
+ },
|
|
||||||
+ ObjectMeta: metav1.ObjectMeta{
|
|
||||||
+ Name: node2Name,
|
|
||||||
+ Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ values.LabelOSinstance: node2Name,
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ Spec: upgradev1.OSInstanceSpec{
|
|
||||||
+ SysConfigs: upgradev1.SysConfigs{
|
|
||||||
+ Version: "v1",
|
|
||||||
+ Configs: []upgradev1.SysConfig{},
|
|
||||||
+ },
|
|
||||||
+ UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}, Version: "v1"},
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
|
|
||||||
+
|
|
||||||
+ // Check that the corresponding OSIns CR has been created
|
|
||||||
+ osInsCRLookupKey2 := types.NamespacedName{Name: node2Name, Namespace: testNamespace}
|
|
||||||
+ createdOSIns = &upgradev1.OSInstance{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node2Name))
|
|
||||||
+
|
|
||||||
// create OS CR
|
|
||||||
OS := &upgradev1.OS{
|
|
||||||
TypeMeta: metav1.TypeMeta{
|
|
||||||
@@ -486,7 +691,13 @@ var _ = Describe("OsController", func() {
|
|
||||||
{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
- UpgradeConfigs: upgradev1.SysConfigs{Configs: []upgradev1.SysConfig{}},
|
|
||||||
+ UpgradeConfigs: upgradev1.SysConfigs{
|
|
||||||
+ Version: "v2",
|
|
||||||
+ Configs: []upgradev1.SysConfig{
|
|
||||||
+ {Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}},
|
|
||||||
+ {Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}},
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
},
|
|
||||||
}
|
|
||||||
Expect(k8sClient.Create(ctx, OS)).Should(Succeed())
|
|
||||||
@@ -501,75 +712,66 @@ var _ = Describe("OsController", func() {
|
|
||||||
Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v2"))
|
|
||||||
|
|
||||||
time.Sleep(1 * time.Second) // sleep a while to make sure Reconcile finished
|
|
||||||
- osInsCRLookupKey = types.NamespacedName{Name: node1Name, Namespace: testNamespace}
|
|
||||||
+ // check node1 osinstance
|
|
||||||
createdOSIns = &upgradev1.OSInstance{}
|
|
||||||
Eventually(func() bool {
|
|
||||||
- err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
|
|
||||||
+ err := k8sClient.Get(ctx, osInsCRLookupKey1, createdOSIns)
|
|
||||||
return err == nil
|
|
||||||
}, timeout, interval).Should(BeTrue())
|
|
||||||
Expect(createdOSIns.Spec.SysConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
|
|
||||||
Expect(createdOSIns.Spec.SysConfigs.Configs[1]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}}))
|
|
||||||
+ Expect(createdOSIns.Spec.UpgradeConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
|
|
||||||
+ Expect(createdOSIns.Spec.NodeStatus).Should(Equal(values.NodeStatusUpgrade.String()))
|
|
||||||
+
|
|
||||||
+ // check node2 osinstance
|
|
||||||
+ createdOSIns2 := &upgradev1.OSInstance{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(ctx, osInsCRLookupKey2, createdOSIns2)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ Expect(createdOSIns2.Spec.NodeStatus).Should(Equal(values.NodeStatusUpgrade.String()))
|
|
||||||
+ Expect(createdOSIns2.Spec.SysConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
|
|
||||||
+ Expect(createdOSIns2.Spec.SysConfigs.Configs[1]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}}))
|
|
||||||
+ Expect(createdOSIns2.Spec.UpgradeConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
|
|
||||||
+
|
|
||||||
+ // check os cr spec
|
|
||||||
+ osCRLookupKey = types.NamespacedName{Name: OSName, Namespace: testNamespace}
|
|
||||||
+ createdOS = &upgradev1.OS{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(ctx, osCRLookupKey, createdOS)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ Expect(createdOS.Spec.SysConfigs.Configs[0]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.current", Contents: []upgradev1.Content{{Key: "a", Value: "1"}}}))
|
|
||||||
+ Expect(createdOS.Spec.SysConfigs.Configs[1]).Should(Equal(upgradev1.SysConfig{Model: "grub.cmdline.next", Contents: []upgradev1.Content{{Key: "b", Value: "2"}}}))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
-func TestOSReconciler_DeleteOSInstance(t *testing.T) {
|
|
||||||
- type fields struct {
|
|
||||||
- Scheme *runtime.Scheme
|
|
||||||
- Client client.Client
|
|
||||||
- }
|
|
||||||
- kClient, _ := client.New(cfg, client.Options{Scheme: scheme.Scheme})
|
|
||||||
+func Test_deepCopySpecConfigs(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
- e event.DeleteEvent
|
|
||||||
- q workqueue.RateLimitingInterface
|
|
||||||
+ os *upgradev1.OS
|
|
||||||
+ osinstance *upgradev1.OSInstance
|
|
||||||
+ configType string
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
- name string
|
|
||||||
- fields fields
|
|
||||||
- args args
|
|
||||||
+ name string
|
|
||||||
+ args args
|
|
||||||
+ wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
- name: "delete osinstance",
|
|
||||||
- fields: fields{
|
|
||||||
- Scheme: nil,
|
|
||||||
- Client: kClient,
|
|
||||||
- },
|
|
||||||
+ name: "error",
|
|
||||||
args: args{
|
|
||||||
- e: event.DeleteEvent{
|
|
||||||
- Object: &upgradev1.OSInstance{
|
|
||||||
- ObjectMeta: metav1.ObjectMeta{
|
|
||||||
- Name: "test-node1",
|
|
||||||
- Namespace: "test",
|
|
||||||
- },
|
|
||||||
- },
|
|
||||||
- },
|
|
||||||
- q: nil,
|
|
||||||
- },
|
|
||||||
+ os: &upgradev1.OS{},
|
|
||||||
+ osinstance: &upgradev1.OSInstance{},
|
|
||||||
+ configType: "test"},
|
|
||||||
+ wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
- var patchList *gomonkey.Patches
|
|
||||||
- var patchDelete *gomonkey.Patches
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
- r := &OSReconciler{
|
|
||||||
- Scheme: tt.fields.Scheme,
|
|
||||||
- Client: tt.fields.Client,
|
|
||||||
+ if err := deepCopySpecConfigs(tt.args.os, tt.args.osinstance, tt.args.configType); (err != nil) != tt.wantErr {
|
|
||||||
+ t.Errorf("deepCopySpecConfigs() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
}
|
|
||||||
- patchList = gomonkey.ApplyMethodFunc(r.Client, "List", func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
|
|
||||||
- list.(*upgradev1.OSInstanceList).Items = []upgradev1.OSInstance{
|
|
||||||
- {
|
|
||||||
- ObjectMeta: metav1.ObjectMeta{
|
|
||||||
- Name: "test-node1",
|
|
||||||
- Namespace: "test",
|
|
||||||
- },
|
|
||||||
- },
|
|
||||||
- }
|
|
||||||
- return nil
|
|
||||||
- })
|
|
||||||
- patchDelete = gomonkey.ApplyMethodReturn(r.Client, "Delete", nil)
|
|
||||||
- r.DeleteOSInstance(tt.args.e, tt.args.q)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
- defer patchDelete.Reset()
|
|
||||||
- defer patchList.Reset()
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,191 +0,0 @@
|
|||||||
From 9bd13d2a1b8b7282d7247caf9ba54f11bb297cd5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Fri, 11 Aug 2023 20:25:46 +0800
|
|
||||||
Subject: [PATCH 12/17] KubeOS: add unit test
|
|
||||||
|
|
||||||
add containerd_image and disk_image unit test
|
|
||||||
modify make test command for only testing server and controllers
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
Makefile | 2 +-
|
|
||||||
cmd/agent/server/containerd_image_test.go | 10 ++-
|
|
||||||
cmd/agent/server/disk_image_test.go | 83 +++++++++++++++++++----
|
|
||||||
3 files changed, 80 insertions(+), 15 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/Makefile b/Makefile
|
|
||||||
index b5b6161..eddf9e6 100644
|
|
||||||
--- a/Makefile
|
|
||||||
+++ b/Makefile
|
|
||||||
@@ -133,7 +133,7 @@ kustomize:
|
|
||||||
$(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v3@v3.8.7)
|
|
||||||
|
|
||||||
ARCH := $(shell uname -m)
|
|
||||||
-TEST_CMD := go test ./... -race -count=1 -timeout=300s -cover -gcflags=all=-l -p 1
|
|
||||||
+TEST_CMD := go test `go list ./cmd/... | grep -E 'server|controllers'` -race -count=1 -timeout=300s -cover -gcflags=all=-l -p 1
|
|
||||||
|
|
||||||
ifeq ($(ARCH), aarch64)
|
|
||||||
TEST_CMD := ETCD_UNSUPPORTED_ARCH=arm64 $(TEST_CMD)
|
|
||||||
diff --git a/cmd/agent/server/containerd_image_test.go b/cmd/agent/server/containerd_image_test.go
|
|
||||||
index d7133c3..85347c8 100644
|
|
||||||
--- a/cmd/agent/server/containerd_image_test.go
|
|
||||||
+++ b/cmd/agent/server/containerd_image_test.go
|
|
||||||
@@ -32,7 +32,6 @@ func Test_conImageHandler_downloadImage(t *testing.T) {
|
|
||||||
want string
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
-
|
|
||||||
{
|
|
||||||
name: "pullImageError",
|
|
||||||
c: conImageHandler{},
|
|
||||||
@@ -62,6 +61,15 @@ func Test_conImageHandler_downloadImage(t *testing.T) {
|
|
||||||
want: "update-test1/upadte.img",
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
+ {
|
|
||||||
+ name: "invalid image name",
|
|
||||||
+ c: conImageHandler{},
|
|
||||||
+ args: args{
|
|
||||||
+ req: &pb.UpdateRequest{ContainerImage: "nginx;v1"},
|
|
||||||
+ },
|
|
||||||
+ want: "",
|
|
||||||
+ wantErr: true,
|
|
||||||
+ },
|
|
||||||
}
|
|
||||||
patchPrepareEnv := gomonkey.ApplyFunc(prepareEnv, func() (preparePath, error) {
|
|
||||||
return preparePath{updatePath: "update-test1/",
|
|
||||||
diff --git a/cmd/agent/server/disk_image_test.go b/cmd/agent/server/disk_image_test.go
|
|
||||||
index 71c5de7..265b323 100644
|
|
||||||
--- a/cmd/agent/server/disk_image_test.go
|
|
||||||
+++ b/cmd/agent/server/disk_image_test.go
|
|
||||||
@@ -21,6 +21,7 @@ import (
|
|
||||||
"crypto/x509/pkix"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/pem"
|
|
||||||
+ "fmt"
|
|
||||||
"io"
|
|
||||||
"math/big"
|
|
||||||
"net/http"
|
|
||||||
@@ -52,36 +53,78 @@ func Test_download(t *testing.T) {
|
|
||||||
want string
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
- // {name: "errornil", args: args{&pb.UpdateRequest{Certs: &pb.CertsInfo{}}}, want: "", wantErr: true},
|
|
||||||
- // {name: "normal", args: args{&pb.UpdateRequest{ImageUrl: "http://www.openeuler.org/zh/", FlagSafe: true, Certs: &pb.CertsInfo{}}}, want: "/persist/update.img", wantErr: false},
|
|
||||||
- // {name: "errornodir", args: args{&pb.UpdateRequest{ImageUrl: "http://www.openeuler.org/zh/", FlagSafe: true, Certs: &pb.CertsInfo{}}}, want: "", wantErr: true},
|
|
||||||
+ {name: "errornil", args: args{&pb.UpdateRequest{Certs: &pb.CertsInfo{}}}, want: "", wantErr: true},
|
|
||||||
+ {name: "error response", args: args{&pb.UpdateRequest{ImageUrl: "http://www.openeuler.abc", FlagSafe: true, Certs: &pb.CertsInfo{}}}, want: "", wantErr: true},
|
|
||||||
{
|
|
||||||
name: "normal",
|
|
||||||
args: args{
|
|
||||||
req: &pb.UpdateRequest{
|
|
||||||
ImageUrl: "http://www.openeuler.org/zh/",
|
|
||||||
+ FlagSafe: true,
|
|
||||||
+ Certs: &pb.CertsInfo{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
want: tmpFileForDownload,
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
+ {
|
|
||||||
+ name: "disk space not enough",
|
|
||||||
+ args: args{
|
|
||||||
+ req: &pb.UpdateRequest{
|
|
||||||
+ ImageUrl: "http://www.openeuler.org/zh/",
|
|
||||||
+ FlagSafe: true,
|
|
||||||
+ Certs: &pb.CertsInfo{},
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ want: "",
|
|
||||||
+ wantErr: true,
|
|
||||||
+ },
|
|
||||||
}
|
|
||||||
- patchStatfs := gomonkey.ApplyFunc(syscall.Statfs, func(path string, stat *syscall.Statfs_t) error {
|
|
||||||
+ var patchStatfs *gomonkey.Patches
|
|
||||||
+ patchStatfs = gomonkey.ApplyFunc(syscall.Statfs, func(path string, stat *syscall.Statfs_t) error {
|
|
||||||
stat.Bfree = 3000
|
|
||||||
stat.Bsize = 4096
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
defer patchStatfs.Reset()
|
|
||||||
- patchGetImageUrl := gomonkey.ApplyFuncReturn(getImageURL, &http.Response{
|
|
||||||
- StatusCode: http.StatusOK,
|
|
||||||
- ContentLength: 5,
|
|
||||||
- Body: io.NopCloser(strings.NewReader("hello")),
|
|
||||||
- }, nil)
|
|
||||||
+ patchGetImageUrl := gomonkey.ApplyFuncSeq(getImageURL,
|
|
||||||
+ []gomonkey.OutputCell{
|
|
||||||
+ {Values: gomonkey.Params{&http.Response{}, fmt.Errorf("error")}},
|
|
||||||
+ {Values: gomonkey.Params{&http.Response{StatusCode: http.StatusBadRequest, Body: io.NopCloser(strings.NewReader(""))}, nil}},
|
|
||||||
+ {
|
|
||||||
+ Values: gomonkey.Params{
|
|
||||||
+ &http.Response{
|
|
||||||
+ StatusCode: http.StatusOK,
|
|
||||||
+ ContentLength: 5,
|
|
||||||
+ Body: io.NopCloser(strings.NewReader("hello")),
|
|
||||||
+ },
|
|
||||||
+ nil,
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ {
|
|
||||||
+ Values: gomonkey.Params{
|
|
||||||
+ &http.Response{
|
|
||||||
+ StatusCode: http.StatusOK,
|
|
||||||
+ ContentLength: 5,
|
|
||||||
+ Body: io.NopCloser(strings.NewReader("hello")),
|
|
||||||
+ },
|
|
||||||
+ nil,
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ )
|
|
||||||
defer patchGetImageUrl.Reset()
|
|
||||||
patchOSCreate := gomonkey.ApplyFuncReturn(os.Create, tmpFile, nil)
|
|
||||||
defer patchOSCreate.Reset()
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
+ if tt.name == "disk space not enough" {
|
|
||||||
+ patchStatfs = gomonkey.ApplyFunc(syscall.Statfs, func(path string, stat *syscall.Statfs_t) error {
|
|
||||||
+ stat.Bfree = 1
|
|
||||||
+ stat.Bsize = 4096
|
|
||||||
+ return nil
|
|
||||||
+ })
|
|
||||||
+ }
|
|
||||||
got, err := download(tt.args.req)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("download() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
@@ -160,13 +203,27 @@ func Test_getImageURL(t *testing.T) {
|
|
||||||
MTLS: false,
|
|
||||||
Certs: &pb.CertsInfo{},
|
|
||||||
}}, want: &http.Response{StatusCode: http.StatusOK}, wantErr: false},
|
|
||||||
+ {name: "httpsLoadCertsError", args: args{req: &pb.UpdateRequest{
|
|
||||||
+ ImageUrl: "https://www.openeuler.abc/zh/",
|
|
||||||
+ FlagSafe: true,
|
|
||||||
+ MTLS: false,
|
|
||||||
+ Certs: &pb.CertsInfo{},
|
|
||||||
+ }}, want: &http.Response{}, wantErr: true},
|
|
||||||
+ {name: "httpsMLTSLoadCertsError", args: args{req: &pb.UpdateRequest{
|
|
||||||
+ ImageUrl: "https://www.openeuler.abc/zh/",
|
|
||||||
+ FlagSafe: true,
|
|
||||||
+ MTLS: true,
|
|
||||||
+ Certs: &pb.CertsInfo{},
|
|
||||||
+ }}, want: &http.Response{}, wantErr: true},
|
|
||||||
}
|
|
||||||
- patchLoadClientCerts := gomonkey.ApplyFunc(loadClientCerts, func(caCert, clientCert, clientKey string) (*http.Client, error) {
|
|
||||||
- return &http.Client{}, nil
|
|
||||||
+ patchLoadClientCerts := gomonkey.ApplyFuncSeq(loadClientCerts, []gomonkey.OutputCell{
|
|
||||||
+ {Values: gomonkey.Params{&http.Client{}, nil}},
|
|
||||||
+ {Values: gomonkey.Params{&http.Client{}, fmt.Errorf("error")}},
|
|
||||||
})
|
|
||||||
defer patchLoadClientCerts.Reset()
|
|
||||||
- patchLoadCaCerts := gomonkey.ApplyFunc(loadCaCerts, func(caCert string) (*http.Client, error) {
|
|
||||||
- return &http.Client{}, nil
|
|
||||||
+ patchLoadCaCerts := gomonkey.ApplyFuncSeq(loadCaCerts, []gomonkey.OutputCell{
|
|
||||||
+ {Values: gomonkey.Params{&http.Client{}, nil}},
|
|
||||||
+ {Values: gomonkey.Params{&http.Client{}, fmt.Errorf("error")}},
|
|
||||||
})
|
|
||||||
defer patchLoadCaCerts.Reset()
|
|
||||||
patchGet := gomonkey.ApplyFunc(http.Get, func(url string) (resp *http.Response, err error) {
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,126 +0,0 @@
|
|||||||
From 1bc41e7e58e99e23cd8be522cc1c2d30090975d2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Tue, 15 Aug 2023 16:33:11 +0800
|
|
||||||
Subject: [PATCH 13/17] KubeOS: fix clean space problems
|
|
||||||
|
|
||||||
add clean space function in server
|
|
||||||
change docker rm position in docker_image
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/agent/main.go | 4 +---
|
|
||||||
cmd/agent/server/docker_image.go | 6 +++---
|
|
||||||
cmd/agent/server/server.go | 9 +++++++++
|
|
||||||
cmd/agent/server/utils.go | 27 +++++++++++++--------------
|
|
||||||
4 files changed, 26 insertions(+), 20 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/agent/main.go b/cmd/agent/main.go
|
|
||||||
index 67c7e2d..7b1ed3d 100644
|
|
||||||
--- a/cmd/agent/main.go
|
|
||||||
+++ b/cmd/agent/main.go
|
|
||||||
@@ -13,8 +13,6 @@
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
- "fmt"
|
|
||||||
-
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
|
|
||||||
@@ -24,7 +22,7 @@ import (
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
- fmt.Println("Version is:", version.Version)
|
|
||||||
+ logrus.Infoln("Version is:", version.Version)
|
|
||||||
l, err := server.NewListener(server.SockDir, server.SockName)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Errorln("listen error" + err.Error())
|
|
||||||
diff --git a/cmd/agent/server/docker_image.go b/cmd/agent/server/docker_image.go
|
|
||||||
index 0b6ee35..16bcea5 100644
|
|
||||||
--- a/cmd/agent/server/docker_image.go
|
|
||||||
+++ b/cmd/agent/server/docker_image.go
|
|
||||||
@@ -61,13 +61,13 @@ func (d dockerImageHandler) getRootfsArchive(req *pb.UpdateRequest, neededPath p
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
- if err := runCommand("docker", "cp", containerId+":/"+neededPath.rootfsFile, neededPath.updatePath); err != nil {
|
|
||||||
- return "", err
|
|
||||||
- }
|
|
||||||
defer func() {
|
|
||||||
if err := runCommand("docker", "rm", containerId); err != nil {
|
|
||||||
logrus.Errorln("remove kubeos-temp container error", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
+ if err := runCommand("docker", "cp", containerId+":/"+neededPath.rootfsFile, neededPath.updatePath); err != nil {
|
|
||||||
+ return "", err
|
|
||||||
+ }
|
|
||||||
return neededPath.tarPath, nil
|
|
||||||
}
|
|
||||||
diff --git a/cmd/agent/server/server.go b/cmd/agent/server/server.go
|
|
||||||
index 8ac6ffd..f8cbb41 100644
|
|
||||||
--- a/cmd/agent/server/server.go
|
|
||||||
+++ b/cmd/agent/server/server.go
|
|
||||||
@@ -112,6 +112,15 @@ func (s *Server) update(req *pb.UpdateRequest) error {
|
|
||||||
return fmt.Errorf("image type %s cannot be recognized", action)
|
|
||||||
}
|
|
||||||
imagePath, err := handler.downloadImage(req)
|
|
||||||
+ defer func() {
|
|
||||||
+ if err != nil {
|
|
||||||
+ path := newPreparePath()
|
|
||||||
+ if err := cleanSpace(path.updatePath, path.mountPath, path.imagePath); err != nil {
|
|
||||||
+ logrus.Errorln("clean space error " + err.Error())
|
|
||||||
+ }
|
|
||||||
+ logrus.Infoln("clean space success")
|
|
||||||
+ }
|
|
||||||
+ }()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
diff --git a/cmd/agent/server/utils.go b/cmd/agent/server/utils.go
|
|
||||||
index b42db18..d2d0946 100644
|
|
||||||
--- a/cmd/agent/server/utils.go
|
|
||||||
+++ b/cmd/agent/server/utils.go
|
|
||||||
@@ -190,26 +190,25 @@ func prepareEnv() (preparePath, error) {
|
|
||||||
if err := checkDiskSize(needGBSize, PersistDir); err != nil {
|
|
||||||
return preparePath{}, err
|
|
||||||
}
|
|
||||||
- rootfsFile := rootfsArchive
|
|
||||||
- updatePath := splicePath(PersistDir, updateDir)
|
|
||||||
- mountPath := splicePath(updatePath, mountDir)
|
|
||||||
- tarPath := splicePath(updatePath, rootfsFile)
|
|
||||||
- imagePath := splicePath(PersistDir, osImageName)
|
|
||||||
-
|
|
||||||
- if err := cleanSpace(updatePath, mountPath, imagePath); err != nil {
|
|
||||||
+ upgradePath := newPreparePath()
|
|
||||||
+ if err := cleanSpace(upgradePath.updatePath, upgradePath.mountPath, upgradePath.imagePath); err != nil {
|
|
||||||
return preparePath{}, err
|
|
||||||
}
|
|
||||||
- if err := os.MkdirAll(mountPath, imgPermission); err != nil {
|
|
||||||
+ if err := os.MkdirAll(upgradePath.mountPath, imgPermission); err != nil {
|
|
||||||
return preparePath{}, err
|
|
||||||
}
|
|
||||||
- upgradePath := preparePath{
|
|
||||||
+ return upgradePath, nil
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+func newPreparePath() preparePath {
|
|
||||||
+ updatePath := splicePath(PersistDir, updateDir)
|
|
||||||
+ return preparePath{
|
|
||||||
updatePath: updatePath,
|
|
||||||
- mountPath: mountPath,
|
|
||||||
- tarPath: tarPath,
|
|
||||||
- imagePath: imagePath,
|
|
||||||
- rootfsFile: rootfsFile,
|
|
||||||
+ mountPath: splicePath(updatePath, mountDir),
|
|
||||||
+ tarPath: splicePath(updatePath, rootfsArchive),
|
|
||||||
+ imagePath: splicePath(PersistDir, osImageName),
|
|
||||||
+ rootfsFile: rootfsArchive,
|
|
||||||
}
|
|
||||||
- return upgradePath, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkDiskSize(needGBSize int, path string) error {
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
From 9f0f03251a1bd0449f4e7e7ab5699e4771fbaa56 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Fri, 18 Aug 2023 17:19:53 +0800
|
|
||||||
Subject: [PATCH 15/17] KubeOS: update version
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
VERSION | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/VERSION b/VERSION
|
|
||||||
index 7dea76e..ee90284 100644
|
|
||||||
--- a/VERSION
|
|
||||||
+++ b/VERSION
|
|
||||||
@@ -1 +1 @@
|
|
||||||
-1.0.1
|
|
||||||
+1.0.4
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
From 235a13b34e65b8d4ec4bde59e36247445b0778e8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Tue, 15 Aug 2023 16:24:25 +0800
|
|
||||||
Subject: [PATCH] KubeOS: add line breaks
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
scripts/admin-container/set-ssh-pub-key.service | 2 +-
|
|
||||||
scripts/admin-container/set-ssh-pub-key.sh | 2 +-
|
|
||||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/scripts/admin-container/set-ssh-pub-key.service b/scripts/admin-container/set-ssh-pub-key.service
|
|
||||||
index cf21406..84dd12d 100644
|
|
||||||
--- a/scripts/admin-container/set-ssh-pub-key.service
|
|
||||||
+++ b/scripts/admin-container/set-ssh-pub-key.service
|
|
||||||
@@ -12,4 +12,4 @@
|
|
||||||
Description="set ssh authorized keys according to the secret which is set by user"
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
-ExecStart="/usr/local/bin/set-ssh-pub-key.sh"
|
|
||||||
\ No newline at end of file
|
|
||||||
+ExecStart="/usr/local/bin/set-ssh-pub-key.sh"
|
|
||||||
diff --git a/scripts/admin-container/set-ssh-pub-key.sh b/scripts/admin-container/set-ssh-pub-key.sh
|
|
||||||
index aa706c2..e91a15d 100755
|
|
||||||
--- a/scripts/admin-container/set-ssh-pub-key.sh
|
|
||||||
+++ b/scripts/admin-container/set-ssh-pub-key.sh
|
|
||||||
@@ -23,4 +23,4 @@ if [ ! -f "$authorized_file" ]; then
|
|
||||||
chmod 600 "$authorized_file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
-echo "$ssh_pub" >> "$authorized_file"
|
|
||||||
\ No newline at end of file
|
|
||||||
+echo "$ssh_pub" >> "$authorized_file"
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
From a01e5ebfd9c314b840eb3a652cda71e33954a403 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Wed, 16 Aug 2023 22:41:44 +0800
|
|
||||||
Subject: [PATCH 16/17] KubeOS: modify code for clean code
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/agent/server/config.go | 4 ++++
|
|
||||||
cmd/operator/controllers/os_controller.go | 6 +++++-
|
|
||||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/agent/server/config.go b/cmd/agent/server/config.go
|
|
||||||
index 20af267..a96370d 100644
|
|
||||||
--- a/cmd/agent/server/config.go
|
|
||||||
+++ b/cmd/agent/server/config.go
|
|
||||||
@@ -317,6 +317,10 @@ func createConfigPath(configPath string) error {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
+ err = f.Chmod(defaultKernelConPermission)
|
|
||||||
+ if err != nil {
|
|
||||||
+ return err
|
|
||||||
+ }
|
|
||||||
f.Close()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
diff --git a/cmd/operator/controllers/os_controller.go b/cmd/operator/controllers/os_controller.go
|
|
||||||
index 620739b..e152681 100644
|
|
||||||
--- a/cmd/operator/controllers/os_controller.go
|
|
||||||
+++ b/cmd/operator/controllers/os_controller.go
|
|
||||||
@@ -94,7 +94,11 @@ func Reconcile(ctx context.Context, r common.ReadStatusWriter, req ctrl.Request)
|
|
||||||
func (r *OSReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
|
||||||
if err := mgr.GetFieldIndexer().IndexField(context.Background(), &upgradev1.OSInstance{}, values.OsiStatusName,
|
|
||||||
func(rawObj client.Object) []string {
|
|
||||||
- osi := rawObj.(*upgradev1.OSInstance)
|
|
||||||
+ osi, ok := rawObj.(*upgradev1.OSInstance)
|
|
||||||
+ if !ok {
|
|
||||||
+ log.Error(nil, "failed to convert to osInstance")
|
|
||||||
+ return []string{}
|
|
||||||
+ }
|
|
||||||
return []string{osi.Spec.NodeStatus}
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,176 +0,0 @@
|
|||||||
From 0c0f3c7ef5749b8806511d9e3312f6cacd4cca04 Mon Sep 17 00:00:00 2001
|
|
||||||
From: liyuanr <liyuanrong1@huawei.com>
|
|
||||||
Date: Tue, 15 Aug 2023 12:29:11 +0000
|
|
||||||
Subject: [PATCH 17/17] KubeOS: fix the issue that osinstance is not updated in
|
|
||||||
time during proxy upgrade.
|
|
||||||
|
|
||||||
Fix the problem that osinstance is not updated in time during proxy upgrade,
|
|
||||||
but the node upgrade tag has been added. As a result, the configuration is skipped
|
|
||||||
and the upgrade is directly performed.
|
|
||||||
|
|
||||||
Signed-off-by: liyuanr <liyuanrong1@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/proxy/controllers/os_controller.go | 11 ++
|
|
||||||
cmd/proxy/controllers/os_controller_test.go | 126 ++++++++++++++++++++
|
|
||||||
2 files changed, 137 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/cmd/proxy/controllers/os_controller.go b/cmd/proxy/controllers/os_controller.go
|
|
||||||
index 30f9839..b8d0f80 100644
|
|
||||||
--- a/cmd/proxy/controllers/os_controller.go
|
|
||||||
+++ b/cmd/proxy/controllers/os_controller.go
|
|
||||||
@@ -126,6 +126,17 @@ func (r *OSReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Re
|
|
||||||
}
|
|
||||||
return values.Requeue, nil
|
|
||||||
}
|
|
||||||
+ if _, ok := node.Labels[values.LabelUpgrading]; ok &&
|
|
||||||
+ osInstance.Spec.NodeStatus == values.NodeStatusIdle.String() {
|
|
||||||
+ log.Info("node has upgrade label, but osInstance.spec.nodestaus idle ",
|
|
||||||
+ "operation:", "refesh node and wait opetaot reassgin")
|
|
||||||
+ if err = r.refreshNode(ctx, &node, osInstance, osCr.Spec.UpgradeConfigs.Version,
|
|
||||||
+ values.UpgradeConfigName); err != nil {
|
|
||||||
+ return values.RequeueNow, err
|
|
||||||
+ }
|
|
||||||
+ return values.Requeue, nil
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if err := r.setConfig(ctx, osInstance, values.UpgradeConfigName); err != nil {
|
|
||||||
return values.RequeueNow, err
|
|
||||||
}
|
|
||||||
diff --git a/cmd/proxy/controllers/os_controller_test.go b/cmd/proxy/controllers/os_controller_test.go
|
|
||||||
index d63f176..27cb0cd 100644
|
|
||||||
--- a/cmd/proxy/controllers/os_controller_test.go
|
|
||||||
+++ b/cmd/proxy/controllers/os_controller_test.go
|
|
||||||
@@ -1098,4 +1098,130 @@ var _ = Describe("OsController", func() {
|
|
||||||
Expect(ok).Should(Equal(false))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
+
|
|
||||||
+ Context("When node has upgrade label but osinstance.spec.nodestatus is idle", func() {
|
|
||||||
+ It("Should be able to refresh node and wait operator reassgin upgrade", func() {
|
|
||||||
+ ctx := context.Background()
|
|
||||||
+ By("Creating a worker node")
|
|
||||||
+ node1Name = "test-node-" + uuid.New().String()
|
|
||||||
+ node1 := &v1.Node{
|
|
||||||
+ ObjectMeta: metav1.ObjectMeta{
|
|
||||||
+ Name: node1Name,
|
|
||||||
+ Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ "beta.kubernetes.io/os": "linux",
|
|
||||||
+ values.LabelUpgrading: "",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ TypeMeta: metav1.TypeMeta{
|
|
||||||
+ APIVersion: "v1",
|
|
||||||
+ Kind: "Node",
|
|
||||||
+ },
|
|
||||||
+ Status: v1.NodeStatus{
|
|
||||||
+ NodeInfo: v1.NodeSystemInfo{
|
|
||||||
+ OSImage: "KubeOS v2",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ err := k8sClient.Create(ctx, node1)
|
|
||||||
+ Expect(err).ToNot(HaveOccurred())
|
|
||||||
+ existingNode := &v1.Node{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(context.Background(),
|
|
||||||
+ types.NamespacedName{Name: node1Name, Namespace: testNamespace}, existingNode)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ reconciler.hostName = node1Name
|
|
||||||
+
|
|
||||||
+ By("Creating the corresponding OSInstance")
|
|
||||||
+ OSIns := &upgradev1.OSInstance{
|
|
||||||
+ TypeMeta: metav1.TypeMeta{
|
|
||||||
+ Kind: "OSInstance",
|
|
||||||
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
|
|
||||||
+ },
|
|
||||||
+ ObjectMeta: metav1.ObjectMeta{
|
|
||||||
+ Name: node1Name,
|
|
||||||
+ Namespace: testNamespace,
|
|
||||||
+ Labels: map[string]string{
|
|
||||||
+ values.LabelOSinstance: node1Name,
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ Spec: upgradev1.OSInstanceSpec{
|
|
||||||
+ NodeStatus: values.NodeStatusIdle.String(),
|
|
||||||
+ },
|
|
||||||
+ Status: upgradev1.OSInstanceStatus{},
|
|
||||||
+ }
|
|
||||||
+ Expect(k8sClient.Create(ctx, OSIns)).Should(Succeed())
|
|
||||||
+
|
|
||||||
+ // Check that the corresponding OSIns CR has been created
|
|
||||||
+ osInsCRLookupKey := types.NamespacedName{Name: node1Name, Namespace: testNamespace}
|
|
||||||
+ createdOSIns := &upgradev1.OSInstance{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(ctx, osInsCRLookupKey, createdOSIns)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ Expect(createdOSIns.ObjectMeta.Name).Should(Equal(node1Name))
|
|
||||||
+ By("Creating a OS custom resource")
|
|
||||||
+ OS := &upgradev1.OS{
|
|
||||||
+ TypeMeta: metav1.TypeMeta{
|
|
||||||
+ APIVersion: "upgrade.openeuler.org/v1alpha1",
|
|
||||||
+ Kind: "OS",
|
|
||||||
+ },
|
|
||||||
+ ObjectMeta: metav1.ObjectMeta{
|
|
||||||
+ Name: OSName,
|
|
||||||
+ Namespace: testNamespace,
|
|
||||||
+ },
|
|
||||||
+ Spec: upgradev1.OSSpec{
|
|
||||||
+ OpsType: "upgrade",
|
|
||||||
+ MaxUnavailable: 3,
|
|
||||||
+ OSVersion: "KubeOS v2",
|
|
||||||
+ FlagSafe: true,
|
|
||||||
+ MTLS: false,
|
|
||||||
+ EvictPodForce: true,
|
|
||||||
+ SysConfigs: upgradev1.SysConfigs{
|
|
||||||
+ Version: "v2",
|
|
||||||
+ Configs: []upgradev1.SysConfig{
|
|
||||||
+ {
|
|
||||||
+ Model: "kernel.sysctl",
|
|
||||||
+ Contents: []upgradev1.Content{
|
|
||||||
+ {Key: "key1", Value: "c"},
|
|
||||||
+ {Key: "key2", Value: "d"},
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ UpgradeConfigs: upgradev1.SysConfigs{
|
|
||||||
+ Version: "v2",
|
|
||||||
+ Configs: []upgradev1.SysConfig{
|
|
||||||
+ {
|
|
||||||
+ Model: "kernel.sysctl",
|
|
||||||
+ Contents: []upgradev1.Content{
|
|
||||||
+ {Key: "key1", Value: "a"},
|
|
||||||
+ {Key: "key2", Value: "b"},
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ }
|
|
||||||
+ Expect(k8sClient.Create(ctx, OS)).Should(Succeed())
|
|
||||||
+ osCRLookupKey := types.NamespacedName{Name: OSName, Namespace: testNamespace}
|
|
||||||
+ createdOS := &upgradev1.OS{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(ctx, osCRLookupKey, createdOS)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ Expect(createdOS.Spec.OSVersion).Should(Equal("KubeOS v2"))
|
|
||||||
+
|
|
||||||
+ time.Sleep(2 * time.Second) // sleep a while to make sure Reconcile finished
|
|
||||||
+ existingNode = &v1.Node{}
|
|
||||||
+ Eventually(func() bool {
|
|
||||||
+ err := k8sClient.Get(context.Background(),
|
|
||||||
+ types.NamespacedName{Name: node1Name, Namespace: testNamespace}, existingNode)
|
|
||||||
+ return err == nil
|
|
||||||
+ }, timeout, interval).Should(BeTrue())
|
|
||||||
+ _, ok := existingNode.Labels[values.LabelUpgrading]
|
|
||||||
+ Expect(ok).Should(Equal(false))
|
|
||||||
+ })
|
|
||||||
+ })
|
|
||||||
})
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From 662f68aa131c09154bb91085e4657beaee00d1d6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Mon, 21 Aug 2023 09:58:45 +0800
|
|
||||||
Subject: [PATCH 1/5] KubeOS: update config log contents
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/agent/server/config.go | 8 ++++++--
|
|
||||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/agent/server/config.go b/cmd/agent/server/config.go
|
|
||||||
index a96370d..f186ee6 100644
|
|
||||||
--- a/cmd/agent/server/config.go
|
|
||||||
+++ b/cmd/agent/server/config.go
|
|
||||||
@@ -57,7 +57,7 @@ func (k KernelSysctl) SetConfig(config *agent.SysConfig) error {
|
|
||||||
}
|
|
||||||
logrus.Infof("Configured kernel.sysctl %s=%s", key, keyInfo.Value)
|
|
||||||
} else {
|
|
||||||
- logrus.Warnf("Failed to parse kernel.sysctl key: %s value: %s operation: %s", key, keyInfo.Value, keyInfo.Operation)
|
|
||||||
+ logrus.Warnf("Failed to parse kernel.sysctl, key: %s, value: %s, operation: %s", key, keyInfo.Value, keyInfo.Operation)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
@@ -97,7 +97,11 @@ type GrubCmdline struct {
|
|
||||||
|
|
||||||
// SetConfig sets grub.cmdline configuration
|
|
||||||
func (g GrubCmdline) SetConfig(config *agent.SysConfig) error {
|
|
||||||
- logrus.Info("start set grub.cmdline configuration")
|
|
||||||
+ if g.isCurPartition {
|
|
||||||
+ logrus.Info("start set grub.cmdline.current configuration")
|
|
||||||
+ } else {
|
|
||||||
+ logrus.Info("start set grub.cmdline.next configuration")
|
|
||||||
+ }
|
|
||||||
fileExist, err := checkFileExist(getGrubCfgPath())
|
|
||||||
if err != nil {
|
|
||||||
logrus.Errorf("Failed to find config path: %v", err)
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,86 +0,0 @@
|
|||||||
From a9220ad3175c38979a052cd595efd34888d886c6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Thu, 24 Aug 2023 11:00:04 +0800
|
|
||||||
Subject: [PATCH 3/5] KubeOS: modify code for clean code
|
|
||||||
|
|
||||||
add err handler in NewControllerManager
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/operator/main.go | 6 +++++-
|
|
||||||
cmd/proxy/main.go | 8 ++++++--
|
|
||||||
pkg/common/common.go | 7 +++----
|
|
||||||
3 files changed, 14 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/operator/main.go b/cmd/operator/main.go
|
|
||||||
index 17b74e1..8249ad2 100644
|
|
||||||
--- a/cmd/operator/main.go
|
|
||||||
+++ b/cmd/operator/main.go
|
|
||||||
@@ -41,7 +41,11 @@ func init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
- mgr := common.NewControllerManager(setupLog, scheme)
|
|
||||||
+ mgr, err := common.NewControllerManager(setupLog, scheme)
|
|
||||||
+ if err != nil {
|
|
||||||
+ setupLog.Error(err, "unable to start manager")
|
|
||||||
+ os.Exit(1)
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if err := (&controllers.OSReconciler{
|
|
||||||
Client: mgr.GetClient(),
|
|
||||||
diff --git a/cmd/proxy/main.go b/cmd/proxy/main.go
|
|
||||||
index ce1f58d..3a537d9 100644
|
|
||||||
--- a/cmd/proxy/main.go
|
|
||||||
+++ b/cmd/proxy/main.go
|
|
||||||
@@ -44,10 +44,14 @@ func init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
- mgr := common.NewControllerManager(setupLog, scheme)
|
|
||||||
+ var err error
|
|
||||||
+ mgr, err := common.NewControllerManager(setupLog, scheme)
|
|
||||||
+ if err != nil {
|
|
||||||
+ setupLog.Error(err, "unable to start manager")
|
|
||||||
+ os.Exit(1)
|
|
||||||
+ }
|
|
||||||
|
|
||||||
reconciler := controllers.NewOSReconciler(mgr)
|
|
||||||
- var err error
|
|
||||||
if reconciler.Connection, err = agentclient.New("unix://" + filepath.Join(server.SockDir, server.SockName)); err != nil {
|
|
||||||
setupLog.Error(err, "Error running proxy")
|
|
||||||
}
|
|
||||||
diff --git a/pkg/common/common.go b/pkg/common/common.go
|
|
||||||
index 4653a61..e888179 100644
|
|
||||||
--- a/pkg/common/common.go
|
|
||||||
+++ b/pkg/common/common.go
|
|
||||||
@@ -15,7 +15,6 @@ package common
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
- "os"
|
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
@@ -33,7 +32,7 @@ type ReadStatusWriter interface {
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewControllerManager configure and return a manager
|
|
||||||
-func NewControllerManager(setupLog logr.Logger, scheme *runtime.Scheme) manager.Manager {
|
|
||||||
+func NewControllerManager(setupLog logr.Logger, scheme *runtime.Scheme) (manager.Manager, error) {
|
|
||||||
opts := zap.Options{}
|
|
||||||
opts.BindFlags(flag.CommandLine)
|
|
||||||
|
|
||||||
@@ -46,7 +45,7 @@ func NewControllerManager(setupLog logr.Logger, scheme *runtime.Scheme) manager.
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
setupLog.Error(err, "unable to start manager")
|
|
||||||
- os.Exit(1)
|
|
||||||
+ return nil, err
|
|
||||||
}
|
|
||||||
- return mgr
|
|
||||||
+ return mgr, nil
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.39.0
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,28 +0,0 @@
|
|||||||
From 9a92903712509e32b9ea84f97e35c50b2152389d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Tue, 5 Sep 2023 12:38:18 +0800
|
|
||||||
Subject: [PATCH 1/3] KubeOS: fix proxy upgrade requeue bug
|
|
||||||
|
|
||||||
fix the bug that proxy doesnt forget ratelimit after updating config
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/proxy/controllers/os_controller.go | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/cmd/proxy/controllers/os_controller.go b/cmd/proxy/controllers/os_controller.go
|
|
||||||
index d7da343..1153419 100644
|
|
||||||
--- a/cmd/proxy/controllers/os_controller.go
|
|
||||||
+++ b/cmd/proxy/controllers/os_controller.go
|
|
||||||
@@ -101,7 +101,7 @@ func (r *OSReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Re
|
|
||||||
if err = r.Update(ctx, osInstance); err != nil {
|
|
||||||
return values.RequeueNow, err
|
|
||||||
}
|
|
||||||
- return values.RequeueNow, nil
|
|
||||||
+ return values.Requeue, nil
|
|
||||||
}
|
|
||||||
if err := r.setConfig(ctx, osInstance, values.SysConfigName); err != nil {
|
|
||||||
return values.RequeueNow, err
|
|
||||||
--
|
|
||||||
2.34.1
|
|
||||||
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
From 5fce81aeda6498425772d3af2bfa858ba8923140 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
Date: Tue, 5 Sep 2023 17:01:41 +0800
|
|
||||||
Subject: [PATCH 2/3] KubeOS: fix label changed after upgrade
|
|
||||||
|
|
||||||
When upgrading, the label of the new root partition are changed to the original disk information
|
|
||||||
|
|
||||||
Signed-off-by: Yuhang Wei <weiyuhang3@huawei.com>
|
|
||||||
---
|
|
||||||
cmd/agent/server/utils.go | 10 ++++++++++
|
|
||||||
1 file changed, 10 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/cmd/agent/server/utils.go b/cmd/agent/server/utils.go
|
|
||||||
index d2d0946..b4a19ff 100644
|
|
||||||
--- a/cmd/agent/server/utils.go
|
|
||||||
+++ b/cmd/agent/server/utils.go
|
|
||||||
@@ -75,6 +75,9 @@ func deleteNewline(out string) string {
|
|
||||||
}
|
|
||||||
|
|
||||||
func install(imagePath string, side string, next string) error {
|
|
||||||
+ if err := modifyImageLabel(imagePath, side, next); err != nil {
|
|
||||||
+ return err
|
|
||||||
+ }
|
|
||||||
if err := runCommand("dd", "if="+imagePath, "of="+side, "bs=8M"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@@ -370,3 +373,10 @@ func getOCIImageDigest(containerRuntime string, imageName string) (string, error
|
|
||||||
}
|
|
||||||
return imageDigests, nil
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+func modifyImageLabel(imagePath, side, next string) error {
|
|
||||||
+ if err := runCommand("e2label", imagePath, "ROOT-"+next); err != nil {
|
|
||||||
+ return err
|
|
||||||
+ }
|
|
||||||
+ return nil
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.34.1
|
|
||||||
|
|
||||||
165
KubeOS.spec
165
KubeOS.spec
@ -1,39 +1,17 @@
|
|||||||
# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
|
# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
|
||||||
|
|
||||||
Name: KubeOS
|
Name: KubeOS
|
||||||
Version: 1.0.4
|
Version: 1.0.5
|
||||||
Release: 4
|
Release: 1
|
||||||
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-add-unit-tests-of-containerd-and-docker-modif.patch
|
Patch1: 0001-build-rust-os-agent-remove-useless-dependency.patch
|
||||||
Patch2: 0002-KubeOS-refactor-assignUpgrade-function.patch
|
|
||||||
Patch3: 0003-KubeOS-fix-the-hostshell-cannot-obtain-the-lib.patch
|
|
||||||
Patch4: 0004-KubeOS-add-agent-proxy-and-operator-ut.patch
|
|
||||||
Patch5: 0005-KubeOS-fix-validate-image-name-bug.patch
|
|
||||||
Patch6: 0006-KubeOS-fix-a-bug-that-failed-to-parse-key-with.patch
|
|
||||||
Patch7: 0007-KubeOS-add-warning-log-during-config.patch
|
|
||||||
Patch8: 0008-KubeOS-modify-log-level-and-content.patch
|
|
||||||
Patch9: 0009-KubeOS-fix-updating-key-to-kv.patch
|
|
||||||
Patch10: 0010-KubeOS-fix-proxy-requeue-bug.patch
|
|
||||||
Patch11: 0011-KubeOS-fix-operator-bug-of-missing-deep-copy.patch
|
|
||||||
Patch12: 0012-KubeOS-add-unit-test.patch
|
|
||||||
Patch13: 0013-KubeOS-fix-clean-space-problems.patch
|
|
||||||
Patch14: 0014-KubeOS-update-version.patch
|
|
||||||
Patch15: 0015-KubeOS-add-line-breaks.patch
|
|
||||||
Patch16: 0016-KubeOS-modify-code-for-clean-code.patch
|
|
||||||
Patch17: 0017-KubeOS-fix-the-issue-that-osinstance-is-not-updated-.patch
|
|
||||||
Patch18: 0018-KubeOS-update-config-log-contents.patch
|
|
||||||
Patch19: 0019-KubeOS-add-unit-tests.patch
|
|
||||||
Patch20: 0020-KubeOS-modify-code-for-clean-code.patch
|
|
||||||
Patch21: 0021-KubeOS-delete-raw-and-docker-image-upgrade.patch
|
|
||||||
Patch22: 0022-KubeOS-delete-scripts-except-admin-container.patch
|
|
||||||
Patch23: 0023-KubeOS-fix-proxy-upgrade-requeue-bug.patch
|
|
||||||
Patch24: 0024-KubeOS-fix-label-changed-after-upgrade.patch
|
|
||||||
|
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
BuildRequires: make
|
BuildRequires: make rust cargo openssl-devel
|
||||||
BuildRequires: golang >= 1.13
|
BuildRequires: golang >= 1.13
|
||||||
|
|
||||||
%description
|
%description
|
||||||
This is an O&M platform used to update the whole OS as an entirety,
|
This is an O&M platform used to update the whole OS as an entirety,
|
||||||
it should be running in kubernetes environment.
|
it should be running in kubernetes environment.
|
||||||
@ -41,15 +19,11 @@ it should be running in kubernetes environment.
|
|||||||
%prep
|
%prep
|
||||||
%autosetup -n %{name}-v%{version} -p1
|
%autosetup -n %{name}-v%{version} -p1
|
||||||
|
|
||||||
%package agent
|
%package scripts
|
||||||
Summary: agent provides os-agent and related service files which are needed on nodes
|
Summary: Scripts to build the os image and binaries of os-proxy and os-operator
|
||||||
%description agent
|
Requires: qemu-img, parted, bc, tar, docker, dosfstools
|
||||||
The agent package includes os-agent and service files
|
%description scripts
|
||||||
|
The scripts package includes scripts which could build the os image and binaries of os-proxy and os-operator
|
||||||
%package admin-container
|
|
||||||
Summary: admin-container contains hostshell and set-ssh-pub-key script and service file
|
|
||||||
%description admin-container
|
|
||||||
The agent package includes hostshell and set-ssh-pub-key script and service file
|
|
||||||
|
|
||||||
%define debug_package %{nil}
|
%define debug_package %{nil}
|
||||||
%define __debug_install_post \
|
%define __debug_install_post \
|
||||||
@ -57,55 +31,110 @@ The agent package includes hostshell and set-ssh-pub-key script and service file
|
|||||||
%{nil}
|
%{nil}
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
mkdir ./KubeOS-Rust/.cargo
|
||||||
|
cat << EOF >> ./KubeOS-Rust/.cargo/config
|
||||||
|
|
||||||
|
[source.crates-io]
|
||||||
|
replace-with = "vendored-sources"
|
||||||
|
|
||||||
|
[source.vendored-sources]
|
||||||
|
directory = "vendor"
|
||||||
|
EOF
|
||||||
|
|
||||||
make
|
make
|
||||||
|
|
||||||
%install
|
%install
|
||||||
install -d -m 0740 %{buildroot}/opt/kubeOS/bin
|
|
||||||
install -p -m 0500 ./bin/proxy %{buildroot}/opt/kubeOS/bin
|
|
||||||
install -p -m 0500 ./bin/operator %{buildroot}/opt/kubeOS/bin
|
|
||||||
|
|
||||||
#kubeos-agent
|
|
||||||
install -d %{buildroot}%{_bindir}
|
install -d %{buildroot}%{_bindir}
|
||||||
install -d %{buildroot}%{_prefix}/lib/systemd/system
|
#install binary
|
||||||
install -p -m 0500 ./bin/os-agent %{buildroot}%{_bindir}
|
install -d -m 0740 %{buildroot}/opt/kubeOS/bin
|
||||||
install -p -m 0600 ./files/boot-efi.mount %{buildroot}%{_prefix}/lib/systemd/system
|
install -p -m 0500 ./bin/rust/release/os-agent %{buildroot}/opt/kubeOS/bin
|
||||||
install -p -m 0600 ./files/etc.mount %{buildroot}%{_prefix}/lib/systemd/system
|
install -p -m 0500 ./bin/rust/release/proxy %{buildroot}/opt/kubeOS/bin
|
||||||
install -p -m 0600 ./files/persist.mount %{buildroot}%{_prefix}/lib/systemd/system
|
install -p -m 0500 ./bin/operator %{buildroot}/opt/kubeOS/bin
|
||||||
install -p -m 0600 ./files/var.mount %{buildroot}%{_prefix}/lib/systemd/system
|
install -p -m 0500 ./bin/hostshell %{buildroot}/opt/kubeOS/bin
|
||||||
install -p -m 0600 ./files/os-agent.service %{buildroot}%{_prefix}/lib/systemd/system
|
|
||||||
install -p -m 0600 ./files/os-release %{buildroot}%{_prefix}/lib/
|
|
||||||
|
|
||||||
#kubeos-admin-container
|
#install artifacts
|
||||||
install -p -m 0500 ./bin/hostshell %{buildroot}%{_bindir}
|
install -d -m 0740 %{buildroot}/opt/kubeOS/scripts
|
||||||
install -d %{buildroot}%{_prefix}/local/bin
|
install -p -m 0600 ./scripts/rpmlist %{buildroot}/opt/kubeOS/scripts
|
||||||
install -p -m 0500 ./scripts/admin-container/set-ssh-pub-key.sh %{buildroot}%{_prefix}/local/bin
|
install -p -m 0500 ./scripts/kbimg.sh %{buildroot}/opt/kubeOS/scripts
|
||||||
install -d %{buildroot}%{_prefix}/lib/sysmaster
|
install -p -m 0500 ./scripts/set_in_chroot.sh %{buildroot}/opt/kubeOS/scripts
|
||||||
install -p -m 0600 ./scripts/admin-container/set-ssh-pub-key.service %{buildroot}%{_prefix}/lib/sysmaster
|
install -p -m 0600 ./scripts/grub.cfg %{buildroot}/opt/kubeOS/scripts
|
||||||
|
install -p -m 0500 ./scripts/bootloader.sh %{buildroot}/opt/kubeOS/scripts
|
||||||
|
install -p -m 0500 ./scripts/Dockerfile %{buildroot}/opt/kubeOS/scripts
|
||||||
|
|
||||||
|
install -d -m 0740 %{buildroot}/opt/kubeOS/scripts/common
|
||||||
|
install -p -m 0500 ./scripts/common/globalVariables.sh %{buildroot}/opt/kubeOS/scripts/common
|
||||||
|
install -p -m 0500 ./scripts/common/log.sh %{buildroot}/opt/kubeOS/scripts/common
|
||||||
|
install -p -m 0500 ./scripts/common/utils.sh %{buildroot}/opt/kubeOS/scripts/common
|
||||||
|
|
||||||
|
install -d -m 0740 %{buildroot}/opt/kubeOS/scripts/create
|
||||||
|
install -p -m 0500 ./scripts/create/imageCreate.sh %{buildroot}/opt/kubeOS/scripts/create
|
||||||
|
install -p -m 0500 ./scripts/create/rootfsCreate.sh %{buildroot}/opt/kubeOS/scripts/create
|
||||||
|
|
||||||
|
install -d -m 0740 %{buildroot}/opt/kubeOS/scripts/00bootup
|
||||||
|
install -p -m 0600 ./scripts/00bootup/Global.cfg %{buildroot}/opt/kubeOS/scripts/00bootup
|
||||||
|
install -p -m 0500 ./scripts/00bootup/module-setup.sh %{buildroot}/opt/kubeOS/scripts/00bootup
|
||||||
|
install -p -m 0500 ./scripts/00bootup/mount.sh %{buildroot}/opt/kubeOS/scripts/00bootup
|
||||||
|
|
||||||
|
install -d -m 0740 %{buildroot}/opt/kubeOS/scripts/admin-container
|
||||||
|
install -p -m 0500 ./scripts/admin-container/set-ssh-pub-key.sh %{buildroot}/opt/kubeOS/scripts/admin-container
|
||||||
|
install -p -m 0600 ./scripts/admin-container/set-ssh-pub-key.service %{buildroot}/opt/kubeOS/scripts/admin-container
|
||||||
|
install -p -m 0500 ./scripts/admin-container/Dockerfile %{buildroot}/opt/kubeOS/scripts/admin-container
|
||||||
|
|
||||||
|
install -d -m 0740 %{buildroot}/opt/kubeOS/files
|
||||||
|
install -p -m 0600 ./files/boot-efi.mount %{buildroot}/opt/kubeOS/files
|
||||||
|
install -p -m 0600 ./files/etc.mount %{buildroot}/opt/kubeOS/files
|
||||||
|
install -p -m 0600 ./files/persist.mount %{buildroot}/opt/kubeOS/files
|
||||||
|
install -p -m 0600 ./files/var.mount %{buildroot}/opt/kubeOS/files
|
||||||
|
install -p -m 0600 ./files/os-agent.service %{buildroot}/opt/kubeOS/files
|
||||||
|
install -p -m 0600 ./files/os-release %{buildroot}/opt/kubeOS/files
|
||||||
|
|
||||||
%files
|
%files
|
||||||
|
%defattr(-,root,root,0500)
|
||||||
|
%attr(0500,root,root) /opt/kubeOS/bin/os-agent
|
||||||
|
%attr(0500,root,root) /opt/kubeOS/bin/hostshell
|
||||||
%attr(0500,root,root) /opt/kubeOS/bin/proxy
|
%attr(0500,root,root) /opt/kubeOS/bin/proxy
|
||||||
%attr(0500,root,root) /opt/kubeOS/bin/operator
|
%attr(0500,root,root) /opt/kubeOS/bin/operator
|
||||||
|
%attr(0600,root,root) /opt/kubeOS/files/boot-efi.mount
|
||||||
|
%attr(0600,root,root) /opt/kubeOS/files/etc.mount
|
||||||
|
%attr(0600,root,root) /opt/kubeOS/files/persist.mount
|
||||||
|
%attr(0600,root,root) /opt/kubeOS/files/var.mount
|
||||||
|
%attr(0600,root,root) /opt/kubeOS/files/os-agent.service
|
||||||
|
%attr(0600,root,root) /opt/kubeOS/files/os-release
|
||||||
|
|
||||||
%files agent
|
%files scripts
|
||||||
%attr(0500,root,root) %{_bindir}/os-agent
|
|
||||||
%defattr(-,root,root,0500)
|
%defattr(-,root,root,0500)
|
||||||
%attr(0600,root,root) %{_prefix}/lib/systemd/system/boot-efi.mount
|
%attr(0600,root,root) /opt/kubeOS/scripts/rpmlist
|
||||||
%attr(0600,root,root) %{_prefix}/lib/systemd/system/etc.mount
|
%attr(0500,root,root) /opt/kubeOS/scripts/kbimg.sh
|
||||||
%attr(0600,root,root) %{_prefix}/lib/systemd/system/persist.mount
|
%attr(0500,root,root) /opt/kubeOS/scripts/set_in_chroot.sh
|
||||||
%attr(0600,root,root) %{_prefix}/lib/systemd/system/var.mount
|
%attr(0600,root,root) /opt/kubeOS/scripts/grub.cfg
|
||||||
%attr(0600,root,root) %{_prefix}/lib/systemd/system/os-agent.service
|
%attr(0500,root,root) /opt/kubeOS/scripts/bootloader.sh
|
||||||
%attr(0600,root,root) %{_prefix}/lib/os-release
|
%attr(0500,root,root) /opt/kubeOS/scripts/Dockerfile
|
||||||
|
|
||||||
%files admin-container
|
%attr(0500,root,root) /opt/kubeOS/scripts/common/globalVariables.sh
|
||||||
%attr(0500,root,root) %{_bindir}/hostshell
|
%attr(0500,root,root) /opt/kubeOS/scripts/common/log.sh
|
||||||
%defattr(-,root,root,0500)
|
%attr(0500,root,root) /opt/kubeOS/scripts/common/utils.sh
|
||||||
%attr(0500,root,root) %{_prefix}/local/bin/set-ssh-pub-key.sh
|
|
||||||
%attr(0600,root,root) %{_prefix}/lib/sysmaster/set-ssh-pub-key.service
|
%attr(0500,root,root) /opt/kubeOS/scripts/create/imageCreate.sh
|
||||||
|
%attr(0500,root,root) /opt/kubeOS/scripts/create/rootfsCreate.sh
|
||||||
|
|
||||||
|
%attr(0600,root,root) /opt/kubeOS/scripts/00bootup/Global.cfg
|
||||||
|
%attr(0500,root,root) /opt/kubeOS/scripts/00bootup/module-setup.sh
|
||||||
|
%attr(0500,root,root) /opt/kubeOS/scripts/00bootup/mount.sh
|
||||||
|
|
||||||
|
%attr(0500,root,root) /opt/kubeOS/scripts/admin-container/set-ssh-pub-key.sh
|
||||||
|
%attr(0500,root,root) /opt/kubeOS/scripts/admin-container/Dockerfile
|
||||||
|
%attr(0600,root,root) /opt/kubeOS/scripts/admin-container/set-ssh-pub-key.service
|
||||||
|
|
||||||
%clean
|
%clean
|
||||||
rm -rfv %{buildroot}
|
rm -rfv %{buildroot}
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Jan 10 2024 Yuhang Wei<weiyuhang3@huawei.com> - 1.0.5-1
|
||||||
|
- Type:requirement
|
||||||
|
- CVE:NA
|
||||||
|
- SUG:restart
|
||||||
|
- DESC:update version to 1.0.5.1
|
||||||
|
|
||||||
* Tue Sep 05 2023 Yuhang Wei<weiyuhang3@huawei.com> - 1.0.4-4
|
* Tue Sep 05 2023 Yuhang Wei<weiyuhang3@huawei.com> - 1.0.4-4
|
||||||
- Type:requirement
|
- Type:requirement
|
||||||
- CVE:NA
|
- CVE:NA
|
||||||
|
|||||||
BIN
v1.0.4.tar.gz
BIN
v1.0.4.tar.gz
Binary file not shown.
BIN
v1.0.5.tar.gz
Normal file
BIN
v1.0.5.tar.gz
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user