mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-02-21 01:42:26 +00:00
Read ca files and convert to string before passing to the docker daemon
Before this commit, the docker daemon would recieve the filename of the .pem files, which would be interpreted as the body and would fail. This commit ensures that the actual body of the pem files are sent to the daemon. Change-type: patch Connects-to: #562 Signed-off-by: Cameron Diver <cameron@resin.io>
This commit is contained in:
parent
378f894da3
commit
5000febf72
@ -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