diff --git a/src/commands/flags.mjs b/src/commands/flags.mjs index cc4f290a2..a9bb67466 100644 --- a/src/commands/flags.mjs +++ b/src/commands/flags.mjs @@ -755,6 +755,16 @@ export const adminKey = { } } +/** @type {CommandFlag} **/ +export const mirrorNodeVersion = { + constName: 'mirrorNodeVersion', + name: 'mirror-node-version', + definition: { + describe: 'Mirror node chart version', + defaultValue: '', + type: 'string' + } +} /** @type {CommandFlag[]} **/ export const allFlags = [ accountId, @@ -815,7 +825,8 @@ export const allFlags = [ tlsPrivateKey, tlsPublicKey, updateAccountKeys, - valuesFile + valuesFile, + mirrorNodeVersion ] /** diff --git a/src/commands/mirror_node.mjs b/src/commands/mirror_node.mjs index 87fa0d358..498fc4d0a 100644 --- a/src/commands/mirror_node.mjs +++ b/src/commands/mirror_node.mjs @@ -60,7 +60,8 @@ export class MirrorNodeCommand extends BaseCommand { flags.profileFile, flags.profileName, flags.tlsClusterIssuerType, - flags.valuesFile + flags.valuesFile, + flags.mirrorNodeVersion ] } @@ -118,6 +119,10 @@ export class MirrorNodeCommand extends BaseCommand { config.hederaExplorerTlsLoadBalancerIp, config.hederaExplorerTlsHostName) } + if (config.mirrorNodeVersion) { + valuesArg += ` --set global.image.tag=${config.mirrorNodeVersion}` + } + valuesArg += ` --set hedera-mirror-node.enabled=true --set hedera-explorer.enabled=${config.deployHederaExplorer}` if (config.valuesFile) { @@ -149,7 +154,8 @@ export class MirrorNodeCommand extends BaseCommand { flags.hederaExplorerTlsHostName, flags.hederaExplorerTlsLoadBalancerIp, flags.tlsClusterIssuerType, - flags.valuesFile + flags.valuesFile, + flags.mirrorNodeVersion ]) await prompts.execute(task, self.configManager, MirrorNodeCommand.DEPLOY_FLAGS_LIST) @@ -171,6 +177,7 @@ export class MirrorNodeCommand extends BaseCommand { * -- extra args -- * @property {string} chartPath * @property {string} valuesArg + * @property {string} mirrorNodeVersion * -- methods -- * @property {getUnusedConfigs} getUnusedConfigs */ diff --git a/src/commands/prompts.mjs b/src/commands/prompts.mjs index 59cdcc838..69c134b26 100644 --- a/src/commands/prompts.mjs +++ b/src/commands/prompts.mjs @@ -421,6 +421,14 @@ export async function promptPersistentVolumeClaims (task, input) { flags.persistentVolumeClaims.name) } +export async function promptMirrorNodeVersion (task, input) { + return await promptToggle(task, input, + flags.mirrorNodeVersion.definition.defaultValue, + 'Would you like to choose mirror node version? ', + null, + flags.mirrorNodeVersion.name) +} + /** * @returns {Map} */ @@ -464,6 +472,7 @@ export function getPromptMap () { .set(flags.gossipEndpoints.name, promptGossipEndpoints) .set(flags.grpcEndpoints.name, promptGrpcEndpoints) .set(flags.endpointType.name, promptEndpointType) + .set(flags.mirrorNodeVersion.name, promptMirrorNodeVersion) } // build the prompt registry diff --git a/src/core/chart_manager.mjs b/src/core/chart_manager.mjs index f97c8bb20..a6cbc2bf6 100644 --- a/src/core/chart_manager.mjs +++ b/src/core/chart_manager.mjs @@ -39,28 +39,36 @@ export class ChartManager { * * @param {Map} repoURLs - a map of name and chart repository URLs * @param {boolean} force - whether or not to update the repo - * @returns {Promise} + * @returns {Promise} - returns the urls */ async setup (repoURLs = constants.DEFAULT_CHART_REPO, force = true) { try { - let forceUpdateArg = '' - if (force) { - forceUpdateArg = '--force-update' - } + const forceUpdateArg = force ? '--force-update' : '' - const urls = [] + /** @type {Array>} */ + const promises = [] for (const [name, url] of repoURLs.entries()) { - this.logger.debug(`Adding repo ${name} -> ${url}`, { repoName: name, repoURL: url }) - await this.helm.repo('add', name, url, forceUpdateArg) - urls.push(url) + promises.push(this.addRepo(name, url, forceUpdateArg)) } - return urls + return await Promise.all(promises) // urls } catch (e) { throw new FullstackTestingError(`failed to setup chart repositories: ${e.message}`, e) } } + /** + * @param {string} name + * @param {string} url + * @param {string} forceUpdateArg + * @returns {Promise} + */ + async addRepo (name, url, forceUpdateArg) { + this.logger.debug(`Adding repo ${name} -> ${url}`, { repoName: name, repoURL: url }) + await this.helm.repo('add', name, url, forceUpdateArg) + return url + } + /** * List available clusters * @param {string} namespaceName diff --git a/test/e2e/commands/mirror_node.test.mjs b/test/e2e/commands/mirror_node.test.mjs index faf1528b6..1d94da56b 100644 --- a/test/e2e/commands/mirror_node.test.mjs +++ b/test/e2e/commands/mirror_node.test.mjs @@ -77,7 +77,7 @@ describe('MirrorNodeCommand', () => { await accountManager.close() bootstrapResp.opts.logger.showUser(`------------------------- END: ${testName} ----------------------------`) - }, 180000) + }, 180_000) afterEach(async () => { await sleep(500) // give a few ticks so that connections can close @@ -101,7 +101,7 @@ describe('MirrorNodeCommand', () => { flags.profileName.constName, flags.tlsClusterIssuerType.constName ]) - }, 600000) + }, 600_000) it('mirror node API should be running', async () => { await accountManager.loadNodeClient(namespace) @@ -111,32 +111,32 @@ describe('MirrorNodeCommand', () => { const pods = await k8.getPodsByLabel(['app.kubernetes.io/name=hedera-explorer']) const explorerPod = pods[0] - portForwarder = await k8.portForward(explorerPod.metadata.name, 8080, 8080) - await sleep(2000) + portForwarder = await k8.portForward(explorerPod.metadata.name, 8_080, 8_080) + await sleep(2_000) // check if mirror node api server is running const apiURL = 'http://127.0.0.1:8080/api/v1/transactions' await expect(downloader.urlExists(apiURL)).resolves.toBeTruthy() - await sleep(2000) + await sleep(2_000) } catch (e) { mirrorNodeCmd.logger.showUserError(e) expect(e).toBeNull() } - }, 60000) + }, 60_000) it('Explorer GUI should be running', async () => { expect.assertions(1) try { const guiURL = 'http://127.0.0.1:8080/localnet/dashboard' await expect(downloader.urlExists(guiURL)).resolves.toBeTruthy() - await sleep(2000) + await sleep(2_000) mirrorNodeCmd.logger.debug('mirror node API and explorer GUI are running') } catch (e) { mirrorNodeCmd.logger.showUserError(e) expect(e).toBeNull() } - }, 60000) + }, 60_000) it('Create topic and submit message should success', async () => { expect.assertions(1) @@ -158,7 +158,7 @@ describe('MirrorNodeCommand', () => { mirrorNodeCmd.logger.showUserError(e) expect(e).toBeNull() } - }, 60000) + }, 60_000) // trigger some extra transactions to trigger MirrorNode to fetch the transactions accountCreationShouldSucceed(accountManager, mirrorNodeCmd, namespace) @@ -196,16 +196,16 @@ describe('MirrorNodeCommand', () => { mirrorNodeCmd.logger.debug(`problem with request: ${e.message}`) }) req.end() // make the request - await sleep(2000) + await sleep(2_000) } - await sleep(1000) + await sleep(1_000) expect(receivedMessage).toBe(testMessage) await k8.stopPortForward(portForwarder) } catch (e) { mirrorNodeCmd.logger.showUserError(e) expect(e).toBeNull() } - }, 300000) + }, 300_000) it('mirror node destroy should success', async () => { expect.assertions(1) @@ -215,5 +215,23 @@ describe('MirrorNodeCommand', () => { mirrorNodeCmd.logger.showUserError(e) expect(e).toBeNull() } - }, 60000) + }, 60_000) + + it('should apply the mirror node version from the --mirror-node-version flag', async () => { + const mirrorNodeVersion = '0.111.1' + const customArgv = { [flags.mirrorNodeVersion.constName]: mirrorNodeVersion, ...argv } + + const valuesArg = await mirrorNodeCmd.prepareValuesArg(customArgv) + + expect(valuesArg).toContain(`--set global.image.tag=${mirrorNodeVersion}`) + }, 5_000) + + it('should not apply the mirror node version from the --mirror-node-version flag if left empty', async () => { + const mirrorNodeVersion = '' + const customArgv = { [flags.mirrorNodeVersion.constName]: mirrorNodeVersion, ...argv } + + const valuesArg = await mirrorNodeCmd.prepareValuesArg(customArgv) + + expect(valuesArg).not.toContain('--set global.image.tag=') + }, 5_000) })