mirror of
https://github.com/cloudnative-pg/plugin-barman-cloud.git
synced 2026-07-09 19:22:21 +02:00
Compare commits
6 Commits
edba80c545
...
bfec61427d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfec61427d | ||
|
|
376e178ab5 | ||
|
|
25d72ce0a3 | ||
|
|
97675a7685 | ||
|
|
1eeed9f783 | ||
|
|
6ec77fb159 |
2
Makefile
2
Makefile
@ -159,7 +159,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint
|
|||||||
|
|
||||||
## Tool Versions
|
## Tool Versions
|
||||||
KUSTOMIZE_VERSION ?= v5.4.3
|
KUSTOMIZE_VERSION ?= v5.4.3
|
||||||
CONTROLLER_TOOLS_VERSION ?= v0.16.1
|
CONTROLLER_TOOLS_VERSION ?= v0.19.0
|
||||||
ENVTEST_VERSION ?= release-0.19
|
ENVTEST_VERSION ?= release-0.19
|
||||||
GOLANGCI_LINT_VERSION ?= v1.64.8
|
GOLANGCI_LINT_VERSION ?= v1.64.8
|
||||||
|
|
||||||
|
|||||||
@ -94,6 +94,9 @@ type RecoveryWindow struct {
|
|||||||
|
|
||||||
// The last failed backup time
|
// The last failed backup time
|
||||||
LastFailedBackupTime *metav1.Time `json:"lastFailedBackupTime,omitempty"`
|
LastFailedBackupTime *metav1.Time `json:"lastFailedBackupTime,omitempty"`
|
||||||
|
|
||||||
|
// The last time a WAL file was successfully archived by this plugin
|
||||||
|
LastArchivedWALTime *metav1.Time `json:"lastArchivedWALTime,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +kubebuilder:object:root=true
|
// +kubebuilder:object:root=true
|
||||||
|
|||||||
@ -169,6 +169,10 @@ func (in *RecoveryWindow) DeepCopyInto(out *RecoveryWindow) {
|
|||||||
in, out := &in.LastFailedBackupTime, &out.LastFailedBackupTime
|
in, out := &in.LastFailedBackupTime, &out.LastFailedBackupTime
|
||||||
*out = (*in).DeepCopy()
|
*out = (*in).DeepCopy()
|
||||||
}
|
}
|
||||||
|
if in.LastArchivedWALTime != nil {
|
||||||
|
in, out := &in.LastArchivedWALTime, &out.LastArchivedWALTime
|
||||||
|
*out = (*in).DeepCopy()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RecoveryWindow.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RecoveryWindow.
|
||||||
|
|||||||
@ -676,6 +676,11 @@ spec:
|
|||||||
restored.
|
restored.
|
||||||
format: date-time
|
format: date-time
|
||||||
type: string
|
type: string
|
||||||
|
lastArchivedWALTime:
|
||||||
|
description: The last time a WAL file was successfully archived
|
||||||
|
by this plugin
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
lastFailedBackupTime:
|
lastFailedBackupTime:
|
||||||
description: The last failed backup time
|
description: The last failed backup time
|
||||||
format: date-time
|
format: date-time
|
||||||
|
|||||||
6
go.mod
6
go.mod
@ -7,7 +7,7 @@ toolchain go1.26.1
|
|||||||
require (
|
require (
|
||||||
github.com/cert-manager/cert-manager v1.19.4
|
github.com/cert-manager/cert-manager v1.19.4
|
||||||
github.com/cloudnative-pg/api v1.28.1
|
github.com/cloudnative-pg/api v1.28.1
|
||||||
github.com/cloudnative-pg/barman-cloud v0.4.1-0.20260302035520-53b8620f1bd6
|
github.com/cloudnative-pg/barman-cloud v0.5.0
|
||||||
github.com/cloudnative-pg/cloudnative-pg v1.28.1
|
github.com/cloudnative-pg/cloudnative-pg v1.28.1
|
||||||
github.com/cloudnative-pg/cnpg-i v0.3.1
|
github.com/cloudnative-pg/cnpg-i v0.3.1
|
||||||
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2
|
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2
|
||||||
@ -16,7 +16,7 @@ require (
|
|||||||
github.com/onsi/gomega v1.39.1
|
github.com/onsi/gomega v1.39.1
|
||||||
github.com/spf13/cobra v1.10.2
|
github.com/spf13/cobra v1.10.2
|
||||||
github.com/spf13/viper v1.21.0
|
github.com/spf13/viper v1.21.0
|
||||||
google.golang.org/grpc v1.79.2
|
google.golang.org/grpc v1.79.3
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
k8s.io/api v0.35.2
|
k8s.io/api v0.35.2
|
||||||
k8s.io/apiextensions-apiserver v0.35.2
|
k8s.io/apiextensions-apiserver v0.35.2
|
||||||
@ -117,7 +117,7 @@ require (
|
|||||||
golang.org/x/net v0.49.0 // indirect
|
golang.org/x/net v0.49.0 // indirect
|
||||||
golang.org/x/oauth2 v0.34.0 // indirect
|
golang.org/x/oauth2 v0.34.0 // indirect
|
||||||
golang.org/x/sync v0.19.0 // indirect
|
golang.org/x/sync v0.19.0 // indirect
|
||||||
golang.org/x/sys v0.41.0 // indirect
|
golang.org/x/sys v0.42.0 // indirect
|
||||||
golang.org/x/term v0.39.0 // indirect
|
golang.org/x/term v0.39.0 // indirect
|
||||||
golang.org/x/text v0.33.0 // indirect
|
golang.org/x/text v0.33.0 // indirect
|
||||||
golang.org/x/time v0.14.0 // indirect
|
golang.org/x/time v0.14.0 // indirect
|
||||||
|
|||||||
12
go.sum
12
go.sum
@ -18,8 +18,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
|
|||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cloudnative-pg/api v1.28.1 h1:hp/TDgR+RrTa4EMp/pAKZia+kZ52i8ZPLG+JG10eeVU=
|
github.com/cloudnative-pg/api v1.28.1 h1:hp/TDgR+RrTa4EMp/pAKZia+kZ52i8ZPLG+JG10eeVU=
|
||||||
github.com/cloudnative-pg/api v1.28.1/go.mod h1:J0RTwrOYxQP17N1YMrDxcUmr/0wPYHQW179P7ibkVsM=
|
github.com/cloudnative-pg/api v1.28.1/go.mod h1:J0RTwrOYxQP17N1YMrDxcUmr/0wPYHQW179P7ibkVsM=
|
||||||
github.com/cloudnative-pg/barman-cloud v0.4.1-0.20260302035520-53b8620f1bd6 h1:BpKKrciaTMC01jMgwWOosC/S8pvDFCxZdJx2ahzksIQ=
|
github.com/cloudnative-pg/barman-cloud v0.5.0 h1:DykSaX4o7ee2vyu5FQoG1RJsntHd+EIttIKZbJPlB1Q=
|
||||||
github.com/cloudnative-pg/barman-cloud v0.4.1-0.20260302035520-53b8620f1bd6/go.mod h1:N/ax2XSnj67scfJ9iFXKxCRMLFghD9B2XX5/SrRsPys=
|
github.com/cloudnative-pg/barman-cloud v0.5.0/go.mod h1:SO2HzLa+GWlSIpGyxnISoJAFPIcaa/qDa33Bb3jefac=
|
||||||
github.com/cloudnative-pg/cloudnative-pg v1.28.1 h1:HdOUWgFhta558uHfXeO/199qCApxaj5yi05x6nWNmgs=
|
github.com/cloudnative-pg/cloudnative-pg v1.28.1 h1:HdOUWgFhta558uHfXeO/199qCApxaj5yi05x6nWNmgs=
|
||||||
github.com/cloudnative-pg/cloudnative-pg v1.28.1/go.mod h1:yhRa4GqJAjNd0tT9AiRgk1KdqLhMjo/JmGGoASRl2CU=
|
github.com/cloudnative-pg/cloudnative-pg v1.28.1/go.mod h1:yhRa4GqJAjNd0tT9AiRgk1KdqLhMjo/JmGGoASRl2CU=
|
||||||
github.com/cloudnative-pg/cnpg-i v0.3.1 h1:fKj8NoToWI11HUL2UWYJBpkVzmaTvbs3kDMo7wQF8RU=
|
github.com/cloudnative-pg/cnpg-i v0.3.1 h1:fKj8NoToWI11HUL2UWYJBpkVzmaTvbs3kDMo7wQF8RU=
|
||||||
@ -277,8 +277,8 @@ golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
|||||||
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
||||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
|
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
|
||||||
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
|
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
|
||||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||||
@ -295,8 +295,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:
|
|||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
||||||
google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU=
|
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
|
||||||
google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cloudnative-pg/barman-cloud/pkg/archiver"
|
"github.com/cloudnative-pg/barman-cloud/pkg/archiver"
|
||||||
@ -38,7 +39,10 @@ import (
|
|||||||
walUtils "github.com/cloudnative-pg/machinery/pkg/fileutils/wals"
|
walUtils "github.com/cloudnative-pg/machinery/pkg/fileutils/wals"
|
||||||
"github.com/cloudnative-pg/machinery/pkg/log"
|
"github.com/cloudnative-pg/machinery/pkg/log"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"k8s.io/client-go/util/retry"
|
||||||
|
"k8s.io/utils/ptr"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
@ -67,6 +71,11 @@ func (e *SpoolManagementError) Unwrap() error {
|
|||||||
return e.err
|
return e.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// walStatusUpdateThrottle is the minimum time between status updates for WAL archiving
|
||||||
|
walStatusUpdateThrottle = 5 * time.Minute
|
||||||
|
)
|
||||||
|
|
||||||
// WALServiceImplementation is the implementation of the WAL Service
|
// WALServiceImplementation is the implementation of the WAL Service
|
||||||
type WALServiceImplementation struct {
|
type WALServiceImplementation struct {
|
||||||
wal.UnimplementedWALServer
|
wal.UnimplementedWALServer
|
||||||
@ -75,6 +84,9 @@ type WALServiceImplementation struct {
|
|||||||
SpoolDirectory string
|
SpoolDirectory string
|
||||||
PGDataPath string
|
PGDataPath string
|
||||||
PGWALPath string
|
PGWALPath string
|
||||||
|
// LastStatusUpdate tracks the last time we updated the status for each ObjectStore+ServerName
|
||||||
|
// Key format: "namespace/objectStoreName/serverName"
|
||||||
|
LastStatusUpdate *sync.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCapabilities implements the WALService interface
|
// GetCapabilities implements the WALService interface
|
||||||
@ -102,6 +114,37 @@ func (w WALServiceImplementation) GetCapabilities(
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shouldUpdateStatus checks if we should update the status based on the throttle.
|
||||||
|
// It returns true if walStatusUpdateThrottle minutes have passed since the last update, or if this is the first update.
|
||||||
|
func (w WALServiceImplementation) shouldUpdateStatus(objectStoreKey client.ObjectKey, serverName string) bool {
|
||||||
|
if w.LastStatusUpdate == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
key := fmt.Sprintf("%s/%s", objectStoreKey.String(), serverName)
|
||||||
|
lastUpdate, ok := w.LastStatusUpdate.Load(key)
|
||||||
|
if !ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
lastUpdateTime, ok := lastUpdate.(time.Time)
|
||||||
|
if !ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return time.Since(lastUpdateTime) >= walStatusUpdateThrottle
|
||||||
|
}
|
||||||
|
|
||||||
|
// recordStatusUpdate records that we just updated the status for a given ObjectStore and server.
|
||||||
|
func (w WALServiceImplementation) recordStatusUpdate(objectStoreKey client.ObjectKey, serverName string) {
|
||||||
|
if w.LastStatusUpdate == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
key := fmt.Sprintf("%s/%s", objectStoreKey.String(), serverName)
|
||||||
|
w.LastStatusUpdate.Store(key, time.Now())
|
||||||
|
}
|
||||||
|
|
||||||
// Archive implements the WALService interface
|
// Archive implements the WALService interface
|
||||||
func (w WALServiceImplementation) Archive(
|
func (w WALServiceImplementation) Archive(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
@ -220,6 +263,28 @@ func (w WALServiceImplementation) Archive(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the last archived WAL time in the ObjectStore status
|
||||||
|
// Only update if walStatusUpdateThrottle minutes have passed since the last update to avoid hitting the API server too often
|
||||||
|
objectStoreKey := configuration.GetBarmanObjectKey()
|
||||||
|
if w.shouldUpdateStatus(objectStoreKey, configuration.ServerName) {
|
||||||
|
contextLogger.Debug("Updating last archived WAL time", "serverName", configuration.ServerName)
|
||||||
|
if err := setLastArchivedWALTime(
|
||||||
|
ctx,
|
||||||
|
w.Client,
|
||||||
|
objectStoreKey,
|
||||||
|
configuration.ServerName,
|
||||||
|
time.Now(),
|
||||||
|
); err != nil {
|
||||||
|
// Log the error but don't fail the archive operation
|
||||||
|
contextLogger.Error(err, "Error updating last archived WAL time in ObjectStore status")
|
||||||
|
} else {
|
||||||
|
contextLogger.Debug("Successfully updated last archived WAL time")
|
||||||
|
w.recordStatusUpdate(objectStoreKey, configuration.ServerName)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
contextLogger.Debug("Skipping status update due to throttle", "serverName", configuration.ServerName)
|
||||||
|
}
|
||||||
|
|
||||||
return &wal.WALArchiveResult{}, nil
|
return &wal.WALArchiveResult{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,3 +574,30 @@ func isEndOfWALStream(results []barmanRestorer.Result) bool {
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetLastArchivedWALTime sets the last archived WAL time in the
|
||||||
|
// passed object store, for the passed server name.
|
||||||
|
func setLastArchivedWALTime(
|
||||||
|
ctx context.Context,
|
||||||
|
c client.Client,
|
||||||
|
objectStoreKey client.ObjectKey,
|
||||||
|
serverName string,
|
||||||
|
lastArchivedWALTime time.Time,
|
||||||
|
) error {
|
||||||
|
return retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||||
|
var objectStore barmancloudv1.ObjectStore
|
||||||
|
|
||||||
|
if err := c.Get(ctx, objectStoreKey, &objectStore); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
recoveryWindow := objectStore.Status.ServerRecoveryWindow[serverName]
|
||||||
|
recoveryWindow.LastArchivedWALTime = ptr.To(metav1.NewTime(lastArchivedWALTime))
|
||||||
|
|
||||||
|
if objectStore.Status.ServerRecoveryWindow == nil {
|
||||||
|
objectStore.Status.ServerRecoveryWindow = make(map[string]barmancloudv1.RecoveryWindow)
|
||||||
|
}
|
||||||
|
objectStore.Status.ServerRecoveryWindow[serverName] = recoveryWindow
|
||||||
|
|
||||||
|
return c.Status().Update(ctx, &objectStore)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -51,6 +51,7 @@ var (
|
|||||||
firstRecoverabilityPointMetricName = buildFqName("first_recoverability_point")
|
firstRecoverabilityPointMetricName = buildFqName("first_recoverability_point")
|
||||||
lastAvailableBackupTimestampMetricName = buildFqName("last_available_backup_timestamp")
|
lastAvailableBackupTimestampMetricName = buildFqName("last_available_backup_timestamp")
|
||||||
lastFailedBackupTimestampMetricName = buildFqName("last_failed_backup_timestamp")
|
lastFailedBackupTimestampMetricName = buildFqName("last_failed_backup_timestamp")
|
||||||
|
lastArchivedWALTimestampMetricName = buildFqName("last_archived_wal_timestamp")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m metricsImpl) GetCapabilities(
|
func (m metricsImpl) GetCapabilities(
|
||||||
@ -97,6 +98,11 @@ func (m metricsImpl) Define(
|
|||||||
Help: "The last failed backup as a unix timestamp",
|
Help: "The last failed backup as a unix timestamp",
|
||||||
ValueType: &metrics.MetricType{Type: metrics.MetricType_TYPE_GAUGE},
|
ValueType: &metrics.MetricType{Type: metrics.MetricType_TYPE_GAUGE},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
FqName: lastArchivedWALTimestampMetricName,
|
||||||
|
Help: "The last archived WAL timestamp as a unix timestamp",
|
||||||
|
ValueType: &metrics.MetricType{Type: metrics.MetricType_TYPE_GAUGE},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -136,6 +142,10 @@ func (m metricsImpl) Collect(
|
|||||||
FqName: lastFailedBackupTimestampMetricName,
|
FqName: lastFailedBackupTimestampMetricName,
|
||||||
Value: 0,
|
Value: 0,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
FqName: lastArchivedWALTimestampMetricName,
|
||||||
|
Value: 0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -143,6 +153,7 @@ func (m metricsImpl) Collect(
|
|||||||
var firstRecoverabilityPoint float64
|
var firstRecoverabilityPoint float64
|
||||||
var lastAvailableBackup float64
|
var lastAvailableBackup float64
|
||||||
var lastFailedBackup float64
|
var lastFailedBackup float64
|
||||||
|
var lastArchivedWAL float64
|
||||||
if x.FirstRecoverabilityPoint != nil {
|
if x.FirstRecoverabilityPoint != nil {
|
||||||
firstRecoverabilityPoint = float64(x.FirstRecoverabilityPoint.Unix())
|
firstRecoverabilityPoint = float64(x.FirstRecoverabilityPoint.Unix())
|
||||||
}
|
}
|
||||||
@ -152,6 +163,9 @@ func (m metricsImpl) Collect(
|
|||||||
if x.LastFailedBackupTime != nil {
|
if x.LastFailedBackupTime != nil {
|
||||||
lastFailedBackup = float64(x.LastFailedBackupTime.Unix())
|
lastFailedBackup = float64(x.LastFailedBackupTime.Unix())
|
||||||
}
|
}
|
||||||
|
if x.LastArchivedWALTime != nil {
|
||||||
|
lastArchivedWAL = float64(x.LastArchivedWALTime.Unix())
|
||||||
|
}
|
||||||
|
|
||||||
return &metrics.CollectMetricsResult{
|
return &metrics.CollectMetricsResult{
|
||||||
Metrics: []*metrics.CollectMetric{
|
Metrics: []*metrics.CollectMetric{
|
||||||
@ -167,6 +181,10 @@ func (m metricsImpl) Collect(
|
|||||||
FqName: lastFailedBackupTimestampMetricName,
|
FqName: lastFailedBackupTimestampMetricName,
|
||||||
Value: lastFailedBackup,
|
Value: lastFailedBackup,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
FqName: lastArchivedWALTimestampMetricName,
|
||||||
|
Value: lastArchivedWAL,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,10 +22,11 @@ package instance
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
|
||||||
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||||
"k8s.io/utils/ptr"
|
"k8s.io/utils/ptr"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/cloudnative-pg/cnpg-i/pkg/metrics"
|
"github.com/cloudnative-pg/cnpg-i/pkg/metrics"
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
@ -117,7 +118,7 @@ var _ = Describe("Metrics Collect method", func() {
|
|||||||
res, err := m.Collect(ctx, req)
|
res, err := m.Collect(ctx, req)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(res).ToNot(BeNil())
|
Expect(res).ToNot(BeNil())
|
||||||
Expect(res.Metrics).To(HaveLen(3))
|
Expect(res.Metrics).To(HaveLen(4))
|
||||||
|
|
||||||
// Verify the metrics
|
// Verify the metrics
|
||||||
metricsMap := make(map[string]float64)
|
metricsMap := make(map[string]float64)
|
||||||
@ -131,6 +132,13 @@ var _ = Describe("Metrics Collect method", func() {
|
|||||||
|
|
||||||
expectedLastBackup, _ := metricsMap[lastAvailableBackupTimestampMetricName]
|
expectedLastBackup, _ := metricsMap[lastAvailableBackupTimestampMetricName]
|
||||||
Expect(expectedLastBackup).To(BeNumerically("~", float64(objectStore.Status.ServerRecoveryWindow[clusterName].LastSuccessfulBackupTime.Unix()), 1))
|
Expect(expectedLastBackup).To(BeNumerically("~", float64(objectStore.Status.ServerRecoveryWindow[clusterName].LastSuccessfulBackupTime.Unix()), 1))
|
||||||
|
|
||||||
|
// Check that unset timestamps are 0
|
||||||
|
expectedLastFailedBackup, _ := metricsMap[lastFailedBackupTimestampMetricName]
|
||||||
|
Expect(expectedLastFailedBackup).To(BeZero())
|
||||||
|
|
||||||
|
expectedLastArchivedWAL, _ := metricsMap[lastArchivedWALTimestampMetricName]
|
||||||
|
Expect(expectedLastArchivedWAL).To(BeZero())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should return an error if the object store is not found", func() {
|
It("should return an error if the object store is not found", func() {
|
||||||
|
|||||||
@ -21,6 +21,7 @@ package instance
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/http"
|
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/http"
|
||||||
"github.com/cloudnative-pg/cnpg-i/pkg/backup"
|
"github.com/cloudnative-pg/cnpg-i/pkg/backup"
|
||||||
@ -47,11 +48,12 @@ type CNPGI struct {
|
|||||||
func (c *CNPGI) Start(ctx context.Context) error {
|
func (c *CNPGI) Start(ctx context.Context) error {
|
||||||
enrich := func(server *grpc.Server) error {
|
enrich := func(server *grpc.Server) error {
|
||||||
wal.RegisterWALServer(server, common.WALServiceImplementation{
|
wal.RegisterWALServer(server, common.WALServiceImplementation{
|
||||||
InstanceName: c.InstanceName,
|
InstanceName: c.InstanceName,
|
||||||
Client: c.Client,
|
Client: c.Client,
|
||||||
SpoolDirectory: c.SpoolDirectory,
|
SpoolDirectory: c.SpoolDirectory,
|
||||||
PGDataPath: c.PGDataPath,
|
PGDataPath: c.PGDataPath,
|
||||||
PGWALPath: c.PGWALPath,
|
PGWALPath: c.PGWALPath,
|
||||||
|
LastStatusUpdate: &sync.Map{},
|
||||||
})
|
})
|
||||||
backup.RegisterBackupServer(server, BackupServiceImplementation{
|
backup.RegisterBackupServer(server, BackupServiceImplementation{
|
||||||
Client: c.Client,
|
Client: c.Client,
|
||||||
|
|||||||
@ -22,6 +22,7 @@ package restore
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"path"
|
"path"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/http"
|
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/http"
|
||||||
restore "github.com/cloudnative-pg/cnpg-i/pkg/restore/job"
|
restore "github.com/cloudnative-pg/cnpg-i/pkg/restore/job"
|
||||||
@ -49,11 +50,12 @@ func (c *CNPGI) Start(ctx context.Context) error {
|
|||||||
|
|
||||||
enrich := func(server *grpc.Server) error {
|
enrich := func(server *grpc.Server) error {
|
||||||
wal.RegisterWALServer(server, common.WALServiceImplementation{
|
wal.RegisterWALServer(server, common.WALServiceImplementation{
|
||||||
InstanceName: c.InstanceName,
|
InstanceName: c.InstanceName,
|
||||||
Client: c.Client,
|
Client: c.Client,
|
||||||
SpoolDirectory: c.SpoolDirectory,
|
SpoolDirectory: c.SpoolDirectory,
|
||||||
PGDataPath: c.PGDataPath,
|
PGDataPath: c.PGDataPath,
|
||||||
PGWALPath: path.Join(c.PGDataPath, "pg_wal"),
|
PGWALPath: path.Join(c.PGDataPath, "pg_wal"),
|
||||||
|
LastStatusUpdate: &sync.Map{},
|
||||||
})
|
})
|
||||||
|
|
||||||
restore.RegisterRestoreJobHooksServer(server, &JobHookImpl{
|
restore.RegisterRestoreJobHooksServer(server, &JobHookImpl{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user