From 4443dc395972a1fae288fbd81544be048aa8eef1 Mon Sep 17 00:00:00 2001 From: Andrea Mazzotti Date: Wed, 19 Jun 2024 12:53:10 +0200 Subject: [PATCH] Use dynamic RKE2 data-dir Signed-off-by: Andrea Mazzotti --- cmd/support/main.go | 54 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/cmd/support/main.go b/cmd/support/main.go index 3ebc9c8d..398962fa 100644 --- a/cmd/support/main.go +++ b/cmd/support/main.go @@ -21,6 +21,7 @@ import ( "bufio" "bytes" "compress/gzip" + "encoding/json" "errors" "fmt" "io" @@ -44,7 +45,9 @@ const ( k3sKubeConfig = "/etc/rancher/k3s/k3s.yaml" k3sKubectl = "/usr/local/bin/kubectl" rkeKubeConfig = "/etc/rancher/rke2/rke2.yaml" - rkeKubectl = "/var/lib/rancher/rke2/bin/kubectl" + rkeConfigPath = "/etc/rancher/rke2/config.yaml.d/50-rancher.yaml" + rkeDataDirDefault = "/var/lib/rancher/rke2" + rkeKubectl = "/bin/kubectl" elementalAgentPlanDir = "/var/lib/elemental/agent/applied/" rancherAgentPlanDirDefault = "/var/lib/rancher/agent/applied/" rancherAgentConf = "/etc/rancher/agent/config.yaml" @@ -56,6 +59,10 @@ const ( systemOEMDir = "/system/oem" ) +type RKEConfig struct { + DataDir string `json:"data-dir,omitempty" yaml:"data-dir,omitempty"` +} + func getServices() []string { return []string{ "elemental-system-agent", @@ -553,14 +560,53 @@ func getKubectl() (string, error) { log.Infof("Found k3s kubectl at %s", k3sKubectl) return k3sKubectl, nil } - if existsNoWarn(rkeKubectl) { - log.Infof("Found rke kubectl at %s", rkeKubectl) - return rkeKubectl, nil + rkeKubectlPath := getRKEKubectlPath() + if existsNoWarn(rkeKubectlPath) { + log.Infof("Found rke kubectl at %s", rkeKubectlPath) + return rkeKubectlPath, nil } return "", errors.New("Cant find kubectl") } +// getRKEKubectlPath tries to locate the RKE2 installed kubectl, parsing the RKE2 config. +// Note that this config has .yaml extension but is a JSON file. +// We try to parse both. +// See: https://github.com/rancher/rancher/issues/45865 +func getRKEKubectlPath() string { + if existsNoWarn(rkeConfigPath) { + log.Infof("Found RKE config: %s", rkeConfigPath) + rkeConfigBytes, err := os.ReadFile(rkeConfigPath) + if err != nil { + log.Errorf("Could not read file '%s': %s", rkeConfigPath, err.Error()) + return filepath.Join(rkeDataDirDefault, rkeKubectl) + } + rkeConfig := RKEConfig{} + err = json.Unmarshal(rkeConfigBytes, &rkeConfig) + if err != nil { + log.Errorf("Could not unmarshal JSON '%s': %s", rkeConfigPath, err.Error()) + } + if len(rkeConfig.DataDir) > 0 { + kubectlPath := filepath.Join(rkeConfig.DataDir, rkeKubectl) + log.Infof("Determined kubectl location: %s", kubectlPath) + return kubectlPath + } + // If JSON didn't work, try YAML + err = yaml.Unmarshal(rkeConfigBytes, &rkeConfig) + if err != nil { + log.Errorf("Could not unmarshal YAML '%s': %s", rkeConfigPath, err.Error()) + } + if len(rkeConfig.DataDir) > 0 { + kubectlPath := filepath.Join(rkeConfig.DataDir, rkeKubectl) + log.Infof("Determined kubectl location: %s", kubectlPath) + return kubectlPath + } + } + return filepath.Join(rkeDataDirDefault, rkeKubectl) +} + +// getSystemAgentAppliedDir tries to locate the Rancher System Agent applied plans dir, +// parsing the system agent config. func getSystemAgentAppliedDir(systemAgentConfigPath string) string { if existsNoWarn(systemAgentConfigPath) { log.Infof("Found Rancher System Agent config: %s", systemAgentConfigPath)