Compare commits

...

6 Commits

Author SHA1 Message Date
simonapencea
bfec61427d
Merge 97675a7685 into 376e178ab5 2026-03-27 12:14:32 -07:00
renovate[bot]
376e178ab5
fix(deps): update module google.golang.org/grpc to v1.79.3 [security] (#819)
Some checks failed
release-please / release-please (push) Failing after 5s
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [google.golang.org/grpc](https://redirect.github.com/grpc/grpc-go) |
`v1.79.2` → `v1.79.3` |
![age](https://developer.mend.io/api/mc/badges/age/go/google.golang.org%2fgrpc/v1.79.3?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/go/google.golang.org%2fgrpc/v1.79.2/v1.79.3?slim=true)
|

### GitHub Vulnerability Alerts

####
[CVE-2026-33186](https://redirect.github.com/grpc/grpc-go/security/advisories/GHSA-p77j-4mvh-x3m3)

### Impact
_What kind of vulnerability is it? Who is impacted?_

It is an **Authorization Bypass** resulting from **Improper Input
Validation** of the HTTP/2 `:path` pseudo-header.

The gRPC-Go server was too lenient in its routing logic, accepting
requests where the `:path` omitted the mandatory leading slash (e.g.,
`Service/Method` instead of `/Service/Method`). While the server
successfully routed these requests to the correct handler, authorization
interceptors (including the official `grpc/authz` package) evaluated the
raw, non-canonical path string. Consequently, "deny" rules defined using
canonical paths (starting with `/`) failed to match the incoming
request, allowing it to bypass the policy if a fallback "allow" rule was
present.

**Who is impacted?**
This affects gRPC-Go servers that meet both of the following criteria:
1. They use path-based authorization interceptors, such as the official
RBAC implementation in `google.golang.org/grpc/authz` or custom
interceptors relying on `info.FullMethod` or `grpc.Method(ctx)`.
2. Their security policy contains specific "deny" rules for canonical
paths but allows other requests by default (a fallback "allow" rule).

The vulnerability is exploitable by an attacker who can send raw HTTP/2
frames with malformed `:path` headers directly to the gRPC server.

### Patches
_Has the problem been patched? What versions should users upgrade to?_

Yes, the issue has been patched. The fix ensures that any request with a
`:path` that does not start with a leading slash is immediately rejected
with a `codes.Unimplemented` error, preventing it from reaching
authorization interceptors or handlers with a non-canonical path string.

Users should upgrade to the following versions (or newer):
* **v1.79.3**
* The latest **master** branch.

It is recommended that all users employing path-based authorization
(especially `grpc/authz`) upgrade as soon as the patch is available in a
tagged release.

### Workarounds
_Is there a way for users to fix or remediate the vulnerability without
upgrading?_

While upgrading is the most secure and recommended path, users can
mitigate the vulnerability using one of the following methods:

#### 1. Use a Validating Interceptor (Recommended Mitigation)
Add an "outermost" interceptor to your server that validates the path
before any other authorization logic runs:

```go
func pathValidationInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
    if info.FullMethod == "" || info.FullMethod[0] != '/' {
        return nil, status.Errorf(codes.Unimplemented, "malformed method name")
    }   
    return handler(ctx, req)
}

// Ensure this is the FIRST interceptor in your chain
s := grpc.NewServer(
    grpc.ChainUnaryInterceptor(pathValidationInterceptor, authzInterceptor),
)
```

#### 2. Infrastructure-Level Normalization
If your gRPC server is behind a reverse proxy or load balancer (such as
Envoy, NGINX, or an L7 Cloud Load Balancer), ensure it is configured to
enforce strict HTTP/2 compliance for pseudo-headers and reject or
normalize requests where the `:path` header does not start with a
leading slash.

#### 3. Policy Hardening
Switch to a "default deny" posture in your authorization policies
(explicitly listing all allowed paths and denying everything else) to
reduce the risk of bypasses via malformed inputs.

---

### Release Notes

<details>
<summary>grpc/grpc-go (google.golang.org/grpc)</summary>

###
[`v1.79.3`](https://redirect.github.com/grpc/grpc-go/releases/tag/v1.79.3):
Release 1.79.3

[Compare
Source](https://redirect.github.com/grpc/grpc-go/compare/v1.79.2...v1.79.3)

### Security

- server: fix an authorization bypass where malformed :path headers
(missing the leading slash) could bypass path-based restricted "deny"
rules in interceptors like `grpc/authz`. Any request with a
non-canonical path is now immediately rejected with an `Unimplemented`
error.
([#&#8203;8981](https://redirect.github.com/grpc/grpc-go/issues/8981))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "" (UTC), Automerge - At any time (no
schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/cloudnative-pg/plugin-barman-cloud).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My42Ni40IiwidXBkYXRlZEluVmVyIjoiNDMuNjYuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYXV0b21hdGVkIiwibm8taXNzdWUiXX0=-->

Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-19 09:42:16 +01:00
Marco Nenciarini
25d72ce0a3
fix(restore): race condition in parallel WAL restore spool (#812)
Some checks failed
release-please / release-please (push) Failing after 3s
Update github.com/cloudnative-pg/barman-cloud from the pre-release pin
(ced266c) to the official v0.5.0 release.

This update fixes a race condition in parallel WAL restore where
prefetched files could be read while still being downloaded, causing
PostgreSQL recovery to fail with "invalid checkpoint record" errors. It
also fixes a misleading "missing Azure credentials" error message when
no object store credentials are defined at all.

Signed-off-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
2026-03-17 15:50:02 +01:00
simonapencea
97675a7685
Merge branch 'main' into add-last-wal-arch-time 2025-11-25 12:23:24 +02:00
Simona Pencea
1eeed9f783 fix: throttle updates to lastwalarchtime to 5min
Signed-off-by: Simona Pencea <simona@xata.io>
2025-11-25 11:21:22 +01:00
Simona Pencea
6ec77fb159 feat: add lastarchivedwaltime to the recoverywindow
Signed-off-by: Simona Pencea <simona@xata.io>
2025-11-12 13:09:50 +01:00
11 changed files with 156 additions and 22 deletions

View File

@ -159,7 +159,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint
## Tool Versions
KUSTOMIZE_VERSION ?= v5.4.3
CONTROLLER_TOOLS_VERSION ?= v0.16.1
CONTROLLER_TOOLS_VERSION ?= v0.19.0
ENVTEST_VERSION ?= release-0.19
GOLANGCI_LINT_VERSION ?= v1.64.8

View File

@ -94,6 +94,9 @@ type RecoveryWindow struct {
// The last failed backup time
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

View File

@ -169,6 +169,10 @@ func (in *RecoveryWindow) DeepCopyInto(out *RecoveryWindow) {
in, out := &in.LastFailedBackupTime, &out.LastFailedBackupTime
*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.

View File

@ -676,6 +676,11 @@ spec:
restored.
format: date-time
type: string
lastArchivedWALTime:
description: The last time a WAL file was successfully archived
by this plugin
format: date-time
type: string
lastFailedBackupTime:
description: The last failed backup time
format: date-time

6
go.mod
View File

@ -7,7 +7,7 @@ toolchain go1.26.1
require (
github.com/cert-manager/cert-manager v1.19.4
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/cnpg-i v0.3.1
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2
@ -16,7 +16,7 @@ require (
github.com/onsi/gomega v1.39.1
github.com/spf13/cobra v1.10.2
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
k8s.io/api 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/oauth2 v0.34.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/text v0.33.0 // indirect
golang.org/x/time v0.14.0 // indirect

12
go.sum
View File

@ -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/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/barman-cloud v0.4.1-0.20260302035520-53b8620f1bd6 h1:BpKKrciaTMC01jMgwWOosC/S8pvDFCxZdJx2ahzksIQ=
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 h1:DykSaX4o7ee2vyu5FQoG1RJsntHd+EIttIKZbJPlB1Q=
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/go.mod h1:yhRa4GqJAjNd0tT9AiRgk1KdqLhMjo/JmGGoASRl2CU=
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/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
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.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
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/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
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/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/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU=
google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
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/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -25,6 +25,7 @@ import (
"fmt"
"os"
"path"
"sync"
"time"
"github.com/cloudnative-pg/barman-cloud/pkg/archiver"
@ -38,7 +39,10 @@ import (
walUtils "github.com/cloudnative-pg/machinery/pkg/fileutils/wals"
"github.com/cloudnative-pg/machinery/pkg/log"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/util/retry"
"k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
@ -67,6 +71,11 @@ func (e *SpoolManagementError) Unwrap() error {
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
type WALServiceImplementation struct {
wal.UnimplementedWALServer
@ -75,6 +84,9 @@ type WALServiceImplementation struct {
SpoolDirectory string
PGDataPath 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
@ -102,6 +114,37 @@ func (w WALServiceImplementation) GetCapabilities(
}, 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
func (w WALServiceImplementation) Archive(
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
}
@ -509,3 +574,30 @@ func isEndOfWALStream(results []barmanRestorer.Result) bool {
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)
})
}

View File

@ -51,6 +51,7 @@ var (
firstRecoverabilityPointMetricName = buildFqName("first_recoverability_point")
lastAvailableBackupTimestampMetricName = buildFqName("last_available_backup_timestamp")
lastFailedBackupTimestampMetricName = buildFqName("last_failed_backup_timestamp")
lastArchivedWALTimestampMetricName = buildFqName("last_archived_wal_timestamp")
)
func (m metricsImpl) GetCapabilities(
@ -97,6 +98,11 @@ func (m metricsImpl) Define(
Help: "The last failed backup as a unix timestamp",
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
}
@ -136,6 +142,10 @@ func (m metricsImpl) Collect(
FqName: lastFailedBackupTimestampMetricName,
Value: 0,
},
{
FqName: lastArchivedWALTimestampMetricName,
Value: 0,
},
},
}, nil
}
@ -143,6 +153,7 @@ func (m metricsImpl) Collect(
var firstRecoverabilityPoint float64
var lastAvailableBackup float64
var lastFailedBackup float64
var lastArchivedWAL float64
if x.FirstRecoverabilityPoint != nil {
firstRecoverabilityPoint = float64(x.FirstRecoverabilityPoint.Unix())
}
@ -152,6 +163,9 @@ func (m metricsImpl) Collect(
if x.LastFailedBackupTime != nil {
lastFailedBackup = float64(x.LastFailedBackupTime.Unix())
}
if x.LastArchivedWALTime != nil {
lastArchivedWAL = float64(x.LastArchivedWALTime.Unix())
}
return &metrics.CollectMetricsResult{
Metrics: []*metrics.CollectMetric{
@ -167,6 +181,10 @@ func (m metricsImpl) Collect(
FqName: lastFailedBackupTimestampMetricName,
Value: lastFailedBackup,
},
{
FqName: lastArchivedWALTimestampMetricName,
Value: lastArchivedWAL,
},
},
}, nil
}

View File

@ -22,10 +22,11 @@ package instance
import (
"context"
"encoding/json"
"time"
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
"k8s.io/utils/ptr"
"time"
"github.com/cloudnative-pg/cnpg-i/pkg/metrics"
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)
Expect(err).ToNot(HaveOccurred())
Expect(res).ToNot(BeNil())
Expect(res.Metrics).To(HaveLen(3))
Expect(res.Metrics).To(HaveLen(4))
// Verify the metrics
metricsMap := make(map[string]float64)
@ -131,6 +132,13 @@ var _ = Describe("Metrics Collect method", func() {
expectedLastBackup, _ := metricsMap[lastAvailableBackupTimestampMetricName]
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() {

View File

@ -21,6 +21,7 @@ package instance
import (
"context"
"sync"
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/http"
"github.com/cloudnative-pg/cnpg-i/pkg/backup"
@ -52,6 +53,7 @@ func (c *CNPGI) Start(ctx context.Context) error {
SpoolDirectory: c.SpoolDirectory,
PGDataPath: c.PGDataPath,
PGWALPath: c.PGWALPath,
LastStatusUpdate: &sync.Map{},
})
backup.RegisterBackupServer(server, BackupServiceImplementation{
Client: c.Client,

View File

@ -22,6 +22,7 @@ package restore
import (
"context"
"path"
"sync"
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/http"
restore "github.com/cloudnative-pg/cnpg-i/pkg/restore/job"
@ -54,6 +55,7 @@ func (c *CNPGI) Start(ctx context.Context) error {
SpoolDirectory: c.SpoolDirectory,
PGDataPath: c.PGDataPath,
PGWALPath: path.Join(c.PGDataPath, "pg_wal"),
LastStatusUpdate: &sync.Map{},
})
restore.RegisterRestoreJobHooksServer(server, &JobHookImpl{