import chalk from 'chalk'; import {command, help, namespace, option, param, required} from 'oo-cli'; import {die} from '../../lib/die'; import {formatError} from '../../lib/formatError'; import {handleInterrupt} from '../../lib/handleInterrupt'; import {TerminalSpinner} from '../../lib/TerminalSpinner'; import {terminal} from 'terminal-kit'; import {Rivendell} from '../../lib/Rivendell'; @namespace('directory') export class UpgradeCommand { @param @help('The App ID of the app to upgrade (e.g. my_app)') public appId!: string; @param @help('The Tracker ID of the account to install into') public trackerId!: string; @option('v') @required @help('The desired version (i.e. 1.0.0)') public toVersion!: string; @option('a') @help('The availability zone that will be targeted (default: us)') private availability: string = ''; @command @help('Upgrade the Install to a specific app version') public async upgrade() { handleInterrupt(); try { const shard = this.availability || 'us'; const install = await Rivendell.fetchAppInstallation(this.appId, this.trackerId, shard); if (install.version === this.toVersion) { console.log( chalk.yellow(`${this.trackerId} is currently at ${this.appId}@${install.version} in ${shard}.`) ); } else { await Rivendell.upgrade(install.id, this.appId, this.toVersion, shard); console.log(`Upgrading ${this.appId} for ${this.trackerId} to ${this.toVersion} in ${shard}`); await this.watchForCompletion(shard); console.log( chalk.green(`Upgraded ${this.trackerId} to ${this.appId}@${this.toVersion} in ${shard}.`)); terminal.removeAllListeners('key'); } } catch (e) { die(formatError(e)); } } private watchForCompletion(shard: string) { console.log(chalk.gray(`Upgrade was scheduled in ${shard}, watching for completion... CTRL+C to stop checking.`)); return new Promise((resolve, reject) => { let attempts = 0; const spinner = new TerminalSpinner().start(''); const checkUpgrade = () => { attempts++; Rivendell.fetchAppInstallation(this.appId, this.trackerId, shard) .then((install) => { if (install.version === this.toVersion) { clearInterval(interval); spinner.stop(); resolve(); } else { if (attempts > 300) { clearInterval(interval); spinner.stop(); die('Timed out waiting for completion'); } } }) .catch((e) => { clearInterval(interval); spinner.stop(); reject(e); }); }; const interval = setInterval(checkUpgrade, 2000); checkUpgrade(); }); } }