mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-02-21 02:01:35 +00:00
Merge pull request #405 from resin-io/404_authentication_for_registry_and_delta
404 authentication for registry and delta
This commit is contained in:
commit
5c207dc4b3
@ -20,7 +20,7 @@
|
||||
"body-parser": "^1.12.0",
|
||||
"buffer-equal-constant-time": "^1.0.1",
|
||||
"docker-delta": "1.0.1",
|
||||
"docker-progress": "^2.3.3",
|
||||
"docker-progress": "^2.5.0",
|
||||
"docker-toolbelt": "^1.3.0",
|
||||
"dockerode": "~2.2.9",
|
||||
"event-stream": "^3.0.20",
|
||||
|
@ -7,7 +7,7 @@ dockerUtils = require './docker-utils'
|
||||
Promise = require 'bluebird'
|
||||
utils = require './utils'
|
||||
logger = require './lib/logger'
|
||||
{ cachedResinApi } = require './request'
|
||||
{ cachedResinApi, request } = require './request'
|
||||
device = require './device'
|
||||
lockFile = Promise.promisifyAll(require('lockfile'))
|
||||
bootstrap = require './bootstrap'
|
||||
@ -215,15 +215,15 @@ fetch = (app, setDeviceUpdateState = true) ->
|
||||
|
||||
Promise.try ->
|
||||
conf = JSON.parse(app.config)
|
||||
|
||||
if conf['RESIN_SUPERVISOR_DELTA'] == '1'
|
||||
logSystemEvent(logTypes.downloadAppDelta, app)
|
||||
requestTimeout = checkInt(conf['RESIN_SUPERVISOR_DELTA_REQUEST_TIMEOUT'], positive: true) ? 30 * 60 * 1000
|
||||
totalTimeout = checkInt(conf['RESIN_SUPERVISOR_DELTA_TOTAL_TIMEOUT'], positive: true) ? 24 * 60 * 60 * 1000
|
||||
dockerUtils.rsyncImageWithProgress(app.imageId, { requestTimeout, totalTimeout }, onProgress)
|
||||
else
|
||||
logSystemEvent(logTypes.downloadApp, app)
|
||||
dockerUtils.fetchImageWithProgress(app.imageId, onProgress)
|
||||
Promise.join utils.getConfig('apiKey'), utils.getConfig('uuid'), (apiKey, uuid) ->
|
||||
if conf['RESIN_SUPERVISOR_DELTA'] == '1'
|
||||
logSystemEvent(logTypes.downloadAppDelta, app)
|
||||
requestTimeout = checkInt(conf['RESIN_SUPERVISOR_DELTA_REQUEST_TIMEOUT'], positive: true) ? 30 * 60 * 1000
|
||||
totalTimeout = checkInt(conf['RESIN_SUPERVISOR_DELTA_TOTAL_TIMEOUT'], positive: true) ? 24 * 60 * 60 * 1000
|
||||
dockerUtils.rsyncImageWithProgress(app.imageId, { requestTimeout, totalTimeout, uuid, apiKey }, onProgress)
|
||||
else
|
||||
logSystemEvent(logTypes.downloadApp, app)
|
||||
dockerUtils.fetchImageWithProgress(app.imageId, onProgress, { uuid, apiKey })
|
||||
.then ->
|
||||
logSystemEvent(logTypes.downloadAppSuccess, app)
|
||||
device.updateState(status: 'Idle', download_progress: null)
|
||||
|
@ -62,7 +62,7 @@ do ->
|
||||
.disposer (release) ->
|
||||
release()
|
||||
|
||||
exports.rsyncImageWithProgress = (imgDest, { requestTimeout, totalTimeout, startFromEmpty = false }, onProgress) ->
|
||||
exports.rsyncImageWithProgress = (imgDest, { requestTimeout, totalTimeout, uuid, apiKey, startFromEmpty = false }, onProgress) ->
|
||||
Promise.using readLockImages(), ->
|
||||
Promise.try ->
|
||||
if startFromEmpty
|
||||
@ -70,26 +70,51 @@ do ->
|
||||
findSimilarImage(imgDest)
|
||||
.then (imgSrc) ->
|
||||
new Promise (resolve, reject) ->
|
||||
progress request.get("#{config.deltaHost}/api/v2/delta?src=#{imgSrc}&dest=#{imgDest}", timeout: requestTimeout)
|
||||
.on 'progress', (progress) ->
|
||||
# In request-progress ^2.0.1, "percentage" is a ratio from 0 to 1
|
||||
onProgress(percentage: progress.percentage * 100)
|
||||
.on 'end', ->
|
||||
onProgress(percentage: 100)
|
||||
.on 'response', (res) ->
|
||||
if res.statusCode is 504
|
||||
reject(new Error('Delta server is still processing the delta, will retry'))
|
||||
else if res.statusCode isnt 200
|
||||
reject(new Error("Got #{res.statusCode} when requesting image from delta server."))
|
||||
else
|
||||
if imgSrc is 'resin/scratch'
|
||||
deltaSrc = null
|
||||
else
|
||||
deltaSrc = imgSrc
|
||||
res.pipe(dockerDelta.applyDelta(deltaSrc, imgDest))
|
||||
.on('id', resolve)
|
||||
.on('error', reject)
|
||||
.on 'error', reject
|
||||
Promise.join docker.getRegistryAndName(imgDest), docker.getRegistryAndName(imgSrc), (dstInfo, srcInfo) ->
|
||||
tokenEndpoint = "#{config.apiEndpoint}/auth/v1/token"
|
||||
authOpts =
|
||||
auth:
|
||||
user: 'd_' + uuid
|
||||
pass: apiKey
|
||||
sendImmediately: true
|
||||
url = "#{tokenEndpoint}?service=#{dstInfo.registry}&scope=repository:#{dstInfo.imageName}:pull&scope=repository:#{srcInfo.imageName}:pull"
|
||||
request.getAsync(url, authOpts)
|
||||
.spread (res, body) ->
|
||||
try
|
||||
return JSON.parse(body)
|
||||
catch e
|
||||
return {}
|
||||
.then (b) ->
|
||||
opts =
|
||||
timeout: requestTimeout
|
||||
|
||||
if b?.token?
|
||||
deltaAuthOpts =
|
||||
auth:
|
||||
bearer: b?.token
|
||||
sendImmediately: true
|
||||
opts = _.merge(opts, deltaAuthOpts)
|
||||
|
||||
progress request.get("#{config.deltaHost}/api/v2/delta?src=#{imgSrc}&dest=#{imgDest}", opts)
|
||||
.on 'progress', (progress) ->
|
||||
# In request-progress ^2.0.1, "percentage" is a ratio from 0 to 1
|
||||
onProgress(percentage: progress.percentage * 100)
|
||||
.on 'end', ->
|
||||
onProgress(percentage: 100)
|
||||
.on 'response', (res) ->
|
||||
if res.statusCode is 504
|
||||
reject(new Error('Delta server is still processing the delta, will retry'))
|
||||
else if res.statusCode isnt 200
|
||||
reject(new Error("Got #{res.statusCode} when requesting image from delta server."))
|
||||
else
|
||||
if imgSrc is 'resin/scratch'
|
||||
deltaSrc = null
|
||||
else
|
||||
deltaSrc = imgSrc
|
||||
res.pipe(dockerDelta.applyDelta(deltaSrc, imgDest))
|
||||
.on('id', resolve)
|
||||
.on('error', reject)
|
||||
.on 'error', reject
|
||||
.timeout(totalTimeout)
|
||||
.then (id) ->
|
||||
getRepoAndTag(imgDest)
|
||||
@ -97,11 +122,18 @@ do ->
|
||||
docker.getImage(id).tagAsync({ repo, tag, force: true })
|
||||
.catch dockerDelta.OutOfSyncError, (err) ->
|
||||
console.log('Falling back to delta-from-empty')
|
||||
exports.rsyncImageWithProgress(imgDest, { requestTimeout, totalTimeout, startFromEmpty: true }, onProgress)
|
||||
exports.rsyncImageWithProgress(imgDest, { requestTimeout, totalTimeout, uuid, apiKey, startFromEmpty: true }, onProgress)
|
||||
|
||||
exports.fetchImageWithProgress = (image, onProgress) ->
|
||||
exports.fetchImageWithProgress = (image, onProgress, { uuid, apiKey }) ->
|
||||
Promise.using readLockImages(), ->
|
||||
dockerProgress.pull(image, onProgress)
|
||||
docker.getRegistryAndName(image)
|
||||
.then ({ registry, imageName, tagName }) ->
|
||||
dockerOptions =
|
||||
authconfig:
|
||||
username: 'd_' + uuid,
|
||||
password: apiKey,
|
||||
serveraddress: registry
|
||||
dockerProgress.pull(image, onProgress, dockerOptions)
|
||||
|
||||
normalizeRepoTag = (image) ->
|
||||
getRepoAndTag(image)
|
||||
|
Loading…
x
Reference in New Issue
Block a user