From 7266fe19572a0fe3771d61017838b137485d9622 Mon Sep 17 00:00:00 2001 From: Ethan Mosbaugh Date: Fri, 31 Jan 2025 10:42:12 -0800 Subject: [PATCH] feat(v2): enable v2 restore (#1776) --- cmd/installer/cli/install2.go | 32 +---- cmd/installer/cli/restore.go | 2 +- cmd/installer/cli/restore2.go | 31 +++-- e2e/scripts/resume-restore.exp | 8 ++ .../controllers/installation_controller.go | 4 +- operator/pkg/cli/upgrade.go | 2 +- operator/pkg/k8sutil/installation.go | 23 +-- operator/pkg/upgrade/installation.go | 12 +- operator/pkg/upgrade/upgrade.go | 2 +- .../embeddedclusteroperator.go | 7 +- pkg/addons2/adminconsole/values.go | 21 ++- pkg/addons2/highavailability.go | 5 +- pkg/dryrun/kubeutils.go | 4 - pkg/extensions/install.go | 2 + pkg/highavailability/enable.go | 6 +- pkg/kubeutils/interface.go | 5 - pkg/kubeutils/kubeutils.go | 131 +++++------------- 17 files changed, 116 insertions(+), 181 deletions(-) diff --git a/cmd/installer/cli/install2.go b/cmd/installer/cli/install2.go index c91f3d5fd..27e83c25d 100644 --- a/cmd/installer/cli/install2.go +++ b/cmd/installer/cli/install2.go @@ -46,7 +46,6 @@ import ( k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/yaml" ) @@ -343,9 +342,7 @@ func runInstall2(ctx context.Context, name string, flags Install2CmdFlags, metri return fmt.Errorf("unable to install extensions: %w", err) } - // mark that the installation as installed as everything has been applied - in.Status.State = ecv1beta1.InstallationStateInstalled - if err := kubeutils.UpdateInstallationStatus(ctx, kcli, in); err != nil { + if err := kubeutils.SetInstallationState(ctx, kcli, in, ecv1beta1.InstallationStateInstalled, "Installed"); err != nil { return fmt.Errorf("unable to update installation: %w", err) } @@ -653,7 +650,6 @@ func recordInstallation(ctx context.Context, kcli client.Client, flags Install2C Name: time.Now().Format("20060102150405"), }, Spec: ecv1beta1.InstallationSpec{ - SourceType: ecv1beta1.InstallationSourceTypeCRD, ClusterID: metrics.ClusterID().String(), MetricsBaseURL: metrics.BaseURL(flags.license), AirGap: flags.isAirgap, @@ -668,12 +664,12 @@ func recordInstallation(ctx context.Context, kcli client.Client, flags Install2C }, }, } - if err := kcli.Create(ctx, installation); err != nil { + if err := kubeutils.CreateInstallation(ctx, kcli, installation); err != nil { return nil, fmt.Errorf("create installation: %w", err) } // the kubernetes api does not allow us to set the state of an object when creating it - err = setInstallationState(ctx, installation, ecv1beta1.InstallationStateKubernetesInstalled) + err = kubeutils.SetInstallationState(ctx, kcli, installation, ecv1beta1.InstallationStateKubernetesInstalled, "Kubernetes installed") if err != nil { return nil, fmt.Errorf("set installation state to KubernetesInstalled: %w", err) } @@ -682,28 +678,6 @@ func recordInstallation(ctx context.Context, kcli client.Client, flags Install2C return installation, nil } -func setInstallationState(ctx context.Context, installation *ecv1beta1.Installation, state string) error { - kcli, err := kubeutils.KubeClient() - if err != nil { - return fmt.Errorf("create kube client: %w", err) - } - - // retry on all errors - return retry.OnError(retry.DefaultRetry, func(_ error) bool { return true }, func() error { - err := kcli.Get(ctx, client.ObjectKey{Name: installation.Name}, installation) - if err != nil { - return fmt.Errorf("get installation: %w", err) - } - - installation.Status.State = state - - if err := kcli.Status().Update(ctx, installation); err != nil { - return fmt.Errorf("update installation status: %w", err) - } - return nil - }) -} - func createECNamespace(ctx context.Context, kcli client.Client) error { ns := corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ diff --git a/cmd/installer/cli/restore.go b/cmd/installer/cli/restore.go index 1e57518a5..1c2cc7490 100644 --- a/cmd/installer/cli/restore.go +++ b/cmd/installer/cli/restore.go @@ -28,7 +28,7 @@ func RestoreCmd(ctx context.Context, name string) *cobra.Command { var s3Store s3BackupStore cmd := &cobra.Command{ - Use: "restore", + Use: "restore-legacy", Short: fmt.Sprintf("Restore a %s cluster", name), PreRunE: func(cmd *cobra.Command, args []string) error { if err := preRunInstall2(cmd, &flags); err != nil { diff --git a/cmd/installer/cli/restore2.go b/cmd/installer/cli/restore2.go index af032f8f3..24b889534 100644 --- a/cmd/installer/cli/restore2.go +++ b/cmd/installer/cli/restore2.go @@ -89,7 +89,7 @@ func Restore2Cmd(ctx context.Context, name string) *cobra.Command { var skipStoreValidation bool cmd := &cobra.Command{ - Use: "restore2", + Use: "restore", Short: fmt.Sprintf("Restore a %s cluster", name), PreRunE: func(cmd *cobra.Command, args []string) error { if err := preRunInstall2(cmd, &flags); err != nil { @@ -544,6 +544,22 @@ func runRestoreExtensions(ctx context.Context, flags Install2CmdFlags) error { } func runRestoreApp(ctx context.Context, backupToRestore *disasterrecovery.ReplicatedBackup) error { + logrus.Debugf("setting installation status to installed") + kcli, err := kubeutils.KubeClient() + if err != nil { + return fmt.Errorf("create kube client: %w", err) + } + + in, err := kubeutils.GetLatestInstallation(ctx, kcli) + if err != nil { + return fmt.Errorf("get latest installation: %w", err) + } + + err = kubeutils.SetInstallationState(ctx, kcli, in, ecv1beta1.InstallationStateInstalled, "Installed") + if err != nil { + return fmt.Errorf("update installation status: %w", err) + } + logrus.Debugf("restoring app from backup %q", backupToRestore.GetName()) if err := restoreFromReplicatedBackup(ctx, *backupToRestore, disasterRecoveryComponentApp, true); err != nil { return err @@ -1490,16 +1506,15 @@ func restoreReconcileInstallationFromRuntimeConfig(ctx context.Context) error { in.Spec.RuntimeConfig = &ecv1beta1.RuntimeConfigSpec{} } - // We allow the user to override the port with a flag to the restore command. - in.Spec.RuntimeConfig.LocalArtifactMirror.Port = runtimeconfig.LocalArtifactMirrorPort() - - if err := kubeutils.UpdateInstallation(ctx, kcli, in); err != nil { + err = kubeutils.UpdateInstallation(ctx, kcli, in, func(in *ecv1beta1.Installation) { + in.Spec.RuntimeConfig.LocalArtifactMirror.Port = runtimeconfig.LocalArtifactMirrorPort() + }) + if err != nil { return fmt.Errorf("update installation: %w", err) } - in.Status.State = ecv1beta1.InstallationStateKubernetesInstalled - - if err := kubeutils.UpdateInstallationStatus(ctx, kcli, in); err != nil { + err = kubeutils.SetInstallationState(ctx, kcli, in, ecv1beta1.InstallationStateKubernetesInstalled, "Kubernetes installed") + if err != nil { return fmt.Errorf("update installation status: %w", err) } diff --git a/e2e/scripts/resume-restore.exp b/e2e/scripts/resume-restore.exp index 14101d67a..9826031c8 100755 --- a/e2e/scripts/resume-restore.exp +++ b/e2e/scripts/resume-restore.exp @@ -375,6 +375,14 @@ expect { } } +expect { + -timeout 240 "Extensions installed!" {} + timeout { + puts "\n\nFailed to find 'extensions installed' spinner." + exit 1 + } +} + expect { "Restoring application" {} timeout { diff --git a/operator/controllers/installation_controller.go b/operator/controllers/installation_controller.go index af8b72f50..5591d64d0 100644 --- a/operator/controllers/installation_controller.go +++ b/operator/controllers/installation_controller.go @@ -522,7 +522,7 @@ func (r *InstallationReconciler) Reconcile(ctx context.Context, req ctrl.Request // are going to operate only on the newest one (sorting by installation // name). log := ctrl.LoggerFrom(ctx) - installs, err := kubeutils.ListCRDInstallations(ctx, r.Client) + installs, err := kubeutils.ListInstallations(ctx, r.Client) if err != nil { return ctrl.Result{}, fmt.Errorf("failed to list installations: %w", err) } @@ -609,7 +609,7 @@ func (r *InstallationReconciler) Reconcile(ctx context.Context, req ctrl.Request } // save the installation status. nothing more to do with it. - if err := r.Status().Update(ctx, in.DeepCopy()); err != nil { + if err := r.Status().Update(ctx, in); err != nil { if k8serrors.IsConflict(err) { return ctrl.Result{}, fmt.Errorf("failed to update status: conflict") } diff --git a/operator/pkg/cli/upgrade.go b/operator/pkg/cli/upgrade.go index 907003ba4..214ee60e4 100644 --- a/operator/pkg/cli/upgrade.go +++ b/operator/pkg/cli/upgrade.go @@ -53,7 +53,7 @@ func UpgradeCmd() *cobra.Command { if err != nil { return fmt.Errorf("apply installation: %w", err) } - previousInstallation, err := kubeutils.GetPreviousCRDInstallation(cmd.Context(), cli, installation) + previousInstallation, err := kubeutils.GetPreviousInstallation(cmd.Context(), cli, installation) if err != nil { return fmt.Errorf("get previous installation: %w", err) } diff --git a/operator/pkg/k8sutil/installation.go b/operator/pkg/k8sutil/installation.go index 4ecc9aa54..9f29e8095 100644 --- a/operator/pkg/k8sutil/installation.go +++ b/operator/pkg/k8sutil/installation.go @@ -5,30 +5,19 @@ import ( "fmt" ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1" + "github.com/replicatedhq/embedded-cluster/pkg/kubeutils" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/client" ) func SetInstallationState(ctx context.Context, cli client.Client, name string, state string, reason string, pendingCharts ...string) error { - err := retry.RetryOnConflict(retry.DefaultRetry, func() error { - updatedIn := ecv1beta1.Installation{} - if err := cli.Get(ctx, types.NamespacedName{Name: name}, &updatedIn); err != nil { - return fmt.Errorf("get crd installation before updating status: %w", err) - } - - updatedIn.Status.SetState(state, reason, pendingCharts) - - if err := cli.Status().Update(ctx, &updatedIn); err != nil { - return fmt.Errorf("update crd installation status: %w", err) - } - return nil - }) - if err != nil { - return fmt.Errorf("persistent conflict error, failed to update installation %s status: %w", name, err) + in := &ecv1beta1.Installation{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, } - return nil + return kubeutils.SetInstallationState(ctx, cli, in, state, reason, pendingCharts...) } func CheckConditionStatus(inStat ecv1beta1.InstallationStatus, conditionName string) metav1.ConditionStatus { diff --git a/operator/pkg/upgrade/installation.go b/operator/pkg/upgrade/installation.go index ca5e29c62..b25fb789e 100644 --- a/operator/pkg/upgrade/installation.go +++ b/operator/pkg/upgrade/installation.go @@ -17,13 +17,13 @@ func CreateInstallation(ctx context.Context, cli client.Client, original *ecv1be // check if the installation already exists - this function can be called multiple times // if the installation is already created, we can just return - if in, err := kubeutils.GetCRDInstallation(ctx, cli, in.Name); err == nil { + if in, err := kubeutils.GetInstallation(ctx, cli, in.Name); err == nil { log.Info(fmt.Sprintf("Installation %s already exists", in.Name)) return nil } log.Info(fmt.Sprintf("Creating installation %s", in.Name)) - err := cli.Create(ctx, in) + err := kubeutils.CreateInstallation(ctx, cli, in) if err != nil { return fmt.Errorf("create installation: %w", err) } @@ -41,13 +41,15 @@ func CreateInstallation(ctx context.Context, cli client.Client, original *ecv1be // reApplyInstallation updates the installation spec to match what's in the configmap used by the upgrade job. // This is required because the installation CRD may have been updated as part of this upgrade, and additional fields may be present now. func reApplyInstallation(ctx context.Context, cli client.Client, in *ecv1beta1.Installation) error { - existingIn, err := kubeutils.GetCRDInstallation(ctx, cli, in.Name) + existingIn, err := kubeutils.GetInstallation(ctx, cli, in.Name) if err != nil { return fmt.Errorf("get installation: %w", err) } - existingIn.Spec = *in.Spec.DeepCopy() // copy the spec in, in case there were fields added to the spec - if err := kubeutils.UpdateInstallation(ctx, cli, existingIn); err != nil { + err = kubeutils.UpdateInstallation(ctx, cli, existingIn, func(ex *ecv1beta1.Installation) { + ex.Spec = *in.Spec.DeepCopy() // copy the spec in, in case there were fields added to the spec + }) + if err != nil { return fmt.Errorf("update installation: %w", err) } diff --git a/operator/pkg/upgrade/upgrade.go b/operator/pkg/upgrade/upgrade.go index 2fc6f6fba..6f6cc219b 100644 --- a/operator/pkg/upgrade/upgrade.go +++ b/operator/pkg/upgrade/upgrade.go @@ -239,7 +239,7 @@ func upgradeExtensions(ctx context.Context, cli client.Client, in *ecv1beta1.Ins return fmt.Errorf("set installation state: %w", err) } - previous, err := kubeutils.GetPreviousCRDInstallation(ctx, cli, in) + previous, err := kubeutils.GetPreviousInstallation(ctx, cli, in) if err != nil { return fmt.Errorf("get previous installation: %w", err) } diff --git a/pkg/addons/embeddedclusteroperator/embeddedclusteroperator.go b/pkg/addons/embeddedclusteroperator/embeddedclusteroperator.go index 9c3dc0a6f..fa52548c1 100644 --- a/pkg/addons/embeddedclusteroperator/embeddedclusteroperator.go +++ b/pkg/addons/embeddedclusteroperator/embeddedclusteroperator.go @@ -257,7 +257,7 @@ func (e *EmbeddedClusterOperator) Outro(ctx context.Context, cli client.Client, } } - installation := ecv1beta1.Installation{ + installation := &ecv1beta1.Installation{ TypeMeta: metav1.TypeMeta{ APIVersion: ecv1beta1.GroupVersion.String(), Kind: "Installation", @@ -284,12 +284,11 @@ func (e *EmbeddedClusterOperator) Outro(ctx context.Context, cli client.Client, }, }, } - if err := cli.Create(ctx, &installation); err != nil { + if err := cli.Create(ctx, installation); err != nil { return fmt.Errorf("unable to create installation: %w", err) } - // we wait for the installation to exist here because items do not show up in the apiserver instantaneously after being created - if err := kubeutils.WaitAndMarkInstallation(ctx, cli, installation.Name, ecv1beta1.InstallationStateKubernetesInstalled); err != nil { + if err := kubeutils.SetInstallationState(ctx, cli, installation, ecv1beta1.InstallationStateKubernetesInstalled, "Kubernetes installed"); err != nil { return fmt.Errorf("unable to wait and mark installation: %w", err) } diff --git a/pkg/addons2/adminconsole/values.go b/pkg/addons2/adminconsole/values.go index 7b4032476..e0c03a6bf 100644 --- a/pkg/addons2/adminconsole/values.go +++ b/pkg/addons2/adminconsole/values.go @@ -31,25 +31,32 @@ func (a *AdminConsole) GenerateHelmValues(ctx context.Context, kcli client.Clien copiedValues["isAirgap"] = "false" } + extraEnv := []map[string]interface{}{ + { + "name": "ENABLE_IMPROVED_DR", + "value": "true", + }, + } + if a.Proxy != nil { - copiedValues["extraEnv"] = []map[string]interface{}{ - { + extraEnv = append(extraEnv, + map[string]interface{}{ "name": "HTTP_PROXY", "value": a.Proxy.HTTPProxy, }, - { + map[string]interface{}{ "name": "HTTPS_PROXY", "value": a.Proxy.HTTPSProxy, }, - { + map[string]interface{}{ "name": "NO_PROXY", "value": a.Proxy.NoProxy, }, - } - } else { - delete(copiedValues, "extraEnv") + ) } + copiedValues["extraEnv"] = extraEnv + copiedValues, err = helm.SetValue(copiedValues, "kurlProxy.nodePort", runtimeconfig.AdminConsolePort()) if err != nil { return nil, errors.Wrap(err, "set kurlProxy.nodePort") diff --git a/pkg/addons2/highavailability.go b/pkg/addons2/highavailability.go index 3de1b2b38..9f58f0f04 100644 --- a/pkg/addons2/highavailability.go +++ b/pkg/addons2/highavailability.go @@ -109,9 +109,10 @@ func EnableHA(ctx context.Context, kcli client.Client, isAirgap bool, serviceCID if err != nil { return errors.Wrap(err, "get latest installation") } - in.Spec.HighAvailability = true - if err := kubeutils.UpdateInstallation(ctx, kcli, in); err != nil { + if err := kubeutils.UpdateInstallation(ctx, kcli, in, func(in *ecv1beta1.Installation) { + in.Spec.HighAvailability = true + }); err != nil { return errors.Wrap(err, "update installation") } diff --git a/pkg/dryrun/kubeutils.go b/pkg/dryrun/kubeutils.go index 6a347c0f7..ba490eb09 100644 --- a/pkg/dryrun/kubeutils.go +++ b/pkg/dryrun/kubeutils.go @@ -78,10 +78,6 @@ func (k *KubeUtils) WaitForKubernetes(ctx context.Context, cli client.Client) <- return errCh } -func (k *KubeUtils) WaitAndMarkInstallation(ctx context.Context, cli client.Client, name string, state string) error { - return nil -} - func (k *KubeUtils) KubeClient() (client.Client, error) { return KubeClient() } diff --git a/pkg/extensions/install.go b/pkg/extensions/install.go index 45311387c..9b2ad5e0c 100644 --- a/pkg/extensions/install.go +++ b/pkg/extensions/install.go @@ -53,5 +53,7 @@ func Install(ctx context.Context, isAirgap bool) error { } } + loading.Infof("Extensions installed!") + return nil } diff --git a/pkg/highavailability/enable.go b/pkg/highavailability/enable.go index e2dacff0d..68f7a17a9 100644 --- a/pkg/highavailability/enable.go +++ b/pkg/highavailability/enable.go @@ -9,6 +9,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1" "github.com/replicatedhq/embedded-cluster/pkg/constants" "github.com/replicatedhq/embedded-cluster/pkg/kubeutils" "github.com/replicatedhq/embedded-cluster/pkg/spinner" @@ -63,8 +64,9 @@ func EnableHA(ctx context.Context, kcli client.Client) error { } loading.Debugf("updating installation") - in.Spec.HighAvailability = true - if err := kubeutils.UpdateInstallation(ctx, kcli, in); err != nil { + if err := kubeutils.UpdateInstallation(ctx, kcli, in, func(in *ecv1beta1.Installation) { + in.Spec.HighAvailability = true + }); err != nil { return fmt.Errorf("unable to update installation: %w", err) } } diff --git a/pkg/kubeutils/interface.go b/pkg/kubeutils/interface.go index 12d01bf1e..729532438 100644 --- a/pkg/kubeutils/interface.go +++ b/pkg/kubeutils/interface.go @@ -36,7 +36,6 @@ type KubeUtilsInterface interface { IsDaemonsetReady(ctx context.Context, cli client.Client, ns, name string) (bool, error) IsJobComplete(ctx context.Context, cli client.Client, ns, name string, completions int32) (bool, error) WaitForKubernetes(ctx context.Context, cli client.Client) <-chan error - WaitAndMarkInstallation(ctx context.Context, cli client.Client, name string, state string) error KubeClient() (client.Client, error) } @@ -119,10 +118,6 @@ func WaitForKubernetes(ctx context.Context, cli client.Client) <-chan error { return kb.WaitForKubernetes(ctx, cli) } -func WaitAndMarkInstallation(ctx context.Context, cli client.Client, name string, state string) error { - return kb.WaitAndMarkInstallation(ctx, cli, name, state) -} - func KubeClient() (client.Client, error) { return kb.KubeClient() } diff --git a/pkg/kubeutils/kubeutils.go b/pkg/kubeutils/kubeutils.go index 3da9a855b..96833f4cd 100644 --- a/pkg/kubeutils/kubeutils.go +++ b/pkg/kubeutils/kubeutils.go @@ -2,7 +2,6 @@ package kubeutils import ( "context" - "errors" "fmt" "io" "regexp" @@ -230,44 +229,56 @@ func (k *KubeUtils) WaitForInstallation(ctx context.Context, cli client.Client, func CreateInstallation(ctx context.Context, cli client.Client, in *ecv1beta1.Installation) error { in.Spec.SourceType = ecv1beta1.InstallationSourceTypeCRD - if err := cli.Create(ctx, in); err != nil { - return fmt.Errorf("create installation: %w", err) + + if in.ObjectMeta.Labels == nil { + in.ObjectMeta.Labels = map[string]string{} } - return nil + in.ObjectMeta.Labels["replicated.com/disaster-recovery"] = "ec-install" + + return cli.Create(ctx, in) } -func UpdateInstallation(ctx context.Context, cli client.Client, in *ecv1beta1.Installation) error { - err := retry.RetryOnConflict(retry.DefaultRetry, func() error { - if err := cli.Update(ctx, in); err != nil { +func UpdateInstallation(ctx context.Context, cli client.Client, in *ecv1beta1.Installation, mutate func(in *ecv1beta1.Installation)) error { + return retry.RetryOnConflict(retry.DefaultRetry, func() error { + err := cli.Get(ctx, client.ObjectKey{Namespace: in.Namespace, Name: in.Name}, in) + if err != nil { + return fmt.Errorf("get installation before updating: %w", err) + } + + mutate(in) + + err = cli.Update(ctx, in) + if err != nil { return fmt.Errorf("update installation: %w", err) } return nil }) - if err != nil { - return fmt.Errorf("persistent conflict error, failed to update installation %s: %w", in.Name, err) - } - return nil } -func UpdateInstallationStatus(ctx context.Context, cli client.Client, in *ecv1beta1.Installation) error { - err := retry.RetryOnConflict(retry.DefaultRetry, func() error { - updatedIn := ecv1beta1.Installation{} - if err := cli.Get(ctx, types.NamespacedName{Name: in.Name, Namespace: in.Namespace}, &updatedIn); err != nil { - return fmt.Errorf("get crd installation before updating status: %w", err) +func UpdateInstallationStatus(ctx context.Context, cli client.Client, in *ecv1beta1.Installation, mutate func(status *ecv1beta1.InstallationStatus)) error { + return retry.RetryOnConflict(retry.DefaultRetry, func() error { + err := cli.Get(ctx, client.ObjectKey{Namespace: in.Namespace, Name: in.Name}, in) + if err != nil { + return fmt.Errorf("get installation before updating status: %w", err) } - updatedIn.Status = in.Status - if err := cli.Status().Update(ctx, &updatedIn); err != nil { - return fmt.Errorf("update crd installation status: %w", err) + + mutate(&in.Status) + + err = cli.Status().Update(ctx, in) + if err != nil { + return fmt.Errorf("update installation status: %w", err) } return nil }) - if err != nil { - return fmt.Errorf("persistent conflict error, failed to update installation %s status: %w", in.Name, err) - } - return nil } -func ListCRDInstallations(ctx context.Context, cli client.Client) ([]ecv1beta1.Installation, error) { +func SetInstallationState(ctx context.Context, cli client.Client, in *ecv1beta1.Installation, state string, reason string, pendingCharts ...string) error { + return UpdateInstallationStatus(ctx, cli, in, func(status *ecv1beta1.InstallationStatus) { + status.SetState(state, reason, pendingCharts) + }) +} + +func ListInstallations(ctx context.Context, cli client.Client) ([]ecv1beta1.Installation, error) { var list ecv1beta1.InstallationList err := cli.List(ctx, &list) if meta.IsNoMatchError(err) { @@ -287,7 +298,9 @@ func ListCRDInstallations(ctx context.Context, cli client.Client) ([]ecv1beta1.I return nil, fmt.Errorf("override installation data dirs: %w", err) } if didUpdate { - err := UpdateInstallation(ctx, cli, &install) + err := UpdateInstallation(ctx, cli, &install, func(in *ecv1beta1.Installation) { + in.Spec.RuntimeConfig = install.Spec.RuntimeConfig + }) if err != nil { return nil, fmt.Errorf("update installation with legacy data dirs: %w", err) } @@ -300,15 +313,6 @@ func ListCRDInstallations(ctx context.Context, cli client.Client) ([]ecv1beta1.I return installs, nil } -func ListInstallations(ctx context.Context, cli client.Client) ([]ecv1beta1.Installation, error) { - // fall back to CRD-based installations - installs, err := ListCRDInstallations(ctx, cli) - if err != nil { - return nil, err - } - return installs, nil -} - func GetInstallation(ctx context.Context, cli client.Client, name string) (*ecv1beta1.Installation, error) { installations, err := ListInstallations(ctx, cli) if err != nil { @@ -328,25 +332,6 @@ func GetInstallation(ctx context.Context, cli client.Client, name string) (*ecv1 return nil, ErrInstallationNotFound{} } -func GetCRDInstallation(ctx context.Context, cli client.Client, name string) (*ecv1beta1.Installation, error) { - installations, err := ListCRDInstallations(ctx, cli) - if err != nil { - return nil, err - } - if len(installations) == 0 { - return nil, ErrNoInstallations{} - } - - for _, installation := range installations { - if installation.Name == name { - return &installation, nil - } - } - - // if we get here, we didn't find the installation - return nil, ErrInstallationNotFound{} -} - func GetLatestInstallation(ctx context.Context, cli client.Client) (*ecv1beta1.Installation, error) { installations, err := ListInstallations(ctx, cli) if err != nil { @@ -381,27 +366,6 @@ func GetPreviousInstallation(ctx context.Context, cli client.Client, in *ecv1bet return nil, ErrInstallationNotFound{} } -// GetPreviousCRDInstallation returns the latest installation object in the cluster OTHER than the one passed as an argument. -func GetPreviousCRDInstallation(ctx context.Context, cli client.Client, in *ecv1beta1.Installation) (*ecv1beta1.Installation, error) { - installations, err := ListCRDInstallations(ctx, cli) - if err != nil { - return nil, err - } - if len(installations) == 0 { - return nil, ErrNoInstallations{} - } - - // find the first installation with a different name than the one we're upgrading to - for _, installation := range installations { - if installation.Name != in.Name { - return &installation, nil - } - } - - // if we get here, we didn't find a previous installation - return nil, ErrInstallationNotFound{} -} - var ( version115 = semver.MustParse("1.15.0") oldVersionSchemeRegex = regexp.MustCompile(`.*\+ec\.[0-9]+`) @@ -710,25 +674,6 @@ func NumOfControlPlaneNodes(ctx context.Context, cli client.Client) (int, error) return len(nodes.Items), nil } -func (k *KubeUtils) WaitAndMarkInstallation(ctx context.Context, cli client.Client, name string, state string) error { - for i := 0; i < 20; i++ { - in, err := GetInstallation(ctx, cli, name) - if err != nil { - if !errors.Is(err, ErrNoInstallations{}) { - return fmt.Errorf("unable to get installation: %w", err) - } - } else { - in.Status.State = state - if err := UpdateInstallationStatus(ctx, cli, in); err != nil { - return fmt.Errorf("unable to update installation status: %w", err) - } - return nil - } - time.Sleep(time.Second) - } - return fmt.Errorf("installation %s not found after 20 seconds", name) -} - // KubeClient returns a new kubernetes client. func (k *KubeUtils) KubeClient() (client.Client, error) { k8slogger := zap.New(func(o *zap.Options) {