Skip to content

Commit ba1f484

Browse files
authored
add support for migrating cometbft pvcs to hyperdisk (#3658)
Signed-off-by: Nicu Reut <nicu.reut@digitalasset.com>
1 parent c810384 commit ba1f484

File tree

6 files changed

+126
-74
lines changed

6 files changed

+126
-74
lines changed

cluster/helm/splice-cometbft/templates/deployment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ spec:
125125
# It is fine to use a persistent volume claim with a deployment instead of a stateful set,
126126
# since we are not going to scale this deployment.
127127
persistentVolumeClaim:
128-
claimName: {{ include "prefix" (list $.Values "cometbft-data") }}
128+
claimName: {{ $.Values.db.pvcName | default (include "prefix" (list $.Values "cometbft-data")) }}
129129
{{- with $.Values.nodeSelector }}
130130
nodeSelector:
131131
{{- toYaml . | nindent 8 }}

cluster/helm/splice-cometbft/templates/pvc.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
apiVersion: v1
66
kind: PersistentVolumeClaim
77
metadata:
8-
name: {{ include "prefix" (list .Values "cometbft-data") }}
8+
name: {{ .Values.db.pvcName | default (include "prefix" (list .Values "cometbft-data")) }}
99
namespace: {{ .Release.Namespace }}
1010
annotations:
1111
helm.sh/resource-policy: keep
@@ -18,4 +18,8 @@ spec:
1818
requests:
1919
storage: {{ $.Values.db.volumeSize }}
2020
storageClassName: {{ $.Values.db.volumeStorageClass }}
21+
{{- with .Values.db.dataSource }}
22+
dataSource:
23+
{{- toYaml . | nindent 4 }}
24+
{{- end }}
2125
volumeMode: Filesystem

cluster/helm/splice-cometbft/tests/cometbft_deployment_test.yaml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
suite: "cometbft deployment"
55
templates:
66
- deployment.yaml
7-
- pvc.yaml
87
release:
98
# Set for testing labels
109
name: global-domain-3
@@ -35,15 +34,18 @@ tests:
3534
- equal:
3635
path: spec.template.spec.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[0].labelSelector.matchExpressions[0].values[0]
3736
value: "cometbft"
38-
- it: "deploys a PVC"
39-
template: pvc.yaml
37+
- equal:
38+
path: spec.template.spec.volumes[4].persistentVolumeClaim.claimName
39+
value: global-domain-3-cometbft-cometbft-data
40+
- it: "uses custom pvcName in deployment when set"
41+
template: deployment.yaml
42+
set:
43+
db:
44+
pvcName: "custom-pvc-name"
4045
documentSelector:
4146
path: kind
42-
value: PersistentVolumeClaim
47+
value: Deployment
4348
asserts:
4449
- equal:
45-
path: metadata.name
46-
value: global-domain-3-cometbft-cometbft-data
47-
- equal:
48-
path: metadata.annotations["helm.sh/resource-policy"]
49-
value: keep
50+
path: spec.template.spec.volumes[4].persistentVolumeClaim.claimName
51+
value: custom-pvc-name
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
suite: "cometbft pvc"
5+
templates:
6+
- pvc.yaml
7+
release:
8+
# Set for testing labels
9+
name: global-domain-3
10+
set:
11+
node:
12+
identifier: "global-domain-3-cometbft"
13+
tests:
14+
- it: "deploys a PVC"
15+
template: pvc.yaml
16+
documentSelector:
17+
path: kind
18+
value: PersistentVolumeClaim
19+
asserts:
20+
- equal:
21+
path: metadata.name
22+
value: global-domain-3-cometbft-cometbft-data
23+
- equal:
24+
path: metadata.annotations["helm.sh/resource-policy"]
25+
value: keep
26+
- it: "uses custom pvcName in PVC when set"
27+
template: pvc.yaml
28+
set:
29+
db:
30+
pvcName: "custom-pvc-name"
31+
documentSelector:
32+
path: kind
33+
value: PersistentVolumeClaim
34+
asserts:
35+
- equal:
36+
path: metadata.name
37+
value: custom-pvc-name
38+
- it: "does not include dataSource in PVC when not set"
39+
template: pvc.yaml
40+
documentSelector:
41+
path: kind
42+
value: PersistentVolumeClaim
43+
asserts:
44+
- isNull:
45+
path: spec.dataSource
46+
- it: "includes dataSource in PVC when set"
47+
template: pvc.yaml
48+
set:
49+
db:
50+
dataSource:
51+
kind: VolumeSnapshot
52+
name: my-snapshot
53+
apiGroup: snapshot.storage.k8s.io
54+
documentSelector:
55+
path: kind
56+
value: PersistentVolumeClaim
57+
asserts:
58+
- equal:
59+
path: spec.dataSource.kind
60+
value: VolumeSnapshot
61+
- equal:
62+
path: spec.dataSource.name
63+
value: my-snapshot
64+
- equal:
65+
path: spec.dataSource.apiGroup
66+
value: snapshot.storage.k8s.io

cluster/pulumi/common-sv/src/singleSvConfig.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ const SvCometbftConfigSchema = z
2121
validatorKeyAddress: z.string().optional(),
2222
// defaults to {svName}-cometbft-keys if not set
2323
keysGcpSecret: z.string().optional(),
24-
snapshotName: z.string().optional(),
2524
resources: K8sResourceSchema,
2625
})
2726
.strict();

