Skip to content

Commit b287164

Browse files
author
Joshua Sierles
committed
Ensure pgBackRest secret exists before starting restore job
1 parent bc0af56 commit b287164

File tree

1 file changed

+42
-64
lines changed

1 file changed

+42
-64
lines changed

internal/controller/postgrescluster/pgbackrest.go

Lines changed: 42 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,18 @@ func (r *Reconciler) reconcileRestoreJob(ctx context.Context,
11491149
dataSource *v1beta1.PostgresClusterDataSource,
11501150
instanceName, instanceSetName, configHash, stanzaName string) error {
11511151

1152+
// Check if the pgBackRest secret exists before proceeding
1153+
pgbackrestSecret := &corev1.Secret{ObjectMeta: naming.PGBackRestSecret(cluster)}
1154+
if err := r.Client.Get(ctx, client.ObjectKeyFromObject(pgbackrestSecret), pgbackrestSecret); err != nil {
1155+
if apierrors.IsNotFound(err) {
1156+
// Secret doesn't exist yet, requeue to wait for it
1157+
r.Recorder.Eventf(cluster, corev1.EventTypeNormal, "WaitingForSecret",
1158+
"Waiting for pgBackRest secret to be created before starting restore")
1159+
return errors.New("pgBackRest secret not yet available, waiting before starting restore")
1160+
}
1161+
return errors.WithStack(err)
1162+
}
1163+
11521164
repoName := dataSource.RepoName
11531165
options := dataSource.Options
11541166

@@ -1580,21 +1592,6 @@ func (r *Reconciler) reconcilePostgresClusterDataSource(ctx context.Context,
15801592
backupsSpecFound bool,
15811593
) error {
15821594

1583-
// grab cluster, namespaces and repo name information from the data source
1584-
sourceClusterName := dataSource.ClusterName
1585-
// if the data source name is empty then we're restoring in-place and use the current cluster
1586-
// as the source cluster
1587-
if sourceClusterName == "" {
1588-
sourceClusterName = cluster.GetName()
1589-
}
1590-
// if data source namespace is empty then use the same namespace as the current cluster
1591-
sourceClusterNamespace := dataSource.ClusterNamespace
1592-
if sourceClusterNamespace == "" {
1593-
sourceClusterNamespace = cluster.GetNamespace()
1594-
}
1595-
// repo name is required by the api, so RepoName should be populated
1596-
sourceRepoName := dataSource.RepoName
1597-
15981595
// Ensure the proper instance and instance set can be identified via the status. The
15991596
// StartupInstance and StartupInstanceSet values should be populated when the cluster
16001597
// is being prepared for a restore, and should therefore always exist at this point.
@@ -1644,59 +1641,40 @@ func (r *Reconciler) reconcilePostgresClusterDataSource(ctx context.Context,
16441641
return nil
16451642
}
16461643

1647-
// Identify the proper source cluster. If the source cluster configured matches the current
1648-
// cluster, then we do not need to lookup a cluster and simply copy the current PostgresCluster.
1649-
// Additionally, pgBackRest is reconciled to ensure any configuration needed to bootstrap the
1650-
// cluster exists (specifically since it may not yet exist, e.g. if we're initializing the
1651-
// data directory for a brand new PostgresCluster using existing backups for that cluster).
1652-
// If the source cluster is not the same as the current cluster, then look it up.
1653-
sourceCluster := &v1beta1.PostgresCluster{}
1654-
if sourceClusterName == cluster.GetName() && sourceClusterNamespace == cluster.GetNamespace() {
1655-
sourceCluster = cluster.DeepCopy()
1656-
instance := &Instance{Name: instanceName}
1657-
// Reconciling pgBackRest here will ensure a pgBackRest instance config file exists (since
1658-
// the cluster hasn't bootstrapped yet, and pgBackRest configs therefore have not yet been
1659-
// reconciled) as needed to properly configure the pgBackRest restore Job.
1660-
// Note that function reconcilePGBackRest only uses forCluster in observedInstances.
1661-
result, err := r.reconcilePGBackRest(ctx, cluster, &observedInstances{
1662-
forCluster: []*Instance{instance},
1663-
}, rootCA, backupsSpecFound)
1664-
if err != nil || result != (reconcile.Result{}) {
1665-
return fmt.Errorf("unable to reconcile pgBackRest as needed to initialize "+
1666-
"PostgreSQL data for the cluster: %w", err)
1667-
}
1668-
} else {
1669-
if err := r.Client.Get(ctx,
1670-
client.ObjectKey{Name: sourceClusterName, Namespace: sourceClusterNamespace},
1671-
sourceCluster); err != nil {
1672-
if apierrors.IsNotFound(err) {
1673-
r.Recorder.Eventf(cluster, corev1.EventTypeWarning, "InvalidDataSource",
1674-
"PostgresCluster %q does not exist", sourceClusterName)
1675-
return nil
1676-
}
1677-
return errors.WithStack(err)
1678-
}
1644+
// First, create the restore configuration and ensure secrets exist
1645+
// before proceeding with other operations
1646+
if err := r.createRestoreConfig(ctx, cluster, configHash); err != nil {
1647+
return err
1648+
}
16791649

1680-
// Copy repository definitions and credentials from the source cluster.
1681-
// A copy is the only way to get this information across namespaces.
1682-
if err := r.copyRestoreConfiguration(ctx, cluster, sourceCluster); err != nil {
1683-
return err
1684-
}
1650+
// Create a fake StatefulSet for reconciling the PGBackRest secret
1651+
fakeRepoHost := &appsv1.StatefulSet{
1652+
ObjectMeta: metav1.ObjectMeta{
1653+
Name: cluster.Name + "-repo-host",
1654+
Namespace: cluster.Namespace,
1655+
},
16851656
}
16861657

1687-
// verify the repo defined in the data source exists in the source cluster
1688-
var foundRepo bool
1689-
for _, repo := range sourceCluster.Spec.Backups.PGBackRest.Repos {
1690-
if repo.Name == sourceRepoName {
1691-
foundRepo = true
1692-
break
1693-
}
1658+
// Ensure the PGBackRest secret exists
1659+
if err := r.reconcilePGBackRestSecret(ctx, cluster, fakeRepoHost, rootCA); err != nil {
1660+
return err
16941661
}
1695-
if !foundRepo {
1696-
r.Recorder.Eventf(cluster, corev1.EventTypeWarning, "InvalidDataSource",
1697-
"PostgresCluster %q does not have a repo named %q defined",
1698-
sourceClusterName, sourceRepoName)
1699-
return nil
1662+
1663+
// Now proceed with volumes and other resources for the restore
1664+
sourceCluster := &v1beta1.PostgresCluster{}
1665+
if dataSource.ClusterName != "" && dataSource.ClusterNamespace != "" {
1666+
if err := r.Client.Get(ctx, types.NamespacedName{
1667+
Name: dataSource.ClusterName,
1668+
Namespace: dataSource.ClusterNamespace,
1669+
}, sourceCluster); err != nil {
1670+
// If source is not found, proceed with the restore using nil for sourceCluster
1671+
if !apierrors.IsNotFound(err) {
1672+
return errors.WithStack(err)
1673+
}
1674+
sourceCluster = nil
1675+
}
1676+
} else {
1677+
sourceCluster = nil
17001678
}
17011679

17021680
// Define a fake STS to use when calling the reconcile functions below since when

0 commit comments

Comments
 (0)