Skip to content

Commit c89a042

Browse files
fix: enhance profile manager to take mirror node component overrides to increase pipeline stability (#289)
Signed-off-by: Jeromy Cannon <[email protected]>
1 parent 4dad9d1 commit c89a042

File tree

6 files changed

+82
-41
lines changed

6 files changed

+82
-41
lines changed

package-lock.json

Lines changed: 22 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"@peculiar/x509": "^1.9.7",
4343
"adm-zip": "^0.5.12",
4444
"chalk": "^5.3.0",
45+
"dot-object": "^2.1.5",
4546
"dotenv": "^16.4.5",
4647
"enquirer": "^2.4.1",
4748
"esm": "^3.2.25",

resources/profiles/custom-spec.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ local: # 3 nodes, ~950 TPS (Docker Desktop 8 cores, 16 GB RAM)
4545
limits:
4646
cpu: 500m
4747
memory: 500Mi
48+
readinessProbe:
49+
failureThreshold: 60
50+
livenessProbe:
51+
failureThreshold: 60
4852
grpc:
4953
resources:
5054
requests:
@@ -53,6 +57,10 @@ local: # 3 nodes, ~950 TPS (Docker Desktop 8 cores, 16 GB RAM)
5357
limits:
5458
cpu: 500m
5559
memory: 1000Mi
60+
readinessProbe:
61+
failureThreshold: 60
62+
livenessProbe:
63+
failureThreshold: 60
5664
web3:
5765
resources:
5866
requests:
@@ -61,6 +69,10 @@ local: # 3 nodes, ~950 TPS (Docker Desktop 8 cores, 16 GB RAM)
6169
limits:
6270
cpu: 500m
6371
memory: 500Mi
72+
readinessProbe:
73+
failureThreshold: 60
74+
livenessProbe:
75+
failureThreshold: 60
6476
monitor:
6577
resources:
6678
requests:

src/core/profile_manager.mjs

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@ import { FullstackTestingError, IllegalArgumentError, MissingArgumentError } fro
2020
import * as yaml from 'js-yaml'
2121
import { flags } from '../commands/index.mjs'
2222
import { constants, helpers } from './index.mjs'
23+
import dot from 'dot-object'
2324

24-
const resourceRequestTypes = ['requests', 'limits']
25-
const hardwareTypes = ['cpu', 'memory']
2625
const consensusSidecars = [
2726
'recordStreamUploader', 'eventStreamUploader', 'backupUploader', 'accountBalanceUploader', 'otelCollector']
2827

@@ -126,27 +125,22 @@ export class ProfileManager {
126125
}
127126

128127
/**
129-
* Set resources for the chart
130-
* @param itemPath item path in the yaml
131-
* @param itemResources item resources object
132-
* @param yamlRoot root of the yaml object
128+
* Set items for the chart
129+
* @param itemPath item path in the yaml, if empty then root of the yaml object will be used
130+
* @param items the element object
131+
* @param yamlRoot root of the yaml object to update
133132
* @private
134133
*/
135-
_setChartResources (itemPath, itemResources, yamlRoot) {
136-
if (!itemResources || !itemResources.resources) return
137-
138-
for (const resourceRequestType of resourceRequestTypes) {
139-
if (itemResources && itemResources.resources[resourceRequestType]) {
140-
const resources = itemResources.resources[resourceRequestType]
141-
for (const hardware of hardwareTypes) {
142-
if (resources[hardware] !== undefined) {
143-
if (itemPath) {
144-
this._setValue(`${itemPath}.resources.${resourceRequestType}.${hardware}`, resources[hardware], yamlRoot)
145-
} else {
146-
this._setValue(`resources.${resourceRequestType}.${hardware}`, resources[hardware], yamlRoot)
147-
}
148-
}
149-
}
134+
_setChartItems (itemPath, items, yamlRoot) {
135+
if (!items) return
136+
137+
const dotItems = dot.dot(items)
138+
139+
for (const key in dotItems) {
140+
if (itemPath) {
141+
this._setValue(`${itemPath}.${key}`, dotItems[key], yamlRoot)
142+
} else {
143+
this._setValue(key, dotItems[key], yamlRoot)
150144
}
151145
}
152146
}
@@ -163,16 +157,16 @@ export class ProfileManager {
163157
for (let nodeIndex = 0; nodeIndex < nodeIds.length; nodeIndex++) {
164158
this._setValue(`hedera.nodes.${nodeIndex}.name`, nodeIds[nodeIndex], yamlRoot)
165159
this._setValue(`hedera.nodes.${nodeIndex}.accountId`, `${realm}.${shard}.${accountId++}`, yamlRoot)
166-
this._setChartResources(`hedera.nodes.${nodeIndex}`, profile.consensus, yamlRoot)
160+
this._setChartItems(`hedera.nodes.${nodeIndex}`, profile.consensus, yamlRoot)
167161
}
168162

169163
if (profile.consensus) {
170164
// set default for consensus pod
171-
this._setChartResources('defaults.root', profile.consensus.root, yamlRoot)
165+
this._setChartItems('defaults.root', profile.consensus.root, yamlRoot)
172166

173167
// set sidecar resources
174168
for (const sidecar of consensusSidecars) {
175-
this._setChartResources(`defaults.sidecars.${sidecar}`, profile.consensus[sidecar], yamlRoot)
169+
this._setChartItems(`defaults.sidecars.${sidecar}`, profile.consensus[sidecar], yamlRoot)
176170
}
177171
}
178172

@@ -183,19 +177,19 @@ export class ProfileManager {
183177
if (!profile) throw new MissingArgumentError('profile is required')
184178
if (!profile.haproxy) return // use chart defaults
185179

186-
return this._setChartResources('defaults.haproxy', profile.haproxy, yamlRoot)
180+
return this._setChartItems('defaults.haproxy', profile.haproxy, yamlRoot)
187181
}
188182

189183
resourcesForEnvoyProxyPod (profile, yamlRoot) {
190184
if (!profile) throw new MissingArgumentError('profile is required')
191185
if (!profile.envoyProxy) return // use chart defaults
192-
return this._setChartResources('defaults.envoyProxy', profile.envoyProxy, yamlRoot)
186+
return this._setChartItems('defaults.envoyProxy', profile.envoyProxy, yamlRoot)
193187
}
194188

195189
resourcesForHederaExplorerPod (profile, yamlRoot) {
196190
if (!profile) throw new MissingArgumentError('profile is required')
197191
if (!profile.explorer) return
198-
return this._setChartResources('hedera-explorer', profile.explorer, yamlRoot)
192+
return this._setChartItems('hedera-explorer', profile.explorer, yamlRoot)
199193
}
200194

201195
resourcesForMinioTenantPod (profile, yamlRoot) {
@@ -210,7 +204,7 @@ export class ProfileManager {
210204
}
211205
}
212206

213-
this._setChartResources(`minio-server.tenant.pools.${poolIndex}`, pool, yamlRoot)
207+
this._setChartItems(`minio-server.tenant.pools.${poolIndex}`, pool, yamlRoot)
214208
}
215209

216210
return yamlRoot
@@ -260,7 +254,7 @@ export class ProfileManager {
260254

261255
// generate the yaml
262256
const yamlRoot = {}
263-
this._setChartResources('', profile.rpcRelay, yamlRoot)
257+
this._setChartItems('', profile.rpcRelay, yamlRoot)
264258

265259
// write the yaml
266260
const cachedValuesFile = path.join(this.cacheDir, `rpcRelay-${profileName}.yaml`)
@@ -292,14 +286,14 @@ export class ProfileManager {
292286
this._setValue('hedera-mirror-node.postgresql.persistence.size', profile.mirror.postgresql.persistence.size, yamlRoot)
293287
}
294288

295-
this._setChartResources('hedera-mirror-node.postgresql.postgresql', profile.mirror.postgresql.postgresql, yamlRoot)
289+
this._setChartItems('hedera-mirror-node.postgresql.postgresql', profile.mirror.postgresql.postgresql, yamlRoot)
296290
}
297291

298-
this._setChartResources('hedera-mirror-node.importer', profile.mirror.importer, yamlRoot)
299-
this._setChartResources('hedera-mirror-node.rest', profile.mirror.rest, yamlRoot)
300-
this._setChartResources('hedera-mirror-node.web3', profile.mirror.web3, yamlRoot)
301-
this._setChartResources('hedera-mirror-node.grpc', profile.mirror.grpc, yamlRoot)
302-
this._setChartResources('hedera-mirror-node.monitor', profile.mirror.monitor, yamlRoot)
292+
this._setChartItems('hedera-mirror-node.importer', profile.mirror.importer, yamlRoot)
293+
this._setChartItems('hedera-mirror-node.rest', profile.mirror.rest, yamlRoot)
294+
this._setChartItems('hedera-mirror-node.web3', profile.mirror.web3, yamlRoot)
295+
this._setChartItems('hedera-mirror-node.grpc', profile.mirror.grpc, yamlRoot)
296+
this._setChartItems('hedera-mirror-node.monitor', profile.mirror.monitor, yamlRoot)
303297
this.resourcesForHederaExplorerPod(profile, yamlRoot)
304298

305299
// write the yaml

test/data/test-profiles.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ test:
100100
limits:
101101
cpu: 250m
102102
memory: 1000Mi
103+
readinessProbe:
104+
failureThreshold: 60
105+
livenessProbe:
106+
failureThreshold: 60
103107
rest:
104108
resources:
105109
requests:
@@ -108,6 +112,10 @@ test:
108112
limits:
109113
cpu: 250m
110114
memory: 500Mi
115+
readinessProbe:
116+
failureThreshold: 60
117+
livenessProbe:
118+
failureThreshold: 60
111119
grpc:
112120
resources:
113121
requests:
@@ -116,6 +124,10 @@ test:
116124
limits:
117125
cpu: 250m
118126
memory: 500Mi
127+
readinessProbe:
128+
failureThreshold: 60
129+
livenessProbe:
130+
failureThreshold: 60
119131
web3:
120132
resources:
121133
requests:
@@ -124,6 +136,10 @@ test:
124136
limits:
125137
cpu: 250m
126138
memory: 500Mi
139+
readinessProbe:
140+
failureThreshold: 60
141+
livenessProbe:
142+
failureThreshold: 60
127143
monitor:
128144
resources:
129145
requests:

test/unit/core/profile_manager.test.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ describe('ProfileManager', () => {
105105
for (const component of ['grpc', 'rest', 'web3', 'importer']) {
106106
expect(valuesYaml['hedera-mirror-node'][component].resources.limits.cpu).not.toBeNull()
107107
expect(valuesYaml['hedera-mirror-node'][component].resources.limits.memory).not.toBeNull()
108+
expect(valuesYaml['hedera-mirror-node'][component].readinessProbe.failureThreshold).toEqual(60)
109+
expect(valuesYaml['hedera-mirror-node'][component].livenessProbe.failureThreshold).toEqual(60)
108110
}
109111
expect(valuesYaml['hedera-explorer'].resources.limits.cpu).not.toBeNull()
110112
expect(valuesYaml['hedera-explorer'].resources.limits.memory).not.toBeNull()

0 commit comments

Comments
 (0)