cluster/pulumi/common-sv/src/synchronizer/cometbft.ts

Lines changed: 43 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,30 @@
11
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
22
// SPDX-License-Identifier: Apache-2.0
3-
import * as gcp from '@pulumi/gcp';
43
import * as k8s from '@pulumi/kubernetes';
54
import * as _ from 'lodash';
65
import {
76
activeVersion,
7+
appsAffinityAndTolerations,
88
CLUSTER_BASENAME,
99
CLUSTER_HOSTNAME,
1010
clusterSmallDisk,
1111
config,
1212
DomainMigrationIndex,
1313
ExactNamespace,
14-
GCP_ZONE,
1514
InstalledHelmChart,
1615
installSpliceHelmChart,
1716
isDevNet,
1817
loadYamlFromFile,
19-
nonHyperdiskAppsAffinityAndTolerations,
2018
SPLICE_ROOT,
2119
SpliceCustomResourceOptions,
20+
standardStorageClassName,
2221
svCometBftKeysFromSecret,
2322
withAddedDependencies,
2423
} from '@lfdecentralizedtrust/splice-pulumi-common';
2524
import { CnChartVersion } from '@lfdecentralizedtrust/splice-pulumi-common/src/artifacts';
26-
import { jsonStringify, Output, Resource } from '@pulumi/pulumi';
25+
import { hyperdiskSupportConfig } from '@lfdecentralizedtrust/splice-pulumi-common/src/config/hyperdiskSupportConfig';
26+
import { CustomResource } from '@pulumi/kubernetes/apiextensions';
27+
import { jsonStringify, Output } from '@pulumi/pulumi';
2728

