diff --git a/internal/pkg/skuba/deployments/ssh/kubernetes.go b/internal/pkg/skuba/deployments/ssh/kubernetes.go index dd273fc2ed..362b1c11e1 100644 --- a/internal/pkg/skuba/deployments/ssh/kubernetes.go +++ b/internal/pkg/skuba/deployments/ssh/kubernetes.go @@ -39,7 +39,9 @@ const ( func init() { stateMap["kubernetes.bootstrap.upload-secrets"] = kubernetesUploadSecrets(KubernetesUploadSecretsContinueOnError) stateMap["kubernetes.join.upload-secrets"] = kubernetesUploadSecrets(KubernetesUploadSecretsFailOnError) - stateMap["kubernetes.install-node-pattern"] = kubernetesInstallNodePattern + stateMap["kubernetes.install-fresh-pkgs"] = kubernetesFreshInstallAllPkgs + stateMap["kubernetes.upgrade-kubeadm-pkg"] = kubernetesUpgradeKubeadmPkg + stateMap["kubernetes.upgrade-other-kubernetes-pkgs"] = kubernetesUpgradeOtherPkgs stateMap["kubernetes.restart-services"] = kubernetesRestartServices } @@ -56,24 +58,89 @@ func kubernetesUploadSecrets(errorHandling KubernetesUploadSecretsErrorBehavior) } } -func kubernetesInstallNodePattern(t *Target, data interface{}) error { +func kubernetesParseInterfaceVersions(data interface{}) (string, string, error) { kubernetesBaseOSConfiguration, ok := data.(deployments.KubernetesBaseOSConfiguration) if !ok { - return errors.New("couldn't access kubernetes base OS configuration") + return "", "", errors.New("couldn't access kubernetes base OS configuration") } v, err := version.ParseSemantic(kubernetesBaseOSConfiguration.CurrentVersion) if err != nil { - return err + return "", "", err } currentVersion := kubernetes.MajorMinorVersion(v) - patternName := fmt.Sprintf("patterns-caasp-Node-%s", currentVersion) + updatedVersion := "" if kubernetesBaseOSConfiguration.UpdatedVersion != "" { - updatedVersion := kubernetes.MajorMinorVersion(version.MustParseSemantic(kubernetesBaseOSConfiguration.UpdatedVersion)) - patternName = fmt.Sprintf("patterns-caasp-Node-%s-%s", currentVersion, updatedVersion) + updatedVersion = kubernetes.MajorMinorVersion(version.MustParseSemantic(kubernetesBaseOSConfiguration.UpdatedVersion)) + } + return currentVersion, updatedVersion, nil +} + +func kubernetesFreshInstallAllPkgs(t *Target, data interface{}) error { + current, _, err := kubernetesParseInterfaceVersions(data) + if err != nil { + return err } - _, _, err = t.ssh("zypper", "--userdata", "skuba", "--non-interactive", "install", patternName) + var pkgs []string + + pkgs = append(pkgs, fmt.Sprintf("+kubernetes-%s-kubeadm", current)) + pkgs = append(pkgs, fmt.Sprintf("+kubernetes-%s-kubelet", current)) + pkgs = append(pkgs, fmt.Sprintf("+kubernetes-%s-client", current)) + _, _, err = t.zypperInstall(pkgs...) + return err +} + +func kubernetesUpgradeKubeadmPkg(t *Target, data interface{}) error { + // zypper install -- -kubernetes-old-kubeadm +kubernetes-new-kubeadm + currentV, nextV, err := kubernetesParseInterfaceVersions(data) + if err != nil { + return err + } + if nextV == "" { + return errors.New("Incorrect upgrade version") + } + + var pkgs []string + + if currentV == "1.17" { + // on 1.17 we can't remove kubernetes-1.17-kubeadm, doesn't exist. + // removing kubeadm remove many things, but keeps kubelet alive, to + // be removed on the next step + pkgs = append(pkgs, "-patterns-caasp-Node-1.17", "-kubernetes-kubeadm", "-cri-o-kubeadm-criconfig") + } else { + pkgs = append(pkgs, fmt.Sprintf("-kubernetes-%s-kubeadm", currentV)) + } + + pkgs = append(pkgs, fmt.Sprintf("+kubernetes-%s-kubeadm", nextV)) + _, _, err = t.zypperInstall(pkgs...) + return err +} + +func kubernetesUpgradeOtherPkgs(t *Target, data interface{}) error { + // Installs the rest of the zypper kubernetes packages during the upgrade + // with zypper install -- -kubernetes-old-* +kubernetes-new-* + // We might need some fine grained installation instead + currentV, nextV, err := kubernetesParseInterfaceVersions(data) + if err != nil { + return err + } + if nextV == "" { + return errors.New("Incorrect upgrade version") + } + + var pkgs []string + + if currentV == "1.17" { + // on 1.17 we need to finalize the cleanup + pkgs = append(pkgs, "-kubernetes-kubelet -kubernetes-common -kubernetes-client") + } else { + pkgs = append(pkgs, fmt.Sprintf("-kubernetes-%s-*", currentV)) + } + + pkgs = append(pkgs, fmt.Sprintf("+kubernetes-%s-client", nextV)) + pkgs = append(pkgs, fmt.Sprintf("+kubernetes-%s-kubelet", nextV)) + _, _, err = t.zypperInstall(pkgs...) return err } diff --git a/internal/pkg/skuba/deployments/pattern.go b/internal/pkg/skuba/deployments/ssh/zypper.go similarity index 56% rename from internal/pkg/skuba/deployments/pattern.go rename to internal/pkg/skuba/deployments/ssh/zypper.go index 71acde288b..c867f224c2 100644 --- a/internal/pkg/skuba/deployments/pattern.go +++ b/internal/pkg/skuba/deployments/ssh/zypper.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 SUSE LLC. + * Copyright (c) 2020 SUSE LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,13 @@ * */ -package deployments +package ssh -func (t *Target) InstallNodePattern(kubernetesBaseOSConfiguration KubernetesBaseOSConfiguration) (bool, error) { - err := t.Apply(kubernetesBaseOSConfiguration, "kubernetes.install-node-pattern") - if err != nil { - return false, err - } - return true, nil +func (t *Target) zypperInstall(packages ...string) (stdout string, stderr string, error error) { + // Runs a zypper install command wrapped with the right userdata and parameters + var cliArgs []string + cliArgs = append(cliArgs, "--userdata", "skuba") + cliArgs = append(cliArgs, "--non-interactive", "install", "--") + cliArgs = append(cliArgs, packages...) + return t.ssh("zypper", cliArgs...) } diff --git a/pkg/skuba/actions/node/bootstrap/bootstrap.go b/pkg/skuba/actions/node/bootstrap/bootstrap.go index e3ca927d28..93e3dd9608 100644 --- a/pkg/skuba/actions/node/bootstrap/bootstrap.go +++ b/pkg/skuba/actions/node/bootstrap/bootstrap.go @@ -91,9 +91,9 @@ func Bootstrap(bootstrapConfiguration deployments.BootstrapConfiguration, target func coreBootstrap(initConfiguration *kubeadmapi.InitConfiguration, bootstrapConfiguration deployments.BootstrapConfiguration, target *deployments.Target) error { versionToDeploy := version.MustParseSemantic(initConfiguration.KubernetesVersion) - if _, err := target.InstallNodePattern(deployments.KubernetesBaseOSConfiguration{ + if err := target.Apply(deployments.KubernetesBaseOSConfiguration{ CurrentVersion: versionToDeploy.String(), - }); err != nil { + }, "kubernetes.install-fresh-pkgs"); err != nil { return err } diff --git a/pkg/skuba/actions/node/join/join.go b/pkg/skuba/actions/node/join/join.go index 26df654842..4e4c1602a5 100644 --- a/pkg/skuba/actions/node/join/join.go +++ b/pkg/skuba/actions/node/join/join.go @@ -52,10 +52,9 @@ func Join(client clientset.Interface, joinConfiguration deployments.JoinConfigur return err } - _, err = target.InstallNodePattern(deployments.KubernetesBaseOSConfiguration{ + if err := target.Apply(deployments.KubernetesBaseOSConfiguration{ CurrentVersion: currentClusterVersion.String(), - }) - if err != nil { + }, "kubernetes.install-fresh-pkgs"); err != nil { return err } diff --git a/pkg/skuba/actions/node/upgrade/apply.go b/pkg/skuba/actions/node/upgrade/apply.go index bcdd822e34..51bd249338 100644 --- a/pkg/skuba/actions/node/upgrade/apply.go +++ b/pkg/skuba/actions/node/upgrade/apply.go @@ -148,7 +148,7 @@ func Apply(client clientset.Interface, target *deployments.Target) error { err = target.Apply(deployments.KubernetesBaseOSConfiguration{ UpdatedVersion: nodeVersionInfoUpdate.Update.KubeletVersion.String(), CurrentVersion: nodeVersionInfoUpdate.Current.KubeletVersion.String(), - }, "kubernetes.install-node-pattern") + }, "kubernetes.upgrade-kubadm-pkg") if err != nil { return err } @@ -164,8 +164,9 @@ func Apply(client clientset.Interface, target *deployments.Target) error { return err } err = target.Apply(deployments.KubernetesBaseOSConfiguration{ - CurrentVersion: nodeVersionInfoUpdate.Update.KubeletVersion.String(), - }, "kubernetes.install-node-pattern") + UpdatedVersion: nodeVersionInfoUpdate.Update.KubeletVersion.String(), + CurrentVersion: nodeVersionInfoUpdate.Current.KubeletVersion.String(), + }, "kubernetes.upgrade-other-kubernetes-pkgs") if err != nil { return err }