Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop databases before restore #1227

Merged
merged 1 commit into from
Dec 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions controllers/checlusterrestore/backup_data_restorer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about returning `err ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, we shouldn't break the process. This step is only needed when database format is changed.

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 12 additions & 1 deletion pkg/deploy/migration/on-reconcile-one-time-migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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(),
Expand Down