diff --git a/controllers/checlusterbackup/backup_data_collector.go b/controllers/checlusterbackup/backup_data_collector.go index 3fe1199bd..87fc24cfb 100644 --- a/controllers/checlusterbackup/backup_data_collector.go +++ b/controllers/checlusterbackup/backup_data_collector.go @@ -162,7 +162,9 @@ func backupDatabases(bctx *BackupContext, destDir string) (bool, error) { databasesToBackup := []string{ bctx.cheCR.Spec.Database.ChePostgresDb, - "keycloak", + } + if !bctx.cheCR.Spec.DevWorkspace.Enable { + databasesToBackup = append(databasesToBackup, "keycloak") } k8sClient := util.GetK8Client() diff --git a/controllers/checlusterrestore/backup_data_restorer.go b/controllers/checlusterrestore/backup_data_restorer.go index 88034c435..eb0bac74d 100644 --- a/controllers/checlusterrestore/backup_data_restorer.go +++ b/controllers/checlusterrestore/backup_data_restorer.go @@ -38,13 +38,27 @@ import ( ) func RestoreChe(rctx *RestoreContext, dataDir string) (bool, error) { - // Delete existing Che resources if any - if !rctx.state.oldCheCleaned { + // Request deletion of existing Che resources if any + if !rctx.state.oldCheDeletionRequested { done, err := cleanPreviousInstallation(rctx, dataDir) if err != nil || !done { return done, err } + rctx.state.oldCheDeletionRequested = true + if err := rctx.UpdateRestoreStatus(); err != nil { + return false, err + } + } + + // Waiting for finalizers of existing Che if any + if !rctx.state.oldCheCleaned { + done, err := waitPreviousInstallationDeleted(rctx) + if err != nil || !done { + logrus.Info("Restore: Waiting for existing Che to be deleted") + return done, err + } + rctx.state.oldCheCleaned = true if err := rctx.UpdateRestoreStatus(); err != nil { return false, err @@ -97,10 +111,12 @@ func RestoreChe(rctx *RestoreContext, dataDir string) (bool, error) { return done, err } - // After Keycloak's database restoring, it is required to restart Keycloak to invalidate its cache. - done, err = deleteKeycloakPod(rctx) - if err != nil || !done { - return done, err + if !rctx.cheCR.Spec.DevWorkspace.Enable { + // After Keycloak's database restoring, it is required to restart Keycloak to invalidate its cache. + done, err = deleteKeycloakPod(rctx) + if err != nil || !done { + return done, err + } } rctx.state.cheDatabaseRestored = true @@ -209,6 +225,19 @@ func cleanPreviousInstallation(rctx *RestoreContext, dataDir string) (bool, erro return true, nil } +func waitPreviousInstallationDeleted(rctx *RestoreContext) (bool, error) { + _, cheCRCount, err := util.FindCheClusterCRInNamespace(rctx.r.cachingClient, rctx.namespace) + if cheCRCount == -1 { + // An error occurred while retreiving CheCluster CR + return false, err + } else if cheCRCount > 0 { + // Wait more for finalizers + return false, nil + } + // Che CR is deleted + return true, nil +} + func deleteKeycloakPod(rctx *RestoreContext) (bool, error) { k8sClient := util.GetK8Client() keycloakPodName, err := k8sClient.GetDeploymentPod(deploy.IdentityProviderName, rctx.namespace) diff --git a/controllers/checlusterrestore/restore_context.go b/controllers/checlusterrestore/restore_context.go index 37046c458..fa00d72fe 100644 --- a/controllers/checlusterrestore/restore_context.go +++ b/controllers/checlusterrestore/restore_context.go @@ -75,25 +75,27 @@ func (rctx *RestoreContext) UpdateRestoreStatus() error { } type RestoreState struct { - backupDownloaded bool - oldCheCleaned bool - cheResourcesRestored bool - cheCRRestored bool - cheAvailable bool - cheDatabaseRestored bool - cheRestored bool + backupDownloaded bool + oldCheDeletionRequested bool + oldCheCleaned bool + cheResourcesRestored bool + cheCRRestored bool + cheAvailable bool + cheDatabaseRestored bool + cheRestored bool } // RestoreState phase messages // Each message represents state in progress, not done const ( - restoreStateIn_backupDownloaded = "Downloading backup from backup server" - restoreStateIn_oldCheCleaned = "Cleaning up existing Che" - restoreStateIn_cheResourcesRestored = "Restoring Che related cluster objects" - restoreStateIn_cheCRRestored = "Restoring Che Custom Resource" - restoreStateIn_cheAvailable = "Waiting until clean Che is ready" - restoreStateIn_cheDatabaseRestored = "Restoring Che database" - restoreStateIn_cheRestored = "Waiting until Che is ready" + restoreStateIn_backupDownloaded = "Downloading backup from backup server" + restoreStateIn_oldCheDeletionRequested = "Requesting deletion of existing Che" + restoreStateIn_oldCheCleaned = "Cleaning up existing Che" + restoreStateIn_cheResourcesRestored = "Restoring Che related cluster objects" + restoreStateIn_cheCRRestored = "Restoring Che Custom Resource" + restoreStateIn_cheAvailable = "Waiting until clean Che is ready" + restoreStateIn_cheDatabaseRestored = "Restoring Che database" + restoreStateIn_cheRestored = "Waiting until Che is ready" ) func (s *RestoreState) GetPhaseMessage() string { @@ -101,6 +103,9 @@ func (s *RestoreState) GetPhaseMessage() string { if !s.backupDownloaded { return restoreStateIn_backupDownloaded } + if !s.oldCheDeletionRequested { + return restoreStateIn_oldCheDeletionRequested + } if !s.oldCheCleaned { return restoreStateIn_oldCheCleaned } @@ -150,6 +155,9 @@ func NewRestoreState(restoreCR *chev1.CheClusterRestore) (*RestoreState, error) rs.oldCheCleaned = true fallthrough case restoreStateIn_oldCheCleaned: + rs.oldCheDeletionRequested = true + fallthrough + case restoreStateIn_oldCheDeletionRequested: rs.backupDownloaded = true fallthrough case restoreStateIn_backupDownloaded: