Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions base/audit_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,11 @@ const (
AuditIDSyncGatewayProfiling AuditID = 53304

// SG cluster events
AuditIDClusterInfoRead AuditID = 53350
AuditIDPostUpgrade AuditID = 54043
AuditIDClusterInfoRead AuditID = 53350
AuditIDClusterCompatVersionRead AuditID = 53351
AuditIDClusterCompatVersionFreeze AuditID = 53352
AuditIDClusterCompatVersionUnfreeze AuditID = 53353
AuditIDPostUpgrade AuditID = 54043

// Database events
AuditIDCreateDatabase AuditID = 54000
Expand Down Expand Up @@ -464,6 +467,38 @@ var AuditEvents = events{
EventType: eventTypeAdmin,
IsGlobalEvent: true,
},
AuditIDClusterCompatVersionRead: {
Name: "Sync Gateway cluster compatibility version read",
Description: "Sync Gateway cluster compatibility version was viewed",
EnabledByDefault: true,
FilteringPermitted: true,
EventType: eventTypeAdmin,
IsGlobalEvent: true,
},
AuditIDClusterCompatVersionFreeze: {
Name: "Sync Gateway cluster compatibility version frozen",
Description: "An admin pinned the Sync Gateway cluster compatibility version to its current value",
MandatoryFields: AuditFields{
AuditFieldClusterCompatVersion: "4.1",
AuditFieldFrozenAt: "2026-01-02T15:04:05Z",
},
EnabledByDefault: true,
FilteringPermitted: true,
EventType: eventTypeAdmin,
IsGlobalEvent: true,
},
AuditIDClusterCompatVersionUnfreeze: {
Name: "Sync Gateway cluster compatibility version unfrozen",
Description: "An admin cleared the Sync Gateway cluster compatibility version freeze. The cluster_compat_version and frozen_at fields describe the freeze record that was lifted (when it was originally set), not the time of the unfreeze action.",
OptionalFields: AuditFields{
AuditFieldClusterCompatVersion: "4.1",
AuditFieldFrozenAt: "2026-01-02T15:04:05Z",
},
EnabledByDefault: true,
FilteringPermitted: true,
EventType: eventTypeAdmin,
IsGlobalEvent: true,
},
AuditIDCreateDatabase: {
Name: "Create database",
Description: "A new database was created",
Expand Down
4 changes: 4 additions & 0 deletions base/audit_events_fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,8 @@ const (
AuditFieldDocIDs = "doc_ids"
AuditFieldFeedType = "feed_type"
AuditFieldIncludeDocs = "include_docs"

// Cluster compat version freeze events 53352, 53353
AuditFieldClusterCompatVersion = "cluster_compat_version"
AuditFieldFrozenAt = "frozen_at"
)
8 changes: 8 additions & 0 deletions base/version_cluster_compat.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ type RegistryNode struct {
Databases map[string]string `json:"databases,omitempty"`
}

// RegistryFreeze records an admin-issued cluster compatibility version freeze stored in a
// bucket registry. When present, the cluster compatibility version reported by Sync Gateway is
// pinned to Version, preventing it from advancing as nodes are upgraded.
type RegistryFreeze struct {
Version ClusterCompatVersion `json:"version"`
FrozenAt time.Time `json:"frozen_at"`
}

// ParseClusterCompatVersion parses a "major.minor" string into a ClusterCompatVersion.
func ParseClusterCompatVersion(s string) (ClusterCompatVersion, error) {
parts := strings.SplitN(s, ".", 2)
Expand Down
6 changes: 6 additions & 0 deletions docs/api/admin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ paths:
$ref: ./paths/admin/_config.yaml
/_cluster_info:
$ref: ./paths/admin/_cluster_info.yaml
/_cluster_compat_version:
$ref: ./paths/admin/_cluster_compat_version.yaml
/_cluster_compat_version/freeze:
$ref: ./paths/admin/_cluster_compat_version-freeze.yaml
/_cluster_compat_version/unfreeze:
$ref: ./paths/admin/_cluster_compat_version-unfreeze.yaml
/_status:
$ref: ./paths/admin/_status.yaml
/_sgcollect_info:
Expand Down
67 changes: 67 additions & 0 deletions docs/api/components/schemas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3356,6 +3356,44 @@ ClusterCompatVersion:
nullable: true
example: '4.1'
title: Cluster Compatibility Version
ClusterCompatVersionState:
type: object
description: |-
Cluster compatibility version state.

Without a freeze, `cluster_compat_version` is the minimum version across all live nodes
in the cluster, and advances automatically as nodes are upgraded.

A freeze pins `cluster_compat_version` to the value captured at the time of the freeze,
preventing it from advancing as nodes upgrade. This preserves the option to roll a node
back to the prior major/minor before committing to the upgrade.

The presence of `frozen_cluster_compat_version` indicates that a frozen version is currently set;
its absence indicates no version has been frozen.
properties:
cluster_compat_version:
allOf:
- $ref: '#/ClusterCompatVersion'
description: |-
The currently-reported cluster compatibility version. Equal to
`frozen_cluster_compat_version` when a freeze is set, otherwise the minimum across
all live nodes. Omitted if no version has been computed yet (e.g. immediately after
startup, before any node has registered).
nodes:
type: object
description: |-
Per-node cluster compatibility versions, keyed by node UID. Includes every node
currently registered in any tracked bucket registry.
additionalProperties:
x-additionalPropertiesName: nodeUID
$ref: '#/ClusterCompatVersion'
frozen_cluster_compat_version:
allOf:
- $ref: '#/ClusterCompatVersion'
description: |-
The cluster compatibility version captured at the time of the most recent freeze.
Omitted when no freeze is set.
title: Cluster Compatibility Version State
DiagnosticFunctionException:
description: The exception thrown during evaluation (if any).
type: string
Expand Down Expand Up @@ -3445,6 +3483,14 @@ GatewayRegistry:
additionalProperties:
x-additionalPropertiesName: nodeUID
$ref: '#/RegistryNode'
frozen_cluster_compat_version:
allOf:
- $ref: '#/RegistryFrozenClusterCompatVersion'
description: |-
Cluster compatibility version freeze record. When present, the
cluster compatibility version reported by this Sync Gateway is capped at
`frozen_cluster_compat_version.version` until the freeze is cleared via
`POST /_cluster_compat_version/unfreeze`.

RegistryNode:
type: object
Expand All @@ -3459,6 +3505,27 @@ RegistryNode:
format: date-time
description: Time of the node's last heartbeat write to this registry.

RegistryFrozenClusterCompatVersion:
type: object
description: |-
A cluster compatibility version freeze record stored in a bucket registry. Set by
`POST /_cluster_compat_version/freeze` and cleared by
`POST /_cluster_compat_version/unfreeze`. Cluster-wide freeze state is the aggregate of
these records across all bucket registries.
properties:
version:
allOf:
- $ref: '#/ClusterCompatVersion'
description: |-
The cluster compatibility version captured at the time of the freeze.
frozen_at:
type: string
format: date-time
description: Time at which the freeze was set.
required:
- version
- frozen_at

RegistryConfigGroup:
type: object
properties:
Expand Down
53 changes: 53 additions & 0 deletions docs/api/paths/admin/_cluster_compat_version-freeze.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright 2026-Present Couchbase, Inc.
#
# Use of this software is governed by the Business Source License included
# in the file licenses/BSL-Couchbase.txt. As of the Change Date specified
# in that file, in accordance with the Business Source License, use of this
# software will be governed by the Apache License, Version 2.0, included in
# the file licenses/APL2.txt.
post:
summary: Freeze the cluster compatibility version at its current value
description: |-
Captures the current cluster compatibility version and pins the cluster to this version.

While frozen, subsequent node upgrades will not advance the reported `cluster_compat_version`, preserving the option to roll a node back to the prior major/minor.

Returns success only if every tracked bucket accepts the freeze.
If one or more buckets fail to accept it, a `503` is returned with the current state — the cluster compatibility version may still be partially pinned, and the request should be retried.

To clear the pinned version, call `POST /_cluster_compat_version/unfreeze`.

Required Sync Gateway RBAC roles:

* Sync Gateway Dev Ops
responses:
'200':
description: Cluster compatibility version has been frozen
content:
application/json:
schema:
$ref: ../../components/schemas.yaml#/ClusterCompatVersionState
'403':
$ref: ../../components/responses.yaml#/Unauthorized
Comment thread
bbrks marked this conversation as resolved.
'500':
description: An unexpected error occurred while freezing the cluster compatibility version
content:
application/json:
schema:
$ref: ../../components/schemas.yaml#/HTTP-Error
'503':
description: |-
The freeze could not be fully applied. Possible reasons:
* Cluster compatibility version tracking is not enabled on this node.
* The cluster compatibility version has not yet been computed (e.g. immediately after startup).
* No tracked bucket registries.
* One or more tracked buckets did not accept the freeze (partial failure). In this case the response body is a `ClusterCompatVersionState` describing the version (if any) that is currently pinned, so the admin can see what did take effect.
content:
application/json:
schema:
oneOf:
- $ref: ../../components/schemas.yaml#/HTTP-Error
- $ref: ../../components/schemas.yaml#/ClusterCompatVersionState
tags:
- Server
operationId: post__cluster_compat_version_freeze
52 changes: 52 additions & 0 deletions docs/api/paths/admin/_cluster_compat_version-unfreeze.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright 2026-Present Couchbase, Inc.
#
# Use of this software is governed by the Business Source License included
# in the file licenses/BSL-Couchbase.txt. As of the Change Date specified
# in that file, in accordance with the Business Source License, use of this
# software will be governed by the Apache License, Version 2.0, included in
# the file licenses/APL2.txt.
post:
summary: Clear the cluster compatibility version freeze
description: |-
Clears any pinned cluster compatibility version previously frozen via `POST /_cluster_compat_version/freeze`.

The reported `cluster_compat_version` will resume tracking the live-node minimum and may immediately advance if all nodes have been upgraded since the freeze was set.

Returns success only if the cluster is fully unfrozen.
If any part of the cluster remains frozen after the request, a `503` is returned with the current state -
the cluster compatibility version may still be held back, and the request should be retried.

Required Sync Gateway RBAC roles:

* Sync Gateway Dev Ops
responses:
'200':
description: Cluster compatibility version freeze has been cleared
content:
application/json:
schema:
$ref: ../../components/schemas.yaml#/ClusterCompatVersionState
'403':
$ref: ../../components/responses.yaml#/Unauthorized
'500':
description: An unexpected error occurred while clearing the cluster compatibility version freeze
content:
application/json:
schema:
$ref: ../../components/schemas.yaml#/HTTP-Error
'503':
description: |-
The unfreeze did not fully apply. The cluster compatibility version may still be held back
and the request should be retried. The response body is either a `ClusterCompatVersionState`
showing the residual freeze, or an `HTTP-Error` when cluster compatibility version tracking
is not enabled on this node, or when the unfreeze partially failed and the residual freeze
state could not be verified.
content:
application/json:
schema:
oneOf:
- $ref: ../../components/schemas.yaml#/ClusterCompatVersionState
- $ref: ../../components/schemas.yaml#/HTTP-Error
tags:
- Server
operationId: post__cluster_compat_version_unfreeze
38 changes: 38 additions & 0 deletions docs/api/paths/admin/_cluster_compat_version.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright 2026-Present Couchbase, Inc.
#
# Use of this software is governed by the Business Source License included
# in the file licenses/BSL-Couchbase.txt. As of the Change Date specified
# in that file, in accordance with the Business Source License, use of this
# software will be governed by the Apache License, Version 2.0, included in
# the file licenses/APL2.txt.
get:
summary: Get the cluster compatibility version state
description: |-
Returns the cluster-wide cluster compatibility version, the per-node versions registered
in the cluster, and the frozen value if a freeze is currently in effect.

Without a freeze, `cluster_compat_version` is the minimum across all live nodes. With a
freeze, `cluster_compat_version` is pinned to `frozen_cluster_compat_version`. The
presence of `frozen_cluster_compat_version` in the response indicates that a freeze is set.

Required Sync Gateway RBAC roles:

* Sync Gateway Dev Ops
responses:
'200':
description: Returned the cluster compatibility version state successfully
content:
application/json:
schema:
$ref: ../../components/schemas.yaml#/ClusterCompatVersionState
'403':
$ref: ../../components/responses.yaml#/Unauthorized
'503':
description: Cluster compatibility version tracking is not enabled on this node
content:
application/json:
schema:
$ref: ../../components/schemas.yaml#/HTTP-Error
Comment thread
bbrks marked this conversation as resolved.
tags:
- Server
operationId: get__cluster_compat_version
Loading
Loading