Browse Source

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
master
Matheus Fernandes 8 years ago
committed by GitHub
parent
commit
d737b56470
  1. 48
      bin/now-scale.js
  2. 70
      lib/alias.js
  3. 7
      lib/scale-info.js

48
bin/now-scale.js

@ -18,6 +18,7 @@ const exit = require('../lib/utils/exit')
const logo = require('../lib/utils/output/logo') const logo = require('../lib/utils/output/logo')
const info = require('../lib/scale-info') const info = require('../lib/scale-info')
const sort = require('../lib/sort-deployments') const sort = require('../lib/sort-deployments')
const success = require('../lib/utils/output/success')
const argv = minimist(process.argv.slice(2), { const argv = minimist(process.argv.slice(2), {
string: ['config', 'token'], string: ['config', 'token'],
@ -139,8 +140,11 @@ async function run({ token, config: { currentTeam } }) {
process.exit(0) process.exit(0)
} else if (id && isHostNameOrId(id)) { } else if (id && isHostNameOrId(id)) {
// Normalize URL by removing slash from the end // Normalize URL by removing slash from the end
if (isURL(id) && id.slice(-1) === '/') { if (isURL(id)) {
id = id.slice(0, -1) id = id.replace(/^https:\/\//i, '')
if (id.slice(-1) === '/') {
id = id.slice(0, -1)
}
} }
} else { } else {
error('Please specify a deployment: now scale <id|url>') error('Please specify a deployment: now scale <id|url>')
@ -150,7 +154,7 @@ async function run({ token, config: { currentTeam } }) {
const deployments = await scale.list() const deployments = await scale.list()
const match = deployments.find(d => { let match = deployments.find(d => {
// `url` should match the hostname of the deployment // `url` should match the hostname of the deployment
let u = id.replace(/^https:\/\//i, '') 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 // `.now.sh` domain is implied if just the subdomain is given
u += '.now.sh' u += '.now.sh'
} }
return d.uid === id || d.name === id || d.url === u return d.uid === id || d.name === id || d.url === u
}) })
if (!match) { if (!match) {
error(`Could not find any deployments matching ${id}`) // Maybe it's an alias
return process.exit(1) 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() const { min, max } = guessParams()
@ -199,7 +211,8 @@ async function run({ token, config: { currentTeam } }) {
Number.isInteger(max) && Number.isInteger(max) &&
currentCurrent <= max currentCurrent <= max
) { ) {
console.log(`> Done`) // Nothing to do, let's print the rules
printScaleingRules(match.url, currentCurrent, min, max)
return return
} }
@ -221,19 +234,24 @@ async function run({ token, config: { currentTeam } }) {
const elapsed = ms(new Date() - start) const elapsed = ms(new Date() - start)
const currentReplicas = match.scale.current 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 const log = console.log
log(`> ${chalk.cyan('Success!')} Configured scaling rules [${elapsed}]`) success(
`Configured scaling rules ${chalk.gray(elapsed ? '[' + elapsed + ']' : '')}`
)
log() log()
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', 'min', chalk.bold(min)))
log(printf('%6s %s', 'max', chalk.bold(newMax))) log(printf('%6s %s', 'max', chalk.bold(max)))
log(printf('%6s %s', 'auto', chalk.bold(newMin === newMax ? '✖' : '✔'))) log(printf('%6s %s', 'auto', chalk.bold(min === max ? '✖' : '✔')))
log() log()
await info(scale, match.url)
scale.close()
} }
async function list(scale) { async function list(scale) {

70
lib/alias.js

@ -227,6 +227,12 @@ module.exports = class Alias extends Now {
} }
async set(deployment, alias, domains, currentTeam, user) { 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) const depl = await this.findDeployment(deployment)
if (!depl) { if (!depl) {
const err = new Error( const err = new Error(
@ -278,44 +284,48 @@ module.exports = class Alias extends Now {
console.log( console.log(
`> Alias ${alias} points to ${chalk.bold(aliasedDeployment.url)} (${chalk.bold(aliasedDeployment.scale.current + ' instances')})` `> 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( console.log(
`> Scaling ${depl.url} to ${chalk.bold(aliasedDeployment.scale.current + ' instances')} atomically` `> Scaling ${depl.url} to ${chalk.bold(aliasedDeployment.scale.current + ' instances')} atomically`
) )
if (depl.scale.current !== aliasedDeployment.scale.current) {
if (depl.scale.max < 1) { if (depl.scale.max < 1) {
if (this._debug) { if (this._debug) {
console.log( console.log(
'Updating max scale to 1 so that deployment may be unfrozen.' '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, { if (depl.scale.current < 1) {
min: depl.scale.min, if (this._debug) {
max: Math.max(aliasedDeployment.scale.max, 1) console.log(`> Deployment ${depl.url} is frozen, unfreezing...`)
}) }
} await this.unfreeze(depl)
if (depl.scale.current < 1) { if (this._debug) {
if (this._debug) { console.log(
console.log(`> Deployment ${depl.url} is frozen, unfreezing...`) `> 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) { if (this._debug) {
console.log( console.log(`> Updating scaling rules for deployment.`)
`> Deployment is now unfrozen, scaling it to match current instance count`
)
} }
} }
// 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, { await this.setScale(depl.uid, {
min: Math.max(aliasedDeployment.scale.min, depl.scale.min), min: Math.max(aliasedDeployment.scale.min, depl.scale.min),

7
lib/scale-info.js

@ -23,7 +23,6 @@ module.exports = async function(now, url) {
} else if (current > max) { } else if (current > max) {
targetReplicaCount = max targetReplicaCount = max
} else { } else {
console.log(`> Nothing to do, already scaled.`)
return return
} }
@ -36,7 +35,7 @@ module.exports = async function(now, url) {
let barcurr = current let barcurr = current
const end = Math.max(current, max) const end = Math.max(current, max)
linelog( 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) barify(barcurr, end)
) )
@ -46,7 +45,7 @@ module.exports = async function(now, url) {
if (barcurr !== res.length) { if (barcurr !== res.length) {
barcurr = res.length barcurr = res.length
linelog( 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) barify(barcurr, end)
) )
@ -66,7 +65,7 @@ module.exports = async function(now, url) {
process.nextTick(() => { process.nextTick(() => {
instances.forEach(inst => { instances.forEach(inst => {
console.log(` - ${chalk.underline(inst.url)}`) console.log(`${chalk.gray('-')} ${chalk.underline(inst.url)}`)
}) })
}) })
} }

Loading…
Cancel
Save