Skip to content

Delete NovaCell cr only when deletion job pass #917

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

Merged
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
6 changes: 6 additions & 0 deletions controllers/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -732,3 +732,9 @@ func ensureMemcached(

return memcached, err
}

func sortNovaCellListByName(cellList *novav1.NovaCellList) {
sort.SliceStable(cellList.Items, func(i, j int) bool {
return cellList.Items[i].Name < cellList.Items[j].Name
})
}
Copy link
Contributor

Choose a reason for hiding this comment

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

sure, though I do have this move added here with a test specific to sorting
https://github.com/openstack-k8s-operators/nova-operator/pull/940/files

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I did this like 5 day ago after rebase https://github.com/openstack-k8s-operators/nova-operator/compare/99a98e8e08ca4e49c4569aac778a58c423649c81..2b3cf8c0f7981a1d1d9418052411109164ef6b30 . This PR is going for quite long time so I didn't want to wait on any other pr

Copy link
Contributor

@auniyal61 auniyal61 Mar 19, 2025

Choose a reason for hiding this comment

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

sure, as this may merge first, lets use this.

53 changes: 26 additions & 27 deletions controllers/nova_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"context"
"errors"
"fmt"
"sort"
"strings"

batchv1 "k8s.io/api/batch/v1"
Expand Down Expand Up @@ -602,26 +601,20 @@ func (r *NovaReconciler) Reconcile(ctx context.Context, req ctrl.Request) (resul
return ctrl.Result{}, err
}

sortNovaCellListByName := func(cellList *novav1.NovaCellList) {
sort.SliceStable(cellList.Items, func(i, j int) bool {
return cellList.Items[i].Name < cellList.Items[j].Name
})
}

sortNovaCellListByName(novaCellList)

var deleteErrs []error

for _, cr := range novaCellList.Items {
_, ok := instance.Spec.CellTemplates[cr.Spec.CellName]
if !ok {
err := r.ensureCellDeleted(ctx, h, instance,
result, err := r.ensureCellDeleted(ctx, h, instance,
cr.Spec.CellName, apiTransportURL,
secret, apiDB, cellDBs[novav1.Cell0Name].Database.GetDatabaseHostname(), cells[novav1.Cell0Name])
if err != nil {
deleteErrs = append(deleteErrs, fmt.Errorf("Cell '%s' deletion failed, because: %w", cr.Spec.CellName, err))

} else {
}
if result == nova.CellDeleteComplete {
Log.Info("Cell deleted", "cell", cr.Spec.CellName)
delete(instance.Status.RegisteredCells, cr.Name)
}
Expand Down Expand Up @@ -687,7 +680,7 @@ func (r *NovaReconciler) ensureCellDeleted(
apiDB *mariadbv1.Database,
APIDatabaseHostname string,
cell0 *novav1.NovaCell,
) error {
) (nova.CellDeploymentStatus, error) {
Log := r.GetLogger(ctx)
cell := &novav1.NovaCell{}
fullCellName := types.NamespacedName{
Expand All @@ -700,29 +693,29 @@ func (r *NovaReconciler) ensureCellDeleted(
// We cannot do further cleanup of the MariaDBDatabase and
// MariaDBAccount as their name is only available in the NovaCell CR
// since the cell definition is removed from the Nova CR already.
return nil
return nova.CellDeleteComplete, nil
}
if err != nil {
return err
return nova.CellDeleteFailed, err
}
// If it is not created by us, we don't touch it
if !OwnedBy(cell, instance) {
Log.Info("Cell isn't defined in the Nova, but there is a "+
"Cell CR not owned by us. Not deleting it.",
"cell", cell)
return nil
return nova.CellDeleteComplete, nil
}

dbName, accountName := novaapi.ServiceName+"-"+cell.Spec.CellName, cell.Spec.CellDatabaseAccount

configHash, scriptName, configName, err := r.ensureNovaManageJobSecret(ctx, h, instance,
cell0, topLevelSecret, APIDatabaseHostname, apiTransportURL, apiDB)
if err != nil {
return err
return nova.CellDeleteFailed, err
}
inputHash, err := util.HashOfInputHashes(configHash)
if err != nil {
return err
return nova.CellDeleteFailed, err
}

labels := map[string]string{
Expand All @@ -734,24 +727,30 @@ func (r *NovaReconciler) ensureCellDeleted(
instance.Spec.PreserveJobs, r.RequeueTimeout,
inputHash)

_, err = job.DoJob(ctx, h)
result, err := job.DoJob(ctx, h)
if err != nil {
return err
return nova.CellDeleteFailed, err
}

if (result != ctrl.Result{}) {
// Job is still running. We can simply return as we will be reconciled
// when the Job status changes
return nova.CellDeleteInProgress, nil
}

secretName := getNovaCellCRName(instance.Name, cellName)
err = secret.DeleteSecretsWithName(ctx, h, secretName, instance.Namespace)
if err != nil && !k8s_errors.IsNotFound(err) {
return err
return nova.CellDeleteFailed, err
}
configSecret, scriptSecret := r.getNovaManageJobSecretNames(cell)
err = secret.DeleteSecretsWithName(ctx, h, configSecret, instance.Namespace)
if err != nil && !k8s_errors.IsNotFound(err) {
return err
return nova.CellDeleteFailed, err
}
err = secret.DeleteSecretsWithName(ctx, h, scriptSecret, instance.Namespace)
if err != nil && !k8s_errors.IsNotFound(err) {
return err
return nova.CellDeleteFailed, err
}

// Delete transportURL cr
Expand All @@ -763,18 +762,18 @@ func (r *NovaReconciler) ensureCellDeleted(
}
err = r.Client.Delete(ctx, transportURL)
if err != nil && !k8s_errors.IsNotFound(err) {
return err
return nova.CellDeleteFailed, err
}

err = mariadbv1.DeleteDatabaseAndAccountFinalizers(
ctx, h, dbName, accountName, instance.Namespace)
if err != nil {
return err
return nova.CellDeleteFailed, err
}

err = r.ensureAccountDeletedIfOwned(ctx, h, instance, accountName)
if err != nil {
return err
return nova.CellDeleteFailed, err
}

database := &mariadbv1.MariaDBDatabase{
Expand All @@ -785,7 +784,7 @@ func (r *NovaReconciler) ensureCellDeleted(
}
err = r.Client.Delete(ctx, database)
if err != nil && !k8s_errors.IsNotFound(err) {
return err
return nova.CellDeleteFailed, err
}
Log.Info("Deleted MariaDBDatabase", "database", database)

Expand All @@ -794,11 +793,11 @@ func (r *NovaReconciler) ensureCellDeleted(
// what to clean up.
err = r.Client.Delete(ctx, cell)
if err != nil && k8s_errors.IsNotFound(err) {
return err
return nova.CellDeleteFailed, err
}

Log.Info("Cell isn't defined in the Nova CR, so it is deleted", "cell", cell)
return nil
return nova.CellDeleteComplete, nil
}

func (r *NovaReconciler) initStatus(
Expand Down
6 changes: 6 additions & 0 deletions pkg/nova/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ const (
// CellComputeDiscoveryReady indicates that all NovaComputes in cell reached the Ready status and
// the hosts in the cell have been successfully discovered
CellComputeDiscoveryReady CellDeploymentStatus = iota
// CellDeleteInProgress indicates that the NovaCell deletion is in progress
CellDeleteInProgress CellDeploymentStatus = iota
// CellDeleteFailed indicates that the NovaCell deletion failed
CellDeleteFailed CellDeploymentStatus = iota
// CellDeleteComplete indicates that the NovaCell deletion is complete
CellDeleteComplete CellDeploymentStatus = iota
)

// Database -
Expand Down
2 changes: 2 additions & 0 deletions test/functional/nova_multicell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,8 @@ var _ = Describe("Nova multi cell deletion", func() {
g.Expect(k8sClient.Update(ctx, nova)).To(Succeed())
}, timeout, interval).Should(Succeed())

th.SimulateJobSuccess(cell2.CellDeleteJobName)
th.SimulateJobSuccess(cell3.CellDeleteJobName)
Copy link
Contributor

Choose a reason for hiding this comment

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

+1

Eventually(func(g Gomega) {
nova := GetNova(novaNames.NovaName)
g.Expect(nova.Status.RegisteredCells).To(HaveKey(cell2.CellCRName.Name))
Expand Down
22 changes: 16 additions & 6 deletions test/functional/nova_reconfiguration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,18 +178,28 @@ var _ = Describe("Nova reconfiguration", func() {
g.Expect(k8sClient.Update(ctx, nova)).To(Succeed())
}, timeout, interval).Should(Succeed())

Eventually(func(g Gomega) {
nova := GetNova(novaNames.NovaName)
g.Expect(nova.Status.RegisteredCells).NotTo(HaveKey(cell1.CellCRName.Name))
}, timeout, interval).Should(Succeed())

NovaCellNotExists(cell1.CellCRName)
Eventually(func(g Gomega) {
mappingJob := th.GetJob(cell1.CellDeleteJobName)
newJobInputHash := GetEnvVarValue(
mappingJob.Spec.Template.Spec.Containers[0].Env, "INPUT_HASH", "")
g.Expect(newJobInputHash).NotTo(BeNil())
}, timeout, interval).Should(Succeed())

// Check that the cell status is not deleted
Consistently(func(g Gomega) {
nova := GetNova(novaNames.NovaName)
g.Expect(nova.Status.RegisteredCells).To(HaveKey(cell1.CellCRName.Name))
}, timeout, interval).Should(Succeed())
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: you can put a GetNovaCell(cell1.CellCRName) into the Consistently block as well to show that NovaCell/cell1 is not deleted until the Job succeeds.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks will fix with other patch touching statuses


// Simulate the cell delete job success
th.SimulateJobSuccess(cell1.CellDeleteJobName)
Eventually(func(g Gomega) {
nova := GetNova(novaNames.NovaName)
g.Expect(nova.Status.RegisteredCells).NotTo(HaveKey(cell1.CellCRName.Name))
}, timeout, interval).Should(Succeed())

NovaCellNotExists(cell1.CellCRName)

th.AssertSecretDoesNotExist(cell1.InternalCellSecretName)

Eventually(func(g Gomega) {
Expand Down