Add /v1/images/load endpoint

This commit is contained in:
Pablo Carranza Velez 2016-05-18 13:47:54 -03:00
parent ebf2c04a08
commit 95f4fdb97f
2 changed files with 58 additions and 33 deletions

View File

@ -171,6 +171,7 @@ module.exports = (application) ->
res.json(device.getState())
unparsedRouter.post '/v1/images/create', dockerUtils.createImage
unparsedRouter.post '/v1/images/load', dockerUtils.loadImage
unparsedRouter.delete '/v1/images/*', dockerUtils.deleteImage
unparsedRouter.get '/v1/images', dockerUtils.listImages
parsedRouter.post '/v1/containers/create', dockerUtils.createContainer

View File

@ -61,39 +61,6 @@ findSimilarImage = (repoTag) ->
DELTA_OUT_OF_SYNC_CODES = [23, 24]
DELTA_REQUEST_TIMEOUT = 15 * 60 * 1000
exports.rsyncImageWithProgress = (imgDest, onProgress, startFromEmpty = false) ->
Promise.try ->
if startFromEmpty
return 'resin/scratch'
findSimilarImage(imgDest)
.then (imgSrc) ->
rsyncDiff = new Promise (resolve, reject) ->
progress request.get("#{config.deltaHost}/api/v1/delta?src=#{imgSrc}&dest=#{imgDest}", timeout: DELTA_REQUEST_TIMEOUT)
.on 'progress', (progress) ->
onProgress(percentage: progress.percent)
.on 'end', ->
onProgress(percentage: 100)
.on 'response', (res) ->
if res.statusCode isnt 200
reject(new Error("Got #{res.statusCode} when requesting image from delta server."))
else
resolve(res)
.on 'error', reject
.pause()
imageConfig = request.getAsync("#{config.deltaHost}/api/v1/config?image=#{imgDest}", {json: true, timeout: 0})
.spread ({statusCode}, imageConfig) ->
if statusCode isnt 200
throw new Error("Invalid configuration: #{imageConfig}")
return imageConfig
return [ rsyncDiff, imageConfig, imgSrc ]
.spread (rsyncDiff, imageConfig, imgSrc) ->
dockerSync(imgSrc, imgDest, rsyncDiff, imageConfig)
.catch OutOfSyncError, (err) ->
console.log('Falling back to delta-from-empty')
exports.rsyncImageWithProgress(imgDest, onProgress, true)
getRepoAndTag = (image) ->
getRegistryAndName(image)
.then ({ registry, imageName, tagName }) ->
@ -156,6 +123,42 @@ do ->
.disposer (release) ->
release()
exports.rsyncImageWithProgress = (imgDest, onProgress, startFromEmpty = false) ->
imagesBeingFetched++
Promise.try ->
if startFromEmpty
return 'resin/scratch'
findSimilarImage(imgDest)
.then (imgSrc) ->
rsyncDiff = new Promise (resolve, reject) ->
progress request.get("#{config.deltaHost}/api/v1/delta?src=#{imgSrc}&dest=#{imgDest}", timeout: DELTA_REQUEST_TIMEOUT)
.on 'progress', (progress) ->
onProgress(percentage: progress.percent)
.on 'end', ->
onProgress(percentage: 100)
.on 'response', (res) ->
if res.statusCode isnt 200
reject(new Error("Got #{res.statusCode} when requesting image from delta server."))
else
resolve(res)
.on 'error', reject
.pause()
imageConfig = request.getAsync("#{config.deltaHost}/api/v1/config?image=#{imgDest}", {json: true, timeout: 0})
.spread ({statusCode}, imageConfig) ->
if statusCode isnt 200
throw new Error("Invalid configuration: #{imageConfig}")
return imageConfig
return [ rsyncDiff, imageConfig, imgSrc ]
.spread (rsyncDiff, imageConfig, imgSrc) ->
dockerSync(imgSrc, imgDest, rsyncDiff, imageConfig)
.catch OutOfSyncError, (err) ->
console.log('Falling back to delta-from-empty')
exports.rsyncImageWithProgress(imgDest, onProgress, true)
.finally ->
imagesBeingFetched--
# Keep track of the images being fetched, so we don't clean them up whilst fetching.
imagesBeingFetched = 0
exports.fetchImageWithProgress = (image, onProgress) ->
@ -261,6 +264,27 @@ do ->
.catch (err) ->
res.status(500).send(err?.message or err or 'Unknown error')
exports.loadImage = (req, res) ->
if imagesBeingFetched > 0
res.status(500).send('Cannot load an image while the supervisor is pulling an update')
return
Promise.using lockImages(), ->
docker.listImagesAsync()
.then (oldImages) ->
docker.loadImageAsync(req)
.then ->
docker.listImagesAsync()
.then (newImages) ->
oldTags = _.flatten(_.map(oldImages, 'RepoTags'))
newTags = _.flatten(_.map(newImages, 'RepoTags'))
createdTags = _.difference(newTags, oldTags)
Promise.map createdTags, (repoTag) ->
knex('image').insert({ repoTag })
.then ->
res.sendStatus(200)
.catch (err) ->
res.status(500).send(err?.message or err or 'Unknown error')
exports.deleteImage = (req, res) ->
imageName = req.params[0]
Promise.using lockImages(), ->