From d737b56470687fec56aeffd8f13f7c57afed800a Mon Sep 17 00:00:00 2001 From: Matheus Fernandes Date: Mon, 22 May 2017 01:37:39 -0700 Subject: [PATCH] Improve `now scale` and `now alias` (#565) * Improve now alias and scale ux * Print scaling rules even when there is nothing to change, and fix scale-info * Allow scale to take alias as parameter * Remove debug print * Fix list prefix color * Fix output styling --- bin/now-scale.js | 48 ++++++++++++++++++++++---------- lib/alias.js | 70 +++++++++++++++++++++++++++-------------------- lib/scale-info.js | 7 ++--- 3 files changed, 76 insertions(+), 49 deletions(-) diff --git a/bin/now-scale.js b/bin/now-scale.js index 85b7c3f..31901ec 100755 --- a/bin/now-scale.js +++ b/bin/now-scale.js @@ -18,6 +18,7 @@ const exit = require('../lib/utils/exit') const logo = require('../lib/utils/output/logo') const info = require('../lib/scale-info') const sort = require('../lib/sort-deployments') +const success = require('../lib/utils/output/success') const argv = minimist(process.argv.slice(2), { string: ['config', 'token'], @@ -139,8 +140,11 @@ async function run({ token, config: { currentTeam } }) { process.exit(0) } else if (id && isHostNameOrId(id)) { // Normalize URL by removing slash from the end - if (isURL(id) && id.slice(-1) === '/') { - id = id.slice(0, -1) + if (isURL(id)) { + id = id.replace(/^https:\/\//i, '') + if (id.slice(-1) === '/') { + id = id.slice(0, -1) + } } } else { error('Please specify a deployment: now scale ') @@ -150,7 +154,7 @@ async function run({ token, config: { currentTeam } }) { const deployments = await scale.list() - const match = deployments.find(d => { + let match = deployments.find(d => { // `url` should match the hostname of the deployment let u = id.replace(/^https:\/\//i, '') @@ -158,13 +162,21 @@ async function run({ token, config: { currentTeam } }) { // `.now.sh` domain is implied if just the subdomain is given u += '.now.sh' } - return d.uid === id || d.name === id || d.url === u }) if (!match) { - error(`Could not find any deployments matching ${id}`) - return process.exit(1) + // Maybe it's an alias + const aliasDeployment = (await scale.listAliases()).find( + e => e.alias === id + ) + if (!aliasDeployment) { + error(`Could not find any deployments matching ${id}`) + return process.exit(1) + } + match = deployments.find(d => { + return d.uid === aliasDeployment.deploymentId + }) } const { min, max } = guessParams() @@ -199,7 +211,8 @@ async function run({ token, config: { currentTeam } }) { Number.isInteger(max) && currentCurrent <= max ) { - console.log(`> Done`) + // Nothing to do, let's print the rules + printScaleingRules(match.url, currentCurrent, min, max) return } @@ -221,19 +234,24 @@ async function run({ token, config: { currentTeam } }) { const elapsed = ms(new Date() - start) const currentReplicas = match.scale.current + printScaleingRules(match.url, currentReplicas, newMin, newMax, elapsed) + await info(scale, match.url) + + scale.close() +} +function printScaleingRules(url, currentReplicas, min, max, elapsed) { const log = console.log - log(`> ${chalk.cyan('Success!')} Configured scaling rules [${elapsed}]`) + success( + `Configured scaling rules ${chalk.gray(elapsed ? '[' + elapsed + ']' : '')}` + ) log() log( - `${chalk.bold(match.url)} (${chalk.gray(currentReplicas)} ${chalk.gray('current')})` + `${chalk.bold(url)} (${chalk.gray(currentReplicas)} ${chalk.gray('current')})` ) - log(printf('%6s %s', 'min', chalk.bold(newMin))) - log(printf('%6s %s', 'max', chalk.bold(newMax))) - log(printf('%6s %s', 'auto', chalk.bold(newMin === newMax ? '✖' : '✔'))) + log(printf('%6s %s', 'min', chalk.bold(min))) + log(printf('%6s %s', 'max', chalk.bold(max))) + log(printf('%6s %s', 'auto', chalk.bold(min === max ? '✖' : '✔'))) log() - await info(scale, match.url) - - scale.close() } async function list(scale) { diff --git a/lib/alias.js b/lib/alias.js index 1f376b2..b964a8f 100644 --- a/lib/alias.js +++ b/lib/alias.js @@ -227,6 +227,12 @@ module.exports = class Alias extends Now { } async set(deployment, alias, domains, currentTeam, user) { + alias = alias.replace(/^https:\/\//i, '') + + if (alias.indexOf('.') === -1) { + // `.now.sh` domain is implied if just the subdomain is given + alias += '.now.sh' + } const depl = await this.findDeployment(deployment) if (!depl) { const err = new Error( @@ -278,44 +284,48 @@ module.exports = class Alias extends Now { console.log( `> Alias ${alias} points to ${chalk.bold(aliasedDeployment.url)} (${chalk.bold(aliasedDeployment.scale.current + ' instances')})` ) + // Test if we need to change the scale or just update the rules console.log( `> Scaling ${depl.url} to ${chalk.bold(aliasedDeployment.scale.current + ' instances')} atomically` ) - - if (depl.scale.max < 1) { - if (this._debug) { - console.log( - 'Updating max scale to 1 so that deployment may be unfrozen.' - ) + if (depl.scale.current !== aliasedDeployment.scale.current) { + if (depl.scale.max < 1) { + if (this._debug) { + console.log( + 'Updating max scale to 1 so that deployment may be unfrozen.' + ) + } + await this.setScale(depl.uid, { + min: depl.scale.min, + max: Math.max(aliasedDeployment.scale.max, 1) + }) } - await this.setScale(depl.uid, { - min: depl.scale.min, - max: Math.max(aliasedDeployment.scale.max, 1) - }) - } - if (depl.scale.current < 1) { - if (this._debug) { - console.log(`> Deployment ${depl.url} is frozen, unfreezing...`) + if (depl.scale.current < 1) { + if (this._debug) { + console.log(`> Deployment ${depl.url} is frozen, unfreezing...`) + } + await this.unfreeze(depl) + if (this._debug) { + console.log( + `> Deployment is now unfrozen, scaling it to match current instance count` + ) + } + } + // Scale it to current limit + if (depl.scale.current !== aliasedDeployment.scale.current) { + if (this._debug) { + console.log(`> Scaling deployment to match current scale.`) + } + await this.setScale(depl.uid, { + min: aliasedDeployment.scale.current, + max: aliasedDeployment.scale.current + }) } - await this.unfreeze(depl) + await scaleInfo(this, depl.url) if (this._debug) { - console.log( - `> Deployment is now unfrozen, scaling it to match current instance count` - ) + console.log(`> Updating scaling rules for deployment.`) } } - // Scale it to current limit - if (this._debug) { - console.log(`> Scaling deployment to match current scale.`) - } - await this.setScale(depl.uid, { - min: aliasedDeployment.scale.current, - max: aliasedDeployment.scale.current - }) - await scaleInfo(this, depl.url) - if (this._debug) { - console.log(`> Updating scaling rules for deployment.`) - } await this.setScale(depl.uid, { min: Math.max(aliasedDeployment.scale.min, depl.scale.min), diff --git a/lib/scale-info.js b/lib/scale-info.js index 371b4d0..ad977b5 100644 --- a/lib/scale-info.js +++ b/lib/scale-info.js @@ -23,7 +23,6 @@ module.exports = async function(now, url) { } else if (current > max) { targetReplicaCount = max } else { - console.log(`> Nothing to do, already scaled.`) return } @@ -36,7 +35,7 @@ module.exports = async function(now, url) { let barcurr = current const end = Math.max(current, max) linelog( - `> Scaling to ${chalk.bold(String(targetReplicaCount) + (targetReplicaCount === 1 ? ' instance' : ' instances'))}: ` + + `${chalk.gray('>')} Scaling to ${chalk.bold(String(targetReplicaCount) + (targetReplicaCount === 1 ? ' instance' : ' instances'))}: ` + barify(barcurr, end) ) @@ -46,7 +45,7 @@ module.exports = async function(now, url) { if (barcurr !== res.length) { barcurr = res.length linelog( - `> Scaling to ${chalk.bold(String(targetReplicaCount) + (targetReplicaCount === 1 ? ' instance' : ' instances'))}: ` + + `${chalk.gray('>')} Scaling to ${chalk.bold(String(targetReplicaCount) + (targetReplicaCount === 1 ? ' instance' : ' instances'))}: ` + barify(barcurr, end) ) @@ -66,7 +65,7 @@ module.exports = async function(now, url) { process.nextTick(() => { instances.forEach(inst => { - console.log(` - ${chalk.underline(inst.url)}`) + console.log(`${chalk.gray('-')} ${chalk.underline(inst.url)}`) }) }) }