diff --git a/controllers/checlusterrestore/backup_data_restorer.go b/controllers/checlusterrestore/backup_data_restorer.go index a93c3b4f4c..88034c4359 100644 --- a/controllers/checlusterrestore/backup_data_restorer.go +++ b/controllers/checlusterrestore/backup_data_restorer.go @@ -123,6 +123,9 @@ func cleanPreviousInstallation(rctx *RestoreContext, dataDir string) (bool, erro rctx.cheCR = cheCR } + // Drop databases, if any, to handle case of different Postgres version (otherwise clean Che will fail to start due to old data in volume) + dropDatabases(rctx) + // Delete Che CR to stop operator from dealing with current installation actualCheCR, cheCRCount, err := util.FindCheClusterCRInNamespace(rctx.r.cachingClient, rctx.namespace) if cheCRCount == -1 { @@ -425,6 +428,36 @@ func readBackupMetadata(rctx *RestoreContext, dataDir string) (*checlusterbackup return backupMetadata, true, nil } +// dropDatabases deletes Che related databases from Postgres, if any +func dropDatabases(rctx *RestoreContext) { + if rctx.cheCR.Spec.Database.ExternalDb { + // Skip this step as there is an external server to connect to + return + } + + databasesToDrop := []string{ + rctx.cheCR.Spec.Database.ChePostgresDb, + "keycloak", + } + + k8sClient := util.GetK8Client() + postgresPodName, err := k8sClient.GetDeploymentPod(deploy.PostgresName, rctx.namespace) + if err != nil { + // Postgres pod not found, probably it doesn't exist + return + } + + for _, dbName := range databasesToDrop { + execReason := fmt.Sprintf("dropping %s database", dbName) + dropDatabaseCommand := fmt.Sprintf("psql -c \"DROP DATABASE IF EXISTS %s;\"", dbName) + if output, err := k8sClient.DoExecIntoPod(rctx.namespace, postgresPodName, dropDatabaseCommand, execReason); err != nil { + if output != "" { + logrus.Error(output) + } + } + } +} + func restoreDatabase(rctx *RestoreContext, dataDir string) (bool, error) { if rctx.cheCR.Spec.Database.ExternalDb { // Skip database restore as there is an external server to connect to diff --git a/controllers/checlusterrestore/checlusterrestore_controller.go b/controllers/checlusterrestore/checlusterrestore_controller.go index a8391fad01..af54870dae 100644 --- a/controllers/checlusterrestore/checlusterrestore_controller.go +++ b/controllers/checlusterrestore/checlusterrestore_controller.go @@ -184,7 +184,7 @@ func (r *ReconcileCheClusterRestore) doReconcile(restoreCR *chev1.CheClusterRest } } - // Makrctxe sure, that backup server configuration in the CR is valid and cache cluster resources + // Make sure, that backup server configuration in the CR is valid and cache cluster resources done, err = rctx.backupServer.PrepareConfiguration(rctx.r.nonCachingClient, rctx.namespace) if err != nil || !done { return done, err diff --git a/pkg/deploy/migration/on-reconcile-one-time-migration.go b/pkg/deploy/migration/on-reconcile-one-time-migration.go index 8176a276c2..8bed10c84c 100644 --- a/pkg/deploy/migration/on-reconcile-one-time-migration.go +++ b/pkg/deploy/migration/on-reconcile-one-time-migration.go @@ -17,6 +17,7 @@ import ( "fmt" "time" + "github.com/eclipse-che/che-operator/controllers/checlusterbackup" "github.com/eclipse-che/che-operator/pkg/deploy" "github.com/eclipse-che/che-operator/pkg/util" routev1 "github.com/openshift/api/route/v1" @@ -214,12 +215,22 @@ func addPartOfLabelForObjectsWithInstanceCheLabel(ctx *deploy.DeployContext) err logrus.Error(getFailedToCreateSelectorErrorMessage()) return err } + // Do not migrate already migrated objects notPartOfCheSelectorRequirement, err := labels.NewRequirement(deploy.KubernetesPartOfLabelKey, selection.NotEquals, []string{deploy.CheEclipseOrg}) if err != nil { logrus.Error(getFailedToCreateSelectorErrorMessage()) return err } - objectsToMigrateLabelSelector := labels.NewSelector().Add(*instanceCheSelectorRequirement).Add(*notPartOfCheSelectorRequirement) + // Do not migrate objects related to backup/restore + notPartOfCheBackupSelectorRequirement, err := labels.NewRequirement(deploy.KubernetesPartOfLabelKey, selection.NotEquals, []string{checlusterbackup.BackupCheEclipseOrg}) + if err != nil { + logrus.Error(getFailedToCreateSelectorErrorMessage()) + return err + } + objectsToMigrateLabelSelector := labels.NewSelector(). + Add(*instanceCheSelectorRequirement). + Add(*notPartOfCheSelectorRequirement). + Add(*notPartOfCheBackupSelectorRequirement) listOptions := &client.ListOptions{ LabelSelector: objectsToMigrateLabelSelector, Namespace: ctx.CheCluster.GetNamespace(),