Gzip images when uploading in resin deploy

Change-Type: minor
Connects-To: #549
This commit is contained in:
Tim Perry 2017-06-13 19:28:37 +02:00
parent 90a5b15dbc
commit e584dc43f7
7 changed files with 54 additions and 25 deletions

View File

@ -8,7 +8,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added
- `package-lock.json` for `npm5` users
- Added ability to run an emulated build silently with resin build
- Added ability to run an emulated build silently with `resin build`
- Gzip images when uploading in `resin deploy`
### Fixed

View File

@ -95,17 +95,20 @@ getBundleInfo = function(options) {
});
};
performUpload = function(imageStream, token, username, url, size, appName, logStreams) {
performUpload = function(gzippedImage, token, username, url, appName, logStreams) {
var request, uploadRequest;
request = require('request');
uploadRequest = request.post({
url: getBuilderPushEndpoint(url, username, appName),
headers: {
'Content-Encoding': 'gzip'
},
auth: {
bearer: token
},
body: imageStream
body: gzippedImage.stream
});
return uploadToPromise(uploadRequest, size, logStreams);
return uploadToPromise(uploadRequest, gzippedImage.size, logStreams);
};
uploadLogs = function(logs, token, url, buildId, username, appName) {
@ -216,7 +219,7 @@ module.exports = {
var buildLogs, imageName;
imageName = arg1.image, buildLogs = arg1.log;
logs = buildLogs;
return Promise.join(dockerUtils.bufferImage(docker, imageName, bufferFile), token, username, url, dockerUtils.getImageSize(docker, imageName), params.appName, logStreams, performUpload);
return Promise.all([dockerUtils.gzipAndBufferImage(docker, imageName, bufferFile), token, username, url, params.appName, logStreams]).spread(performUpload);
})["finally"](function() {
return require('mz/fs').unlink(bufferFile)["catch"](_.noop);
});

View File

@ -273,12 +273,25 @@ exports.runBuild = function(params, options, getBundleInfo, logStreams) {
});
};
exports.bufferImage = function(docker, imageId, bufferFile) {
var image, streamUtils;
exports.gzipAndBufferImage = function(docker, imageId, bufferFile) {
var fs, image, streamUtils, zlib;
streamUtils = require('./streams');
zlib = require('zlib');
fs = require('mz/fs');
image = docker.getImage(imageId);
return image.get().then(function(img) {
return streamUtils.buffer(img, bufferFile);
return image.get().then(function(imageStream) {
var gzippedStream;
gzippedStream = imageStream.pipe(zlib.createGzip());
return streamUtils.buffer(gzippedStream, bufferFile);
}).then(function(bufferedStream) {
return fs.stat(bufferFile).then(function(stats) {
var size;
size = stats.size;
return {
stream: bufferedStream,
size: stats.size
};
});
});
};

View File

@ -2,7 +2,7 @@
exports.buffer = function(stream, bufferFile) {
var Promise, fileWriteStream, fs;
Promise = require('bluebird');
fs = require('mz/fs');
fs = require('fs');
fileWriteStream = fs.createWriteStream(bufferFile);
return new Promise(function(resolve, reject) {
return stream.on('error', reject).on('end', resolve).pipe(fileWriteStream);

View File

@ -65,15 +65,17 @@ getBundleInfo = (options) ->
.then (app) ->
[app.arch, app.device_type]
performUpload = (imageStream, token, username, url, size, appName, logStreams) ->
performUpload = (gzippedImage, token, username, url, appName, logStreams) ->
request = require('request')
uploadRequest = request.post
url: getBuilderPushEndpoint(url, username, appName)
headers:
'Content-Encoding': 'gzip'
auth:
bearer: token
body: imageStream
body: gzippedImage.stream
uploadToPromise(uploadRequest, size, logStreams)
uploadToPromise(uploadRequest, gzippedImage.size, logStreams)
uploadLogs = (logs, token, url, buildId, username, appName) ->
request = require('request')
@ -186,16 +188,15 @@ module.exports =
{ image: imageName, log: '' }
.then ({ image: imageName, log: buildLogs }) ->
logs = buildLogs
Promise.join(
dockerUtils.bufferImage(docker, imageName, bufferFile)
Promise.all [
dockerUtils.gzipAndBufferImage(docker, imageName, bufferFile)
token
username
url
dockerUtils.getImageSize(docker, imageName)
params.appName
logStreams
performUpload
)
]
.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

View File

@ -281,16 +281,27 @@ exports.runBuild = (params, options, getBundleInfo, logStreams) ->
builder.createBuildStream(opts, hooks, reject)
# Given an image id or tag, export the image to a tar archive.
# Also needs the options generated by the appendOptions()
# function, and a tmpFile to buffer the data into.
exports.bufferImage = (docker, imageId, bufferFile) ->
# Given an image id or tag, export the image to a tar archive,
# gzip the result, and buffer it to disk.
# Returns a { stream, size } object
exports.gzipAndBufferImage = (docker, imageId, bufferFile) ->
streamUtils = require('./streams')
zlib = require('zlib')
fs = require('mz/fs')
image = docker.getImage(imageId)
image.get()
.then (img) ->
streamUtils.buffer(img, bufferFile)
.then (imageStream) ->
gzippedStream = imageStream.pipe(zlib.createGzip())
streamUtils.buffer(gzippedStream, bufferFile)
.then (bufferedStream) ->
fs.stat(bufferFile)
.then (stats) ->
size = stats.size
return {
stream: bufferedStream,
size: stats.size
}
exports.getDocker = (options) ->
Docker = require('dockerode')

View File

@ -1,6 +1,6 @@
exports.buffer = (stream, bufferFile) ->
Promise = require('bluebird')
fs = require('mz/fs')
fs = require('fs')
fileWriteStream = fs.createWriteStream(bufferFile)