mirror of
https://github.com/cozystack/cozystack.git
synced 2026-10-25 12:37:06 +09:00
A restore sets bootstrap.enabled on the target app, which skips the init-job, so the recovered roles keep the source's password hashes while the target's credentials Secret holds generated ones and every application login fails. Once recovery converges, the driver records RecoveryConverged and then clears bootstrap.enabled, so the next HelmRelease reconcile runs the init-job and applies the passwords. Ready carries RestoreCompletedCredentialsPending and an Event says the convergence is still pending. A clear that keeps failing is retried under BootstrapDisablePending within a fixed grace window after convergence and then fails the restore. bootstrap.enabled is serialized without omitempty so the patch sends false instead of dropping the key. Running the init-job on a restored cluster exposes its delete pass to a catalog the spec does not describe: the driver sets spec.databases to the Backup's snapshot, but recovery replays WAL past it, so a database created after the Backup comes back still marked as managed and would be dropped with its data. The first run after a restore, told apart by the per-RestoreJob bootstrap.newServerName that the cluster has not yet recorded, releases such a database and its roles from management instead, and the run records the value once every pass has succeeded. Signed-off-by: Alexey Artamonov <aleksei.artamonov@aenix.io>
42 lines
1.6 KiB
Go
42 lines
1.6 KiB
Go
package backupcontroller
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
|
|
"github.com/cozystack/cozystack/internal/backupcontroller/postgresapp"
|
|
)
|
|
|
|
// disablePostgresAppBootstrap flips Bootstrap.Enabled from true to false through
|
|
// a client.MergeFrom merge patch. If the field keeps `json:"...,omitempty"`, the
|
|
// false zero value is dropped from the patched object, so the computed merge
|
|
// patch DELETES the key (`{"enabled":null}`) instead of setting it false — the
|
|
// exact trap the sibling Backup.UseSystemBucket field carries a comment against.
|
|
// It only converges today because the chart default for bootstrap.enabled is
|
|
// false; if that ever changes the restore reports Succeeded while recovery stays
|
|
// wedged. Pin that the wire patch sets enabled:false. Re-adding omitempty to the
|
|
// Enabled field turns this red.
|
|
func TestDisableBootstrapMergePatchSetsEnabledFalse(t *testing.T) {
|
|
app := &postgresapp.Postgres{
|
|
ObjectMeta: metav1.ObjectMeta{Name: "pg-target", Namespace: "tenant-root"},
|
|
}
|
|
app.Spec.Bootstrap.Enabled = true
|
|
|
|
patched := app.DeepCopy()
|
|
patched.Spec.Bootstrap.Enabled = false
|
|
|
|
data, err := client.MergeFrom(app).Data(patched)
|
|
if err != nil {
|
|
t.Fatalf("build merge patch: %v", err)
|
|
}
|
|
if bytes.Contains(data, []byte(`"enabled":null`)) {
|
|
t.Fatalf("merge patch deletes the enabled key instead of setting false; the server would fall back to a default: %s", data)
|
|
}
|
|
if !bytes.Contains(data, []byte(`"enabled":false`)) {
|
|
t.Fatalf("merge patch must carry enabled:false so the server clears bootstrap; got: %s", data)
|
|
}
|
|
}
|