Skip to content
This repository has been archived by the owner on Feb 12, 2022. It is now read-only.

Multiple dockerfiles #6

Merged
merged 27 commits into from
Jul 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4d70559
4.1.1
hunterloftis Sep 29, 2016
d7cf202
push multiple, recursive, choose nearest, warn multiple, fail ambiguo…
hunterloftis Sep 30, 2016
e66a79b
Update push.js
jbyrum Oct 5, 2016
a66925e
more readable formatting
hunterloftis Oct 5, 2016
502e3f1
multiple dockerfiles
KarateCowboy May 3, 2017
b4c8b85
some changes for excluding certain files
KarateCowboy May 3, 2017
9522087
review feedback
KarateCowboy May 4, 2017
c00e780
minor fixes and updates
KarateCowboy May 11, 2017
99f90f8
remove heroku-client dependency
KarateCowboy May 12, 2017
c940247
do not treat 'Dockerfile' as 'Dockerfile.web'
KarateCowboy May 19, 2017
be01673
use regular dockerfile when recurse arg omitted
KarateCowboy May 22, 2017
be7651f
Remove docker text
jbyrum May 22, 2017
5b148f9
Remove Docker text
jbyrum May 22, 2017
fc6fc7b
Update to usage text
jbyrum May 22, 2017
a3b4a22
Merge pull request #17 from heroku/jbyrum-text-updates
KarateCowboy May 22, 2017
632a3c8
change headers to use cli.styledHeader
KarateCowboy May 22, 2017
832be4e
review feedback
KarateCowboy Jun 5, 2017
db8f6db
fixed merge conflicts
KarateCowboy Jun 5, 2017
0773479
fix pushing standard dockerfiles
KarateCowboy Jun 9, 2017
4f8e25e
more regression fixing
KarateCowboy Jun 9, 2017
7377b6c
fix recursive regression
KarateCowboy Jun 12, 2017
cbcf60e
add handling for directories w/o dockerfiles
KarateCowboy Jun 15, 2017
f18dae3
Made text updates to push
jbyrum Jun 19, 2017
df8ce5f
logout/in command fix
jbyrum Jun 19, 2017
d744280
login text change
jbyrum Jun 19, 2017
fb84194
Merge pull request #18 from heroku/new-push-text
KarateCowboy Jun 20, 2017
ec54401
consolidate spawing methods into helper
KarateCowboy Jun 30, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions commands/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
module.exports = function index(pkg) {
module.exports = function index (pkg) {
return {
topic: pkg.topic,
description: pkg.description,
help: pkg.description,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you put the help back in with an output example?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To which command are you referring? the basic heroku containers just prints the version. What would you like added -- the sum of all the help for the other commands?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an example of it printing the version then, we're supposed to have output examples for every command. I realize that isn't the most useful thing in the world, but it clearly demonstrates what a command is for.

this is the (soon-to-be enforced) rule for core plugins anyways, but we should do it on any plugin we can

run: showVersion
};
}

function showVersion(context) {
console.log(pkg.version);
function showVersion (context) {
console.log(pkg.version)
}
}
61 changes: 27 additions & 34 deletions commands/login.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,42 @@
'use strict';
const cli = require('heroku-cli-util')
const log = require('../lib/log')

const cli = require('heroku-cli-util');
const co = require('co');
const child = require('child_process');

module.exports = function(topic) {
module.exports = function (topic) {
return {
topic: topic,
command: 'login',
flags: [{ name: 'verbose', char: 'v', hasValue: false }],
description: 'Logs in to the Heroku Docker registry',
flags: [{name: 'verbose', char: 'v', hasValue: false}],
description: 'login to the Heroku Container Registry',
help: `Usage:
heroku container:login`,
needsApp: false,
needsAuth: true,
run: cli.command(co.wrap(login))
};
};
run: cli.command(login)
}
}

function* login(context, heroku) {
let herokuHost = process.env.HEROKU_HOST || 'heroku.com';
let registry = `registry.${ herokuHost }`;
let password = context.auth.password;
async function login (context, heroku) {
let herokuHost = process.env.HEROKU_HOST || 'heroku.com'
let registry = `registry.${ herokuHost }`
let password = context.auth.password

try {
let user = yield dockerLogin(registry, password, context.flags.verbose);
let user = await dockerLogin(registry, password, context.flags.verbose)
}
catch (err) {
cli.error(`Error: docker login exited with ${ err }`);
cli.error(`Error: docker login exited with ${ err }`)
cli.hush(err.stack || err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should exit with a nonzero code, it looks like it's exiting with 0

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

cli.exit(1)
}
}

function dockerLogin(registry, password, verbose) {
return new Promise((resolve, reject) => {
let args = [
'login',
'--username=_',
`--password=${ password }`,
registry
];
if (verbose) {
console.log(['> docker'].concat(args).join(' '));
}
child.spawn('docker', args, { stdio: 'inherit' })
.on('exit', (code, signal) => {
if (signal || code) reject(signal || code);
else resolve();
});
});
function dockerLogin (registry, password, verbose) {
let args = [
'login',
'--username=_',
`--password=${ password }`,
registry
]
log(verbose, args)
return Sanbashi.cmd('docker', args)
}
51 changes: 20 additions & 31 deletions commands/logout.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,35 @@
'use strict';
const cli = require('heroku-cli-util')
const log = require('../lib/log')

const cli = require('heroku-cli-util');
const co = require('co');
const child = require('child_process');

module.exports = function(topic) {
module.exports = function (topic) {
return {
topic: topic,
command: 'logout',
flags: [{ name: 'verbose', char: 'v', hasValue: false }],
description: 'Logs out from the Heroku Docker registry',
flags: [{name: 'verbose', char: 'v', hasValue: false}],
description: 'logout from the Heroku Container Registry',
needsApp: false,
needsAuth: false,
run: cli.command(co.wrap(logout))
};
};
run: cli.command(logout)
}
}

function* logout(context, heroku) {
let herokuHost = process.env.HEROKU_HOST || 'heroku.com';
let registry = `registry.${ herokuHost }`;
async function logout (context, heroku) {
let herokuHost = process.env.HEROKU_HOST || 'heroku.com'
let registry = `registry.${ herokuHost }`

try {
let user = yield dockerLogout(registry, context.flags.verbose);
let user = await dockerLogout(registry, context.flags.verbose)
}
catch (err) {
cli.error(`Error: docker logout exited with ${ err }`);
cli.error(`Error: docker logout exited with ${ err }`)
}
}

function dockerLogout(registry, verbose) {
return new Promise((resolve, reject) => {
let args = [
'logout',
registry
];
if (verbose) {
console.log(['> docker'].concat(args).join(' '));
}
child.spawn('docker', args, { stdio: 'inherit' })
.on('exit', (code, signal) => {
if (signal || code) reject(signal || code);
else resolve();
});
});
function dockerLogout (registry, verbose) {
let args = [
'logout',
registry
]
log(verbose, args)
return Sanbashi.cmd('docker', args)
}
135 changes: 77 additions & 58 deletions commands/push.js
Original file line number Diff line number Diff line change
@@ -1,77 +1,96 @@
'use strict';
const cli = require('heroku-cli-util')
const Sanbashi = require('../lib/sanbashi')

const cli = require('heroku-cli-util');
const co = require('co');
const child = require('child_process');
let usage = `
${cli.color.bold.underline.magenta('Usage:')}
${ cli.color.cmd('heroku container:push web')} # Pushes Dockerfile to web process type
${ cli.color.cmd('heroku container:push web worker --recursive')} # Pushes Dockerfile.web and Dockerfile.worker
${ cli.color.cmd('heroku container:push --recursive')} # Pushes Dockerfile.*`

module.exports = function(topic) {
module.exports = function (topic) {
return {
topic: topic,
command: 'push',
description: 'Builds, then pushes a Docker image to deploy your Heroku app',
description: 'builds, then pushes Docker images to deploy your Heroku app',
needsApp: true,
needsAuth: true,
args: [{ name: 'process', optional: true }],
flags: [{ name: 'verbose', char: 'v', hasValue: false }],
run: cli.command(co.wrap(push))
};
};
variableArgs: true,
help: usage,
flags: [
{
name: 'verbose',
char: 'v',
hasValue: false
},
{
name: 'recursive',
char: 'R',
hasValue: false,
description: 'pushes Dockerfile.<process> found in current and subdirectories'
}
],
run: cli.command(push)
}
}

function* push(context, heroku) {
let herokuHost = process.env.HEROKU_HOST || 'heroku.com';
let registry = `registry.${ herokuHost }`;
let proc = context.args.process || 'web';
let resource = `${ registry }/${ context.app }/${ proc }`;
let push = async function (context, heroku) {
const recurse = !!context.flags.recursive
if (context.args.length === 0 && !recurse) {
cli.error(`Error: Requires either --recursive or one or more process types\n ${usage} `)
process.exit(1)
}
if (context.args.length > 1 && !recurse) {
cli.error(`Error: Please specify one target process type\n ${usage} `)
process.exit(1)
}
let herokuHost = process.env.HEROKU_HOST || 'heroku.com'
let registry = `registry.${ herokuHost }`
let dockerfiles = Sanbashi.getDockerfiles(process.cwd(), recurse)

let possibleJobs = Sanbashi.getJobs(`${ registry }/${ context.app }`, dockerfiles)
let jobs = []
if (recurse) {
if (context.args.length) {
possibleJobs = Sanbashi.filterByProcessType(possibleJobs, context.args)
}
jobs = await Sanbashi.chooseJobs(possibleJobs)
} else if (possibleJobs.standard) {
possibleJobs.standard.forEach((pj) => { pj.resource = pj.resource.replace(/standard$/, context.args[0])})
jobs = possibleJobs.standard || []
}
if (!jobs.length) {
cli.warn('No images to push')
process.exit(1)
}
try {
let build = yield buildImage(resource, process.cwd(), context.flags.verbose);
for (let job of jobs) {
if (job.name === 'standard') {
cli.styledHeader(`Building for ${context.args} (${job.dockerfile })`)
} else {
cli.styledHeader(`Building ${job.name} (${job.dockerfile})`)
}
await Sanbashi.buildImage(job.dockerfile, job.resource, context.flags.verbose)
}
}
catch (err) {
cli.error(`Error: docker build exited with ${ err }`);
process.exit(1);
cli.error(`Error: docker build exited with ${ err }`)
cli.hush(err.stack || err)
process.exit(1)
}

try {
let push = yield pushImage(resource, context.flags.verbose);
for (let job of jobs) {
if (job.name === 'standard') {
cli.styledHeader(`Pushing for ${context.args} (${job.dockerfile })`)
} else {
cli.styledHeader(`Pushing ${job.name} (${job.dockerfile })`)
}
await Sanbashi.pushImage(job.resource, context.flags.verbose)
}
}
catch (err) {
cli.error(`Error: docker push exited with ${ err }`);
process.exit(1);
cli.error(`Error: docker push exited with ${ err }`)
cli.hush(err.stack || err)
process.exit(1)
}
}

function buildImage(resource, cwd, verbose) {
return new Promise((resolve, reject) => {
let args = [
'build',
'-t',
resource,
cwd
];
if (verbose) {
console.log(['> docker'].concat(args).join(' '));
}
child.spawn('docker', args, { stdio: 'inherit' })
.on('exit', (code, signal) => {
if (signal || code) reject(signal || code);
else resolve();
});
});
}

function pushImage(resource, verbose) {
return new Promise((resolve, reject) => {
let args = [
'push',
resource
];
if (verbose) {
console.log(['> docker'].concat(args).join(' '));
}
child.spawn('docker', args, { stdio: 'inherit' })
.on('exit', (code, signal) => {
if (signal || code) reject(signal || code);
else resolve();
});
});
}
9 changes: 7 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
var pkg = require('./package.json');
var pkg = require('./package.json')

module.exports = {
topic: {
description: 'Use containers to build and deploy Heroku apps',
name: 'container',
help: pkg.description
},
commands: [
require('./commands/index')(pkg),
require('./commands/login')(pkg.topic),
require('./commands/logout')(pkg.topic),
require('./commands/push')(pkg.topic)
]
};
}
4 changes: 4 additions & 0 deletions lib/log.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = (visible, args) => {
if (!visible) return
console.log(`> docker ${ args.join(' ') }`)
}
Loading