diff --git a/internal/cnpgi/common/wal.go b/internal/cnpgi/common/wal.go index 222a17b..537fa34 100644 --- a/internal/cnpgi/common/wal.go +++ b/internal/cnpgi/common/wal.go @@ -157,19 +157,13 @@ func (w WALServiceImplementation) Archive( } // Step 2: Check if the archive location is safe to perform archiving. - // The operator owns the marker file's lifecycle, so a non-nil decision - // already accounts for it and is obeyed as-is. A nil value means an - // operator that predates this field; fall back to checking the marker - // file and Cluster annotation directly. - var checkEmptyWalArchive bool - if request.CheckEmptyWalArchive != nil { - checkEmptyWalArchive = *request.CheckEmptyWalArchive - } else { - checkFileExisting, err := fileutils.FileExists(emptyWalArchiveFile) - if err != nil { - return nil, fmt.Errorf("while checking for empty wal archive check file %q: %w", emptyWalArchiveFile, err) - } - checkEmptyWalArchive = utils.IsEmptyWalArchiveCheckEnabled(&configuration.Cluster.ObjectMeta) && checkFileExisting + checkEmptyWalArchive, err := resolveArchiveEmptyWalArchiveCheck( + request.CheckEmptyWalArchive, + configuration.Cluster, + emptyWalArchiveFile, + ) + if err != nil { + return nil, err } if checkEmptyWalArchive { @@ -234,6 +228,31 @@ func (w WALServiceImplementation) Archive( return &wal.WALArchiveResult{}, nil } +// resolveArchiveEmptyWalArchiveCheck reports whether the WAL archive +// destination must be verified before archiving this segment. +// +// The operator owns the marker file's lifecycle, so when it sets the decision +// (non-nil) that value already accounts for the marker and is obeyed as-is. A +// nil value comes from an operator that predates this field, so we fall back to +// the previous logic: the Cluster annotation combined with the on-disk marker +// file. +func resolveArchiveEmptyWalArchiveCheck( + operatorDecision *bool, + cluster *cnpgv1.Cluster, + markerFilePath string, +) (bool, error) { + if operatorDecision != nil { + return *operatorDecision, nil + } + + markerFilePresent, err := fileutils.FileExists(markerFilePath) + if err != nil { + return false, fmt.Errorf("while checking for empty wal archive check file %q: %w", markerFilePath, err) + } + + return utils.IsEmptyWalArchiveCheckEnabled(&cluster.ObjectMeta) && markerFilePresent, nil +} + // Restore implements the WALService interface func (w WALServiceImplementation) Restore( ctx context.Context, diff --git a/internal/cnpgi/restore/restore.go b/internal/cnpgi/restore/restore.go index 0b46f44..9ee7354 100644 --- a/internal/cnpgi/restore/restore.go +++ b/internal/cnpgi/restore/restore.go @@ -290,24 +290,26 @@ func (impl *JobHookImpl) checkBackupDestination( } } - // Check if we're ok to restore from the desired destination. Unlike - // archiving, restore is a one-shot operation that has never been gated - // on the first-archive marker file, so the only fallback needed here - // (for an operator that predates this field) is the Cluster annotation. - var checkEmptyWalArchive bool - if operatorCheckEmptyWalArchive != nil { - checkEmptyWalArchive = *operatorCheckEmptyWalArchive - } else { - checkEmptyWalArchive = utils.IsEmptyWalArchiveCheckEnabled(&cluster.ObjectMeta) - } - - if checkEmptyWalArchive { + if resolveRestoreEmptyWalArchiveCheck(operatorCheckEmptyWalArchive, cluster) { return common.CheckBackupDestination(ctx, barmanConfiguration, walArchiver, serverName) } return nil } +// resolveRestoreEmptyWalArchiveCheck reports whether the destination must be +// verified before restoring. When the operator sets the decision (non-nil) it +// is obeyed as-is; a nil value comes from an operator that predates this field, +// so we fall back to the Cluster annotation. Unlike archiving, restore is a +// one-shot operation that has never been gated on the first-archive marker +// file, so the annotation is the only fallback needed. +func resolveRestoreEmptyWalArchiveCheck(operatorDecision *bool, cluster *cnpgv1.Cluster) bool { + if operatorDecision != nil { + return *operatorDecision + } + return utils.IsEmptyWalArchiveCheckEnabled(&cluster.ObjectMeta) +} + // restoreCustomWalDir moves the current pg_wal data to the specified custom wal dir and applies the symlink // returns indicating if any changes were made and any error encountered in the process func (impl JobHookImpl) restoreCustomWalDir(ctx context.Context) (bool, error) {