mirror of
https://github.com/cloudnative-pg/plugin-barman-cloud.git
synced 2026-01-11 13:23:09 +01:00
This commit makes the Barman cloud plugin support the enforcement of retention policy as provided by the barman-cloud tool suite. The first recoverability point and the last successful backup are shown in the status of the ObjectStore resource for each involved server name. Signed-off-by: Leonardo Cecchi <leonardo.cecchi@enterprisedb.com> Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com> Signed-off-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com> Co-authored-by: Armando Ruocco <armando.ruocco@enterprisedb.com> Co-authored-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
152 lines
4.7 KiB
Go
152 lines
4.7 KiB
Go
package instance
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
barmanBackup "github.com/cloudnative-pg/barman-cloud/pkg/backup"
|
|
barmanCapabilities "github.com/cloudnative-pg/barman-cloud/pkg/capabilities"
|
|
barmanCredentials "github.com/cloudnative-pg/barman-cloud/pkg/credentials"
|
|
"github.com/cloudnative-pg/cloudnative-pg/pkg/postgres"
|
|
"github.com/cloudnative-pg/cnpg-i/pkg/backup"
|
|
"github.com/cloudnative-pg/machinery/pkg/fileutils"
|
|
"github.com/cloudnative-pg/machinery/pkg/log"
|
|
pgTime "github.com/cloudnative-pg/machinery/pkg/postgres/time"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
|
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/common"
|
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
|
)
|
|
|
|
// BackupServiceImplementation is the implementation
|
|
// of the Backup CNPG capability
|
|
type BackupServiceImplementation struct {
|
|
Client client.Client
|
|
InstanceName string
|
|
backup.UnimplementedBackupServer
|
|
}
|
|
|
|
// This is an implementation of the barman executor
|
|
// that always instruct the barman library to use the
|
|
// "--name" option for backups. We don't support old
|
|
// Barman versions that do not implement that option.
|
|
type barmanCloudExecutor struct{}
|
|
|
|
func (barmanCloudExecutor) ShouldForceLegacyBackup() bool {
|
|
return false
|
|
}
|
|
|
|
// GetCapabilities implements the BackupService interface
|
|
func (b BackupServiceImplementation) GetCapabilities(
|
|
_ context.Context, _ *backup.BackupCapabilitiesRequest,
|
|
) (*backup.BackupCapabilitiesResult, error) {
|
|
return &backup.BackupCapabilitiesResult{
|
|
Capabilities: []*backup.BackupCapability{
|
|
{
|
|
Type: &backup.BackupCapability_Rpc{
|
|
Rpc: &backup.BackupCapability_RPC{
|
|
Type: backup.BackupCapability_RPC_TYPE_BACKUP,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// Backup implements the Backup interface
|
|
func (b BackupServiceImplementation) Backup(
|
|
ctx context.Context,
|
|
request *backup.BackupRequest,
|
|
) (*backup.BackupResult, error) {
|
|
contextLogger := log.FromContext(ctx)
|
|
|
|
contextLogger.Info("Starting backup")
|
|
|
|
configuration, err := config.NewFromClusterJSON(request.ClusterDefinition)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var objectStore barmancloudv1.ObjectStore
|
|
if err := b.Client.Get(ctx, configuration.GetBarmanObjectKey(), &objectStore); err != nil {
|
|
contextLogger.Error(err, "while getting object store", "key", configuration.GetRecoveryBarmanObjectKey())
|
|
return nil, err
|
|
}
|
|
|
|
if err := fileutils.EnsureDirectoryExists(postgres.BackupTemporaryDirectory); err != nil {
|
|
contextLogger.Error(err, "Cannot create backup temporary directory", "err", err)
|
|
return nil, err
|
|
}
|
|
|
|
capabilities, err := barmanCapabilities.CurrentCapabilities()
|
|
if err != nil {
|
|
contextLogger.Error(err, "while getting capabilities")
|
|
return nil, err
|
|
}
|
|
backupCmd := barmanBackup.NewBackupCommand(
|
|
&objectStore.Spec.Configuration,
|
|
capabilities,
|
|
)
|
|
|
|
// We need to connect to PostgreSQL and to do that we need
|
|
// PGHOST (and the like) to be available
|
|
osEnvironment := os.Environ()
|
|
caBundleEnvironment := common.GetRestoreCABundleEnv(&objectStore.Spec.Configuration)
|
|
env, err := barmanCredentials.EnvSetCloudCredentialsAndCertificates(
|
|
ctx,
|
|
b.Client,
|
|
objectStore.Namespace,
|
|
&objectStore.Spec.Configuration,
|
|
common.MergeEnv(osEnvironment, caBundleEnvironment),
|
|
common.BuildCertificateFilePath(objectStore.Name),
|
|
)
|
|
if err != nil {
|
|
contextLogger.Error(err, "while setting backup cloud credentials")
|
|
return nil, err
|
|
}
|
|
|
|
backupName := fmt.Sprintf("backup-%v", pgTime.ToCompactISO8601(time.Now()))
|
|
|
|
if err = backupCmd.Take(
|
|
ctx,
|
|
backupName,
|
|
configuration.ServerName,
|
|
env,
|
|
barmanCloudExecutor{},
|
|
postgres.BackupTemporaryDirectory,
|
|
); err != nil {
|
|
contextLogger.Error(err, "while taking backup")
|
|
return nil, err
|
|
}
|
|
|
|
executedBackupInfo, err := backupCmd.GetExecutedBackupInfo(
|
|
ctx,
|
|
backupName,
|
|
configuration.ServerName,
|
|
barmanCloudExecutor{},
|
|
env)
|
|
if err != nil {
|
|
contextLogger.Error(err, "while getting executed backup info")
|
|
return nil, err
|
|
}
|
|
|
|
contextLogger.Info("Backup completed", "backup", executedBackupInfo.ID)
|
|
return &backup.BackupResult{
|
|
BackupId: executedBackupInfo.ID,
|
|
BackupName: executedBackupInfo.BackupName,
|
|
StartedAt: metav1.Time{Time: executedBackupInfo.BeginTime}.Unix(),
|
|
StoppedAt: metav1.Time{Time: executedBackupInfo.EndTime}.Unix(),
|
|
BeginWal: executedBackupInfo.BeginWal,
|
|
EndWal: executedBackupInfo.EndWal,
|
|
BeginLsn: executedBackupInfo.BeginLSN,
|
|
EndLsn: executedBackupInfo.EndLSN,
|
|
InstanceId: b.InstanceName,
|
|
Online: true,
|
|
Metadata: newBackupResultMetadata(configuration.Cluster.ObjectMeta.UID, executedBackupInfo.TimeLine).toMap(),
|
|
}, nil
|
|
}
|