mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-04-13 22:22:58 +00:00
Merge pull request #563 from resin-io/562-fix-tls-connect
Read ca files and convert to string before passing to the docker daemon
This commit is contained in:
commit
26d123b33d
@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Fixed
|
||||
|
||||
- Ensure to send .pem file contents rather than filename to docker daemon
|
||||
|
||||
## [5.11.0] - 2017-06-19
|
||||
|
||||
### Added
|
||||
|
@ -202,57 +202,57 @@ module.exports = {
|
||||
tmp.setGracefulCleanup();
|
||||
logs = '';
|
||||
upload = function(token, username, url) {
|
||||
var docker;
|
||||
docker = dockerUtils.getDocker(options);
|
||||
return parseInput(params, options).then(function(arg) {
|
||||
var appName, build, imageName, source;
|
||||
appName = arg[0], build = arg[1], source = arg[2], imageName = arg[3];
|
||||
return tmpNameAsync().then(function(bufferFile) {
|
||||
options = _.assign({}, options, {
|
||||
appName: appName
|
||||
});
|
||||
params = _.assign({}, params, {
|
||||
source: source
|
||||
});
|
||||
return Promise["try"](function() {
|
||||
if (build) {
|
||||
return dockerUtils.runBuild(params, options, getBundleInfo, logStreams);
|
||||
} else {
|
||||
return {
|
||||
image: imageName,
|
||||
log: ''
|
||||
};
|
||||
}
|
||||
}).then(function(arg1) {
|
||||
var buildLogs, imageName;
|
||||
imageName = arg1.image, buildLogs = arg1.log;
|
||||
logging.logInfo(logStreams, 'Initializing deploy...');
|
||||
logs = buildLogs;
|
||||
return Promise.all([dockerUtils.bufferImage(docker, imageName, bufferFile), token, username, url, params.appName, logStreams]).spread(performUpload);
|
||||
})["finally"](function() {
|
||||
return dockerUtils.getDocker(options).then(function(docker) {
|
||||
return parseInput(params, options).then(function(arg) {
|
||||
var appName, build, imageName, source;
|
||||
appName = arg[0], build = arg[1], source = arg[2], imageName = arg[3];
|
||||
return tmpNameAsync().then(function(bufferFile) {
|
||||
options = _.assign({}, options, {
|
||||
appName: appName
|
||||
});
|
||||
params = _.assign({}, params, {
|
||||
source: source
|
||||
});
|
||||
return Promise["try"](function() {
|
||||
return require('mz/fs').unlink(bufferFile);
|
||||
})["catch"](_.noop);
|
||||
if (build) {
|
||||
return dockerUtils.runBuild(params, options, getBundleInfo, logStreams);
|
||||
} else {
|
||||
return {
|
||||
image: imageName,
|
||||
log: ''
|
||||
};
|
||||
}
|
||||
}).then(function(arg1) {
|
||||
var buildLogs, imageName;
|
||||
imageName = arg1.image, buildLogs = arg1.log;
|
||||
logging.logInfo(logStreams, 'Initializing deploy...');
|
||||
logs = buildLogs;
|
||||
return Promise.all([dockerUtils.bufferImage(docker, imageName, bufferFile), token, username, url, params.appName, logStreams]).spread(performUpload);
|
||||
})["finally"](function() {
|
||||
return Promise["try"](function() {
|
||||
return require('mz/fs').unlink(bufferFile);
|
||||
})["catch"](_.noop);
|
||||
});
|
||||
});
|
||||
});
|
||||
}).tap(function(arg) {
|
||||
var buildId, imageName;
|
||||
imageName = arg.image, buildId = arg.buildId;
|
||||
logging.logSuccess(logStreams, "Successfully deployed image: " + (formatImageName(imageName)));
|
||||
return buildId;
|
||||
}).then(function(arg) {
|
||||
var buildId, imageName;
|
||||
imageName = arg.image, buildId = arg.buildId;
|
||||
if (logs === '' || (options.nologupload != null)) {
|
||||
return '';
|
||||
}
|
||||
logging.logInfo(logStreams, 'Uploading logs to dashboard...');
|
||||
return Promise.join(logs, token, url, buildId, username, params.appName, uploadLogs)["return"]('Successfully uploaded logs');
|
||||
}).then(function(msg) {
|
||||
if (msg !== '') {
|
||||
return logging.logSuccess(logStreams, msg);
|
||||
}
|
||||
}).asCallback(done);
|
||||
}).tap(function(arg) {
|
||||
var buildId, imageName;
|
||||
imageName = arg.image, buildId = arg.buildId;
|
||||
logging.logSuccess(logStreams, "Successfully deployed image: " + (formatImageName(imageName)));
|
||||
return buildId;
|
||||
}).then(function(arg) {
|
||||
var buildId, imageName;
|
||||
imageName = arg.image, buildId = arg.buildId;
|
||||
if (logs === '' || (options.nologupload != null)) {
|
||||
return '';
|
||||
}
|
||||
logging.logInfo(logStreams, 'Uploading logs to dashboard...');
|
||||
return Promise.join(logs, token, url, buildId, username, params.appName, uploadLogs)["return"]('Successfully uploaded logs');
|
||||
}).then(function(msg) {
|
||||
if (msg !== '') {
|
||||
return logging.logSuccess(logStreams, msg);
|
||||
}
|
||||
}).asCallback(done);
|
||||
});
|
||||
};
|
||||
return Promise.join(resin.auth.getToken(), resin.auth.whoami(), resin.settings.get('resinUrl'), upload);
|
||||
}
|
||||
|
@ -58,27 +58,35 @@ exports.appendOptions = function(opts) {
|
||||
};
|
||||
|
||||
exports.generateConnectOpts = generateConnectOpts = function(opts) {
|
||||
var connectOpts;
|
||||
connectOpts = {};
|
||||
if ((opts.docker != null) && (opts.dockerHost == null)) {
|
||||
connectOpts.socketPath = opts.docker;
|
||||
} else if ((opts.dockerHost != null) && (opts.docker == null)) {
|
||||
connectOpts.host = opts.dockerHost;
|
||||
connectOpts.port = opts.dockerPort || 2376;
|
||||
} else if ((opts.docker != null) && (opts.dockerHost != null)) {
|
||||
throw new Error("Both a local docker socket and docker host have been provided. Don't know how to continue.");
|
||||
} else {
|
||||
connectOpts.socketPath = '/var/run/docker.sock';
|
||||
}
|
||||
if ((opts.ca != null) || (opts.cert != null) || (opts.key != null)) {
|
||||
if (!((opts.ca != null) && (opts.cert != null) && (opts.key != null))) {
|
||||
throw new Error('You must provide a CA, certificate and key in order to use TLS');
|
||||
var Promise, fs;
|
||||
Promise = require('bluebird');
|
||||
fs = require('mz/fs');
|
||||
return Promise["try"](function() {
|
||||
var connectOpts;
|
||||
connectOpts = {};
|
||||
if ((opts.docker != null) && (opts.dockerHost == null)) {
|
||||
connectOpts.socketPath = opts.docker;
|
||||
} else if ((opts.dockerHost != null) && (opts.docker == null)) {
|
||||
connectOpts.host = opts.dockerHost;
|
||||
connectOpts.port = opts.dockerPort || 2376;
|
||||
} else if ((opts.docker != null) && (opts.dockerHost != null)) {
|
||||
throw new Error("Both a local docker socket and docker host have been provided. Don't know how to continue.");
|
||||
} else {
|
||||
connectOpts.socketPath = '/var/run/docker.sock';
|
||||
}
|
||||
connectOpts.ca = opts.ca;
|
||||
connectOpts.cert = opts.cert;
|
||||
connectOpts.key = opts.key;
|
||||
}
|
||||
return connectOpts;
|
||||
if ((opts.ca != null) || (opts.cert != null) || (opts.key != null)) {
|
||||
if (!((opts.ca != null) && (opts.cert != null) && (opts.key != null))) {
|
||||
throw new Error('You must provide a CA, certificate and key in order to use TLS');
|
||||
}
|
||||
return Promise.all([fs.readFile(opts.ca), fs.readFile(opts.cert), fs.readFile(opts.key)]).spread(function(ca, cert, key) {
|
||||
connectOpts.ca = ca.toString();
|
||||
connectOpts.cert = cert.toString();
|
||||
connectOpts.key = key.toString();
|
||||
return connectOpts;
|
||||
});
|
||||
}
|
||||
return connectOpts;
|
||||
});
|
||||
};
|
||||
|
||||
exports.tarDirectory = tarDirectory = function(dir) {
|
||||
@ -189,7 +197,7 @@ exports.runBuild = function(params, options, getBundleInfo, logStreams) {
|
||||
return tarDirectory(params.source);
|
||||
}).then(function(tarStream) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var builder, connectOpts, hooks, opts;
|
||||
var hooks;
|
||||
hooks = {
|
||||
buildSuccess: function(image) {
|
||||
var doodle;
|
||||
@ -252,23 +260,25 @@ exports.runBuild = function(params, options, getBundleInfo, logStreams) {
|
||||
return newStream.pipe(logThroughStream).pipe(cacheHighlightStream()).pipe(logStreams.build);
|
||||
}
|
||||
};
|
||||
connectOpts = generateConnectOpts(options);
|
||||
logging.logDebug(logStreams, 'Connecting with the following options:');
|
||||
logging.logDebug(logStreams, JSON.stringify(connectOpts, null, ' '));
|
||||
builder = new dockerBuild.Builder(connectOpts);
|
||||
opts = {};
|
||||
if (options.tag != null) {
|
||||
opts['t'] = options.tag;
|
||||
}
|
||||
if (options.nocache != null) {
|
||||
opts['nocache'] = true;
|
||||
}
|
||||
if (options.buildArg != null) {
|
||||
opts['buildargs'] = parseBuildArgs(options.buildArg, function(arg) {
|
||||
return logging.logWarn(logStreams, "Could not parse variable: '" + arg + "'");
|
||||
});
|
||||
}
|
||||
return builder.createBuildStream(opts, hooks, reject);
|
||||
return generateConnectOpts(options).then(function(connectOpts) {
|
||||
var builder, opts;
|
||||
logging.logDebug(logStreams, 'Connecting with the following options:');
|
||||
logging.logDebug(logStreams, JSON.stringify(connectOpts, null, ' '));
|
||||
builder = new dockerBuild.Builder(connectOpts);
|
||||
opts = {};
|
||||
if (options.tag != null) {
|
||||
opts['t'] = options.tag;
|
||||
}
|
||||
if (options.nocache != null) {
|
||||
opts['nocache'] = true;
|
||||
}
|
||||
if (options.buildArg != null) {
|
||||
opts['buildargs'] = parseBuildArgs(options.buildArg, function(arg) {
|
||||
return logging.logWarn(logStreams, "Could not parse variable: '" + arg + "'");
|
||||
});
|
||||
}
|
||||
return builder.createBuildStream(opts, hooks, reject);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -287,12 +297,13 @@ exports.bufferImage = function(docker, imageId, bufferFile) {
|
||||
};
|
||||
|
||||
exports.getDocker = function(options) {
|
||||
var Docker, Promise, connectOpts;
|
||||
var Docker, Promise;
|
||||
Docker = require('dockerode');
|
||||
Promise = require('bluebird');
|
||||
connectOpts = generateConnectOpts(options);
|
||||
connectOpts['Promise'] = Promise;
|
||||
return new Docker(connectOpts);
|
||||
return generateConnectOpts(options).then(function(connectOpts) {
|
||||
connectOpts['Promise'] = Promise;
|
||||
return new Docker(connectOpts);
|
||||
});
|
||||
};
|
||||
|
||||
hasQemu = function() {
|
||||
|
@ -175,64 +175,65 @@ module.exports =
|
||||
logs = ''
|
||||
|
||||
upload = (token, username, url) ->
|
||||
docker = dockerUtils.getDocker(options)
|
||||
# Check input parameters
|
||||
parseInput(params, options)
|
||||
.then ([appName, build, source, imageName]) ->
|
||||
tmpNameAsync()
|
||||
.then (bufferFile) ->
|
||||
dockerUtils.getDocker(options)
|
||||
.then (docker) ->
|
||||
# Check input parameters
|
||||
parseInput(params, options)
|
||||
.then ([appName, build, source, imageName]) ->
|
||||
tmpNameAsync()
|
||||
.then (bufferFile) ->
|
||||
|
||||
# Setup the build args for how the build routine expects them
|
||||
options = _.assign({}, options, { appName })
|
||||
params = _.assign({}, params, { source })
|
||||
# Setup the build args for how the build routine expects them
|
||||
options = _.assign({}, options, { appName })
|
||||
params = _.assign({}, params, { source })
|
||||
|
||||
Promise.try ->
|
||||
if build
|
||||
dockerUtils.runBuild(params, options, getBundleInfo, logStreams)
|
||||
else
|
||||
{ image: imageName, log: '' }
|
||||
.then ({ image: imageName, log: buildLogs }) ->
|
||||
logging.logInfo(logStreams, 'Initializing deploy...')
|
||||
|
||||
logs = buildLogs
|
||||
Promise.all [
|
||||
dockerUtils.bufferImage(docker, imageName, bufferFile)
|
||||
token
|
||||
username
|
||||
url
|
||||
params.appName
|
||||
logStreams
|
||||
]
|
||||
.spread(performUpload)
|
||||
.finally ->
|
||||
# If the file was never written to (for instance because an error
|
||||
# has occured before any data was written) this call will throw an
|
||||
# ugly error, just suppress it
|
||||
Promise.try ->
|
||||
require('mz/fs').unlink(bufferFile)
|
||||
.catch(_.noop)
|
||||
.tap ({ image: imageName, buildId }) ->
|
||||
logging.logSuccess(logStreams, "Successfully deployed image: #{formatImageName(imageName)}")
|
||||
return buildId
|
||||
.then ({ image: imageName, buildId }) ->
|
||||
if logs is '' or options.nologupload?
|
||||
return ''
|
||||
if build
|
||||
dockerUtils.runBuild(params, options, getBundleInfo, logStreams)
|
||||
else
|
||||
{ image: imageName, log: '' }
|
||||
.then ({ image: imageName, log: buildLogs }) ->
|
||||
logging.logInfo(logStreams, 'Initializing deploy...')
|
||||
|
||||
logging.logInfo(logStreams, 'Uploading logs to dashboard...')
|
||||
logs = buildLogs
|
||||
Promise.all [
|
||||
dockerUtils.bufferImage(docker, imageName, bufferFile)
|
||||
token
|
||||
username
|
||||
url
|
||||
params.appName
|
||||
logStreams
|
||||
]
|
||||
.spread(performUpload)
|
||||
.finally ->
|
||||
# If the file was never written to (for instance because an error
|
||||
# has occured before any data was written) this call will throw an
|
||||
# ugly error, just suppress it
|
||||
Promise.try ->
|
||||
require('mz/fs').unlink(bufferFile)
|
||||
.catch(_.noop)
|
||||
.tap ({ image: imageName, buildId }) ->
|
||||
logging.logSuccess(logStreams, "Successfully deployed image: #{formatImageName(imageName)}")
|
||||
return buildId
|
||||
.then ({ image: imageName, buildId }) ->
|
||||
if logs is '' or options.nologupload?
|
||||
return ''
|
||||
|
||||
Promise.join(
|
||||
logs
|
||||
token
|
||||
url
|
||||
buildId
|
||||
username
|
||||
params.appName
|
||||
uploadLogs
|
||||
)
|
||||
.return('Successfully uploaded logs')
|
||||
.then (msg) ->
|
||||
logging.logSuccess(logStreams, msg) if msg isnt ''
|
||||
.asCallback(done)
|
||||
logging.logInfo(logStreams, 'Uploading logs to dashboard...')
|
||||
|
||||
Promise.join(
|
||||
logs
|
||||
token
|
||||
url
|
||||
buildId
|
||||
username
|
||||
params.appName
|
||||
uploadLogs
|
||||
)
|
||||
.return('Successfully uploaded logs')
|
||||
.then (msg) ->
|
||||
logging.logSuccess(logStreams, msg) if msg isnt ''
|
||||
.asCallback(done)
|
||||
|
||||
Promise.join(
|
||||
resin.auth.getToken()
|
||||
|
@ -70,36 +70,47 @@ exports.appendOptions = (opts) ->
|
||||
]
|
||||
|
||||
exports.generateConnectOpts = generateConnectOpts = (opts) ->
|
||||
connectOpts = {}
|
||||
# Firsly need to decide between a local docker socket
|
||||
# and a host available over a host:port combo
|
||||
if opts.docker? and not opts.dockerHost?
|
||||
# good, local docker socket
|
||||
connectOpts.socketPath = opts.docker
|
||||
else if opts.dockerHost? and not opts.docker?
|
||||
# Good a host is provided, and local socket isn't
|
||||
connectOpts.host = opts.dockerHost
|
||||
connectOpts.port = opts.dockerPort || 2376
|
||||
else if opts.docker? and opts.dockerHost?
|
||||
# Both provided, no obvious way to continue
|
||||
throw new Error("Both a local docker socket and docker host have been provided. Don't know how to continue.")
|
||||
else
|
||||
# None provided, assume default docker local socket
|
||||
connectOpts.socketPath = '/var/run/docker.sock'
|
||||
Promise = require('bluebird')
|
||||
fs = require('mz/fs')
|
||||
_ = require('lodash')
|
||||
|
||||
# Now need to check if the user wants to connect over TLS
|
||||
# to the host
|
||||
Promise.try ->
|
||||
connectOpts = {}
|
||||
# Firsly need to decide between a local docker socket
|
||||
# and a host available over a host:port combo
|
||||
if opts.docker? and not opts.dockerHost?
|
||||
# good, local docker socket
|
||||
connectOpts.socketPath = opts.docker
|
||||
else if opts.dockerHost? and not opts.docker?
|
||||
# Good a host is provided, and local socket isn't
|
||||
connectOpts.host = opts.dockerHost
|
||||
connectOpts.port = opts.dockerPort || 2376
|
||||
else if opts.docker? and opts.dockerHost?
|
||||
# Both provided, no obvious way to continue
|
||||
throw new Error("Both a local docker socket and docker host have been provided. Don't know how to continue.")
|
||||
else
|
||||
# None provided, assume default docker local socket
|
||||
connectOpts.socketPath = '/var/run/docker.sock'
|
||||
|
||||
# If any are set...
|
||||
if (opts.ca? or opts.cert? or opts.key?)
|
||||
# but not all
|
||||
if not (opts.ca? and opts.cert? and opts.key?)
|
||||
throw new Error('You must provide a CA, certificate and key in order to use TLS')
|
||||
connectOpts.ca = opts.ca
|
||||
connectOpts.cert = opts.cert
|
||||
connectOpts.key = opts.key
|
||||
# Now need to check if the user wants to connect over TLS
|
||||
# to the host
|
||||
|
||||
return connectOpts
|
||||
# If any are set...
|
||||
if (opts.ca? or opts.cert? or opts.key?)
|
||||
# but not all
|
||||
if not (opts.ca? and opts.cert? and opts.key?)
|
||||
throw new Error('You must provide a CA, certificate and key in order to use TLS')
|
||||
|
||||
certBodies = {
|
||||
ca: fs.readFile(opts.ca, 'utf-8')
|
||||
cert: fs.readFile(opts.cert, 'utf-8')
|
||||
key: fs.readFile(opts.key, 'utf-8')
|
||||
}
|
||||
return Promise.props(certBodies)
|
||||
.then (toMerge) ->
|
||||
_.merge(connectOpts, toMerge)
|
||||
|
||||
return connectOpts
|
||||
|
||||
exports.tarDirectory = tarDirectory = (dir) ->
|
||||
Promise = require('bluebird')
|
||||
@ -262,24 +273,25 @@ exports.runBuild = (params, options, getBundleInfo, logStreams) ->
|
||||
.pipe(logStreams.build)
|
||||
|
||||
# Create a builder
|
||||
connectOpts = generateConnectOpts(options)
|
||||
generateConnectOpts(options)
|
||||
.then (connectOpts) ->
|
||||
|
||||
# Allow degugging output, hidden behind an env var
|
||||
logging.logDebug(logStreams, 'Connecting with the following options:')
|
||||
logging.logDebug(logStreams, JSON.stringify(connectOpts, null, ' '))
|
||||
# Allow degugging output, hidden behind an env var
|
||||
logging.logDebug(logStreams, 'Connecting with the following options:')
|
||||
logging.logDebug(logStreams, JSON.stringify(connectOpts, null, ' '))
|
||||
|
||||
builder = new dockerBuild.Builder(connectOpts)
|
||||
opts = {}
|
||||
builder = new dockerBuild.Builder(connectOpts)
|
||||
opts = {}
|
||||
|
||||
if options.tag?
|
||||
opts['t'] = options.tag
|
||||
if options.nocache?
|
||||
opts['nocache'] = true
|
||||
if options.buildArg?
|
||||
opts['buildargs'] = parseBuildArgs options.buildArg, (arg) ->
|
||||
logging.logWarn(logStreams, "Could not parse variable: '#{arg}'")
|
||||
if options.tag?
|
||||
opts['t'] = options.tag
|
||||
if options.nocache?
|
||||
opts['nocache'] = true
|
||||
if options.buildArg?
|
||||
opts['buildargs'] = parseBuildArgs options.buildArg, (arg) ->
|
||||
logging.logWarn(logStreams, "Could not parse variable: '#{arg}'")
|
||||
|
||||
builder.createBuildStream(opts, hooks, reject)
|
||||
builder.createBuildStream(opts, hooks, reject)
|
||||
|
||||
# Given an image id or tag, export the image to a tar archive,
|
||||
# gzip the result, and buffer it to disk.
|
||||
@ -298,10 +310,12 @@ exports.bufferImage = (docker, imageId, bufferFile) ->
|
||||
exports.getDocker = (options) ->
|
||||
Docker = require('dockerode')
|
||||
Promise = require('bluebird')
|
||||
connectOpts = generateConnectOpts(options)
|
||||
# Use bluebird's promises
|
||||
connectOpts['Promise'] = Promise
|
||||
new Docker(connectOpts)
|
||||
|
||||
generateConnectOpts(options)
|
||||
.then (connectOpts) ->
|
||||
# Use bluebird's promises
|
||||
connectOpts['Promise'] = Promise
|
||||
new Docker(connectOpts)
|
||||
|
||||
hasQemu = ->
|
||||
fs = require('mz/fs')
|
||||
|
Loading…
x
Reference in New Issue
Block a user