From 47c3865fd413f94afa38ec3338a1d26ccfc802b9 Mon Sep 17 00:00:00 2001 From: Yuhang Wei Date: Mon, 31 Jul 2023 03:04:09 +0000 Subject: [PATCH] KubeOS: add lib path in hostshell, refactor config add library path for executing command in hostshell refactor config feature for maintainability Signed-off-by: Yuhang Wei --- cmd/admin-container/main.go | 3 +- cmd/agent/server/config.go | 153 +++++++++++++--------- cmd/agent/server/config_test.go | 28 ++-- cmd/agent/server/server.go | 1 + cmd/agent/server/utils.go | 2 - cmd/operator/controllers/os_controller.go | 9 +- 6 files changed, 118 insertions(+), 78 deletions(-) diff --git a/cmd/admin-container/main.go b/cmd/admin-container/main.go index 14e57ec0..f6a72939 100644 --- a/cmd/admin-container/main.go +++ b/cmd/admin-container/main.go @@ -41,8 +41,9 @@ func main() { paths[i] = rootFsPath + p } path := "PATH=$PATH:" + strings.Join(paths, ":") + lib := "LD_LIBRARY_PATH=/lib:/lib64:/usr/lib:/usr/lib64:$LD_LIBRARY_PATH" if err := syscall.Exec("/usr/bin/nsenter", []string{"nsenter", "-t", "1", "-a", - "env", "-i", path, rootFsPath + bashPath}, os.Environ()); err != nil { + "env", "-i", path, lib, rootFsPath + bashPath}, os.Environ()); err != nil { logrus.Error("nsenter excute error", err) } } diff --git a/cmd/agent/server/config.go b/cmd/agent/server/config.go index a1662003..e7110f8a 100644 --- a/cmd/agent/server/config.go +++ b/cmd/agent/server/config.go @@ -28,11 +28,11 @@ import ( ) const ( - defaultProcPath = "/proc/sys/" - defaultKernelConPath = "/etc/sysctl.conf" - defalutGrubCfgPath = "/boot/efi/EFI/openEuler/grub.cfg" defaultKernelConPermission = 0644 defaultGrubCfgPermission = 0751 + // Config has two format: key or key=value. Following variables stand for the length after splitting + onlyKey = 1 + kvPair = 2 ) // Configuration defines interface of configuring @@ -49,14 +49,15 @@ func (k KernelSysctl) SetConfig(config *agent.SysConfig) error { for key, keyInfo := range config.Contents { procPath := getProcPath(key) if keyInfo.Operation == "delete" { - logrus.Errorf("Failed to delete kernel.sysctl config with key %s", key) - } else if keyInfo.Operation == "add" || keyInfo.Operation == "update" || keyInfo.Operation == "" { + logrus.Warnf("Failed to delete kernel.sysctl config with key %s", key) + } else if keyInfo.Operation == "" && keyInfo.Value != "" { if err := os.WriteFile(procPath, []byte(keyInfo.Value), defaultKernelConPermission); err != nil { logrus.Errorf("Failed to write kernel.sysctl with key %s: %v", key, err) return err } + logrus.Infof("Configured kernel.sysctl %s=%s", key, keyInfo.Value) } else { - logrus.Errorf("Failed to parse kernel.sysctl config operation %s", keyInfo.Operation) + logrus.Errorf("Failed to parse kernel.sysctl config operation %s value %s", keyInfo.Operation, keyInfo.Value) } } return nil @@ -175,49 +176,27 @@ func modifyLinuxCfg(m map[string]*agent.KeyInfo, line string) (string, error) { expectConfigs := deepCopyConfigMap(m) newConfigs := []string{" "} oldConfigs := strings.Split(line, " ") - // Config has two format: key or key=value. Following variables stand for the length after splitting - onlyKey, KVpair := 1, 2 for _, oldConfig := range oldConfigs { if oldConfig == "" { continue } // At most 2 substrings can be returned to satisfy the case like root=UUID=xxxx - config := strings.SplitN(oldConfig, "=", KVpair) - if len(config) != onlyKey && len(config) != KVpair { + config := strings.SplitN(oldConfig, "=", kvPair) + if len(config) != onlyKey && len(config) != kvPair { return "", fmt.Errorf("cannot parse grub.cfg linux line %s", oldConfig) } - if keyInfo, ok := expectConfigs[config[0]]; ok { - if keyInfo.Operation == "delete" { - if len(config) == KVpair && keyInfo.Value != config[1] { - logrus.Warnf("Failed to delete key %s with inconsistent values "+ - "%s and %s", config[0], config[1], keyInfo.Value) - newConfigs = append(newConfigs, oldConfig) - } - delete(expectConfigs, config[0]) - continue - } - if keyInfo.Operation != "delete" && len(config) == KVpair { - config[1] = keyInfo.Value - } - } - if len(config) == onlyKey { - newConfigs = append(newConfigs, config[0]) - } else if len(config) == KVpair { - newConfigs = append(newConfigs, strings.Join(config, "=")) - } - delete(expectConfigs, config[0]) - } - for key, keyInfo := range expectConfigs { - if keyInfo.Operation == "delete" { - logrus.Warnf("Failed to delete inexistent key %s", key) - continue - } - if keyInfo.Value == "" { - newConfigs = append(newConfigs, key) + newKeyInfo, ok := expectConfigs[config[0]] + var newConfig string + if ok && newKeyInfo.Operation == "delete" { + newConfig = handleDeleteKey(config, newKeyInfo) } else { - newConfigs = append(newConfigs, fmt.Sprintf("%s=%s", key, keyInfo.Value)) + newConfig = handleUpdateKey(config, newKeyInfo, ok) } + newConfigs = append(newConfigs, newConfig) + delete(expectConfigs, config[0]) } + newConfig := handleAddKey(expectConfigs, true) + newConfigs = append(newConfigs, newConfig...) return convertNewConfigsToString(newConfigs) } @@ -281,37 +260,25 @@ func getAndSetConfigsFromFile(expectConfigs map[string]*agent.KeyInfo, path stri continue } configKV := strings.Split(line, "=") - requiredLen := 2 // If it is in the key=value format, the length after splitting is 2 - if len(configKV) != requiredLen { + if len(configKV) != kvPair { logrus.Errorf("could not parse systctl config %s", line) return nil, fmt.Errorf("could not parse systctl config %s", line) } - key := strings.TrimSpace(configKV[0]) - value := strings.TrimSpace(configKV[1]) - if newKeyInfo, ok := expectConfigs[key]; ok { - if newKeyInfo.Operation != "delete" { - config := key + " = " + newKeyInfo.Value - configsWrite = append(configsWrite, config) - } else if newKeyInfo.Operation == "delete" && newKeyInfo.Value != value { - logrus.Warnf("Failed to delete key %s with inconsistent values "+ - "%s and %s", key, value, newKeyInfo.Value) - configsWrite = append(configsWrite, line) - } - delete(expectConfigs, key) - continue + newKeyInfo, ok := expectConfigs[configKV[0]] + var newConfig string + if ok && newKeyInfo.Operation == "delete" { + newConfig = handleDeleteKey(configKV, newKeyInfo) + } else { + newConfig = handleUpdateKey(configKV, newKeyInfo, ok) } - configsWrite = append(configsWrite, line) + configsWrite = append(configsWrite, newConfig) + delete(expectConfigs, configKV[0]) } if err = configScanner.Err(); err != nil { return nil, err } - - for newKey, newKeyInfo := range expectConfigs { - if newKeyInfo.Operation != "delete" { - config := newKey + " = " + newKeyInfo.Value - configsWrite = append(configsWrite, config) - } - } + newConfig := handleAddKey(expectConfigs, false) + configsWrite = append(configsWrite, newConfig...) return configsWrite, nil } @@ -324,6 +291,9 @@ func writeConfigToFile(path string, configs []string) error { defer f.Close() w := bufio.NewWriter(f) for _, line := range configs { + if line == "" { + continue + } if _, err = w.WriteString(line + "\n"); err != nil { return err } @@ -362,3 +332,62 @@ func getKernelConPath() string { func getGrubCfgPath() string { return "/boot/efi/EFI/openEuler/grub.cfg" } + +// 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]) + return "" + } + key, oldValue := config[0], config[1] + if oldValue != configInfo.Value { + logrus.Warnf("Failed to delete key %s with inconsistent values "+ + "%s and %s", key, oldValue, configInfo.Value) + return strings.Join(config, "=") + } + logrus.Infof("delete configuration %s=%s", key, oldValue) + return "" +} + +// 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, oldValue := config[0], config[1] + if !isFound { + return key + "=" + oldValue + } + if configInfo.Operation != "" { + logrus.Warnf("Unknown operation %s, updating key %s with value %s by default", + configInfo.Operation, key, configInfo.Value) + } + 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 +} + +func handleAddKey(m map[string]*agent.KeyInfo, isOnlyKeyValid bool) []string { + var configs []string + for key, keyInfo := range m { + if keyInfo.Operation == "delete" { + logrus.Warnf("Failed to delete inexistent key %s", key) + continue + } + k, v := strings.TrimSpace(key), strings.TrimSpace(keyInfo.Value) + if keyInfo.Value == "" && isOnlyKeyValid { + logrus.Infoln("add configuration ", k) + configs = append(configs, k) + } else if keyInfo.Value == "" { + logrus.Warnf("Failed to add key %s with null value", k) + } else { + logrus.Infof("add configuration %s=%s", k, v) + configs = append(configs, fmt.Sprintf("%s=%s", k, v)) + } + } + return configs +} diff --git a/cmd/agent/server/config_test.go b/cmd/agent/server/config_test.go index 725d1f8f..903af878 100644 --- a/cmd/agent/server/config_test.go +++ b/cmd/agent/server/config_test.go @@ -59,7 +59,7 @@ func TestKernelSysctl_SetConfig(t *testing.T) { wantErr: false, }, { - name: "invalide operation", + name: "invalid operation", k: KernelSysctl{}, args: args{config: &agent.SysConfig{ Contents: map[string]*agent.KeyInfo{ @@ -102,12 +102,13 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) { Contents: map[string]*agent.KeyInfo{ "a": {Value: "1"}, "b": {Value: "2"}, + "c": {Value: ""}, }, }, }, want: []string{ - "a = 1", - "b = 2", + "a=1", + "b=2", }, wantErr: false, }, @@ -118,12 +119,13 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) { ConfigPath: persistPath, Contents: map[string]*agent.KeyInfo{ "a": {Value: "2"}, + "b": {Value: ""}, }, }, }, want: []string{ - "a = 2", - "b = 2", + "a=2", + "b=2", }, wantErr: false, }, @@ -139,7 +141,7 @@ func TestKerSysctlPersist_SetConfig(t *testing.T) { }, }, want: []string{ - "a = 2", + "a=2", }, wantErr: false, }, @@ -208,12 +210,13 @@ menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestri args: args{ config: &agent.SysConfig{ Contents: map[string]*agent.KeyInfo{ - "panic": {Value: "5"}, - "quiet": {Value: "", Operation: "delete"}, - "selinux": {Value: "1", Operation: "delete"}, - "acpi": {Value: "off", Operation: "delete"}, - "debug": {}, - "pci": {Value: "nomis"}, + "panic": {Value: "5"}, // update existent kv + "quiet": {Value: "", Operation: "delete"}, // delete existent key + "oops": {Value: ""}, // update existent kv with null value + "selinux": {Value: "1", Operation: "delete"}, // failed to delete inconsistent kv + "acpi": {Value: "off", Operation: "delete"}, // failed to delete inexistent kv + "debug": {}, // add key + "pci": {Value: "nomis"}, // add kv }, }, }, @@ -228,6 +231,7 @@ menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestri Contents: map[string]*agent.KeyInfo{ "panic": {Value: "4"}, "quiet": {Value: "", Operation: "delete"}, + "oops": {Value: ""}, // update existent kv with null value "selinux": {Value: "1", Operation: "delete"}, "acpi": {Value: "off", Operation: "delete"}, "debug": {}, diff --git a/cmd/agent/server/server.go b/cmd/agent/server/server.go index d7737792..b41ebc49 100644 --- a/cmd/agent/server/server.go +++ b/cmd/agent/server/server.go @@ -120,6 +120,7 @@ func (s *Server) update(req *pb.UpdateRequest) error { return err } side, next, err := getNextPart(partA, partB) + logrus.Infoln("switching to " + side + " partition " + next) if err != nil { return err } diff --git a/cmd/agent/server/utils.go b/cmd/agent/server/utils.go index 8cea6393..c8a72c3e 100644 --- a/cmd/agent/server/utils.go +++ b/cmd/agent/server/utils.go @@ -98,13 +98,11 @@ func getNextPart(partA string, partB string) (string, string, error) { return "", "", fmt.Errorf("fail to lsblk %s out:%s err:%s", partA, out, err) } mountPoint := strings.TrimSpace(string(out)) - logrus.Infoln(partA + " mounted on " + mountPoint) side := partA if mountPoint == "/" { side = partB } - logrus.Infoln("side is " + side) next := "B" if side != partB { next = "A" diff --git a/cmd/operator/controllers/os_controller.go b/cmd/operator/controllers/os_controller.go index 40610cfa..87eaac7b 100644 --- a/cmd/operator/controllers/os_controller.go +++ b/cmd/operator/controllers/os_controller.go @@ -174,7 +174,6 @@ func assignUpgrade(ctx context.Context, r common.ReadStatusWriter, os upgradev1. log.Error(err, "failed to get osInstance "+node.Name) return false, err } - log.Error(err, "not found osInstance "+node.Name) continue } count++ @@ -188,6 +187,14 @@ func assignUpgrade(ctx context.Context, r common.ReadStatusWriter, os upgradev1. 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 { -- Gitee