2829
import { svsConfig } from '../config';
2930
import { SingleSvConfiguration } from '../singleSvConfig';
@@ -104,6 +105,41 @@ export function installCometBftNode(
104105
? undefined
105106
: installCometBftKeysSecret(xns, nodeConfig.validator.keyAddress, migrationId);
106107

108+
let hyperdiskDbValues = {};
109+
if (hyperdiskSupportConfig.hyperdiskSupport.enabled) {
110+
hyperdiskDbValues = {
111+
pvcName: `cometbft-migration-${migrationId}-hd-pvc`,
112+
volumeStorageClass: standardStorageClassName,
113+
};
114+
if (hyperdiskSupportConfig.hyperdiskSupport.migrating) {
115+
const pvcSnapshot = new CustomResource(
116+
`cometbft-${xns.logicalName}-migration-${migrationId}-snapshot`,
117+
{
118+
apiVersion: 'snapshot.storage.k8s.io/v1',
119+
kind: 'VolumeSnapshot',
120+
metadata: {
121+
name: `cometbft-migration-${migrationId}-pd-snapshot`,
122+
namespace: xns.logicalName,
123+
},
124+
spec: {
125+
volumeSnapshotClassName: 'dev-vsc',
126+
source: {
127+
persistentVolumeClaimName: `global-domain-${migrationId}-cometbft-cometbft-data`,
128+
},
129+
},
130+
}
131+
);
132+
hyperdiskDbValues = {
133+
...hyperdiskDbValues,
134+
dataSource: {
135+
kind: 'VolumeSnapshot',
136+
name: pvcSnapshot.metadata.name,
137+
apiGroup: 'snapshot.storage.k8s.io',
138+
},
139+
};
140+
}
141+
}
142+
107143
const cometbftChartValues = _.mergeWith(cometBftValues, {
108144
sv1: nodeConfigs.sv1,
109145
istioVirtualService: {
@@ -138,67 +174,12 @@ export function installCometBftNode(
138174
},
139175
db: {
140176
volumeSize: clusterSmallDisk ? '240Gi' : svsConfig?.cometbft?.volumeSize,
177+
...hyperdiskDbValues,
141178
},
142179
extraLogLevelFlags: svConfiguration.logging?.cometbftExtraLogLevelFlags,
143180
serviceAccountName: imagePullServiceAccountName,
144181
resources: svConfiguration.cometbft?.resources,
145182
});
146-
const svIdentifier = nodeConfigs.selfSvNodeName;
147-
const svIdentifierWithMigration = `${svIdentifier}-m${migrationId}`;
148-
let volumeDependecies: Resource[] = [];
149-
if (svConfiguration?.cometbft?.snapshotName) {
150-
const volumeSize = cometbftChartValues.db.volumeSize;
151-
const diskSnapshot = gcp.compute.getSnapshot({
152-
name: svConfiguration.cometbft.snapshotName,
153-
});
154-
155-
if (!GCP_ZONE) {
156-
throw new Error('Zone is required to create a disk');
157-
}
158-
const restoredDisk = new gcp.compute.Disk(
159-
`${svIdentifierWithMigration}-cometbft-restored-data`,
160-
{
161-
name: `${svIdentifierWithMigration}-cometbft-restored-disk`,
162-
// eslint-disable-next-line promise/prefer-await-to-then
163-
size: diskSnapshot.then(snapshot => snapshot.diskSizeGb),
164-
// eslint-disable-next-line promise/prefer-await-to-then
165-
snapshot: diskSnapshot.then(snapshot => snapshot.selfLink),
166-
type: 'pd-ssd',
167-
zone: GCP_ZONE,
168-
},
169-
opts
170-
);
171-
172-
// create the underlying persistent volume that will be used by cometbft from the state of an existing PV
173-
volumeDependecies = [
174-
new k8s.core.v1.PersistentVolume(
175-
`${svIdentifier}-cometbft-data`,
176-
{
177-
metadata: {
178-
name: `${svIdentifier}-cometbft-data-pv`,
179-
},
180-
spec: {
181-
capacity: {
182-
storage: volumeSize,
183-
},
184-
volumeMode: 'Filesystem',
185-
accessModes: ['ReadWriteOnce'],
186-
persistentVolumeReclaimPolicy: 'Delete',
187-
storageClassName: cometbftChartValues.db.volumeStorageClass,
188-
claimRef: {
189-
name: `global-domain-${migrationId}-cometbft-cometbft-data`,
190-
namespace: xns.ns.metadata.name,
191-
},
192-
csi: {
193-
driver: 'pd.csi.storage.gke.io',
194-
volumeHandle: restoredDisk.id,
195-
},
196-
},
197-
},
198-
opts
199-
),
200-
];
201-
}
202183
const protectCometBft = svsConfig?.cometbft?.protected ?? false;
203184
const release = installSpliceHelmChart(
204185
xns,
@@ -208,13 +189,13 @@ export function installCometBftNode(
208189
version,
209190
// support old runbook names, can be removed once the runbooks are all reset and latest release is >= 0.2.x
210191
{
211-
...withAddedDependencies(opts, volumeDependecies.concat(keysSecret ? [keysSecret] : [])),
192+
...withAddedDependencies(opts, keysSecret ? [keysSecret] : []),
212193
aliases: [{ name: `global-domain-${migrationId}-cometbft`, parent: undefined }],
213194
ignoreChanges: ['name'],
214195
protect: disableProtection ? false : protectCometBft,
215196
},
216197
true,
217-
nonHyperdiskAppsAffinityAndTolerations
198+
appsAffinityAndTolerations
218199
);
219200
return { rpcServiceName: `${nodeConfig.identifier}-cometbft-rpc`, release };
220201
}

0 commit comments

Comments
 (0)