mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-06-01 15:20:51 +00:00
Move the cleanupContainersAndImages
code into the docker utils, and make use of a count of currently fetching images to only clean up images if we aren't fetching any.
This commit is contained in:
parent
07a4df1d05
commit
00d725cfac
@ -253,7 +253,7 @@ exports.update = update = ->
|
|||||||
updateDeviceInfo(status: 'Cleaning old images')
|
updateDeviceInfo(status: 'Cleaning old images')
|
||||||
# We cleanup here as we want a point when we have a consistent apps/images state, rather than potentially at a
|
# We cleanup here as we want a point when we have a consistent apps/images state, rather than potentially at a
|
||||||
# point where we might clean up an image we still want.
|
# point where we might clean up an image we still want.
|
||||||
cleanupContainersAndImages()
|
dockerUtils.cleanupContainersAndImages()
|
||||||
.catch (err) ->
|
.catch (err) ->
|
||||||
failedUpdates++
|
failedUpdates++
|
||||||
if currentlyUpdating is 2
|
if currentlyUpdating is 2
|
||||||
@ -299,34 +299,3 @@ exports.updateDeviceInfo = updateDeviceInfo = (body) ->
|
|||||||
.catch (error) ->
|
.catch (error) ->
|
||||||
utils.mixpanelTrack('Device info update failure', {error, body})
|
utils.mixpanelTrack('Device info update failure', {error, body})
|
||||||
|
|
||||||
cleanupContainersAndImages = ->
|
|
||||||
knex('app').select()
|
|
||||||
.map (app) ->
|
|
||||||
app.imageId + ':latest'
|
|
||||||
.then (apps) ->
|
|
||||||
# Make sure not to delete the supervisor image!
|
|
||||||
apps.push(config.localImage + ':latest')
|
|
||||||
apps.push(config.remoteImage + ':latest')
|
|
||||||
|
|
||||||
# Cleanup containers first, so that they don't block image removal.
|
|
||||||
docker.listContainersAsync(all: true)
|
|
||||||
.filter (containerInfo) ->
|
|
||||||
!_.contains(apps, containerInfo.Image)
|
|
||||||
.map (containerInfo) ->
|
|
||||||
docker.getContainer(containerInfo.Id).removeAsync()
|
|
||||||
.then ->
|
|
||||||
console.log('Deleted container:', containerInfo.Id, containerInfo.Image)
|
|
||||||
.catch (err) ->
|
|
||||||
console.log('Error deleting container:', containerInfo.Id, containerInfo.Image, err)
|
|
||||||
.then ->
|
|
||||||
# And then clean up the images.
|
|
||||||
docker.listImagesAsync()
|
|
||||||
.filter (image) ->
|
|
||||||
!_.any image.RepoTags, (imageId) ->
|
|
||||||
_.contains(apps, imageId)
|
|
||||||
.map (image) ->
|
|
||||||
docker.getImage(image.Id).removeAsync()
|
|
||||||
.then ->
|
|
||||||
console.log('Deleted image:', image.Id, image.RepoTags)
|
|
||||||
.catch (err) ->
|
|
||||||
console.log('Error deleting image:', image.Id, image.RepoTags, err)
|
|
||||||
|
@ -3,6 +3,8 @@ Promise = require 'bluebird'
|
|||||||
config = require './config'
|
config = require './config'
|
||||||
JSONStream = require 'JSONStream'
|
JSONStream = require 'JSONStream'
|
||||||
es = require 'event-stream'
|
es = require 'event-stream'
|
||||||
|
_ = require 'lodash'
|
||||||
|
knex = require './db'
|
||||||
|
|
||||||
docker = Promise.promisifyAll(new Docker(socketPath: config.dockerSocket))
|
docker = Promise.promisifyAll(new Docker(socketPath: config.dockerSocket))
|
||||||
# Hack dockerode to promisify internal classes' prototypes
|
# Hack dockerode to promisify internal classes' prototypes
|
||||||
@ -10,16 +12,56 @@ Promise.promisifyAll(docker.getImage().__proto__)
|
|||||||
Promise.promisifyAll(docker.getContainer().__proto__)
|
Promise.promisifyAll(docker.getContainer().__proto__)
|
||||||
|
|
||||||
exports.docker = docker
|
exports.docker = docker
|
||||||
exports.fetchImage = (image) ->
|
|
||||||
docker.createImageAsync(fromImage: image)
|
|
||||||
.then (stream) ->
|
|
||||||
return new Promise (resolve, reject) ->
|
|
||||||
if stream.headers['content-type'] is 'application/json'
|
|
||||||
stream.pipe(JSONStream.parse('error'))
|
|
||||||
.pipe(es.mapSync(reject))
|
|
||||||
else
|
|
||||||
stream.pipe es.wait (error, text) ->
|
|
||||||
if error
|
|
||||||
reject(text)
|
|
||||||
|
|
||||||
stream.on('end', resolve)
|
do ->
|
||||||
|
# Keep track of the images being fetched, so we don't clean them up whilst fetching.
|
||||||
|
imagesBeingFetched = 0
|
||||||
|
exports.fetchImage = (image) ->
|
||||||
|
imagesBeingFetched++
|
||||||
|
docker.createImageAsync(fromImage: image)
|
||||||
|
.then (stream) ->
|
||||||
|
return new Promise (resolve, reject) ->
|
||||||
|
if stream.headers['content-type'] is 'application/json'
|
||||||
|
stream.pipe(JSONStream.parse('error'))
|
||||||
|
.pipe(es.mapSync(reject))
|
||||||
|
else
|
||||||
|
stream.pipe es.wait (error, text) ->
|
||||||
|
if error
|
||||||
|
reject(text)
|
||||||
|
|
||||||
|
stream.on('end', resolve)
|
||||||
|
.finally ->
|
||||||
|
imagesBeingFetched--
|
||||||
|
|
||||||
|
exports.cleanupContainersAndImages = ->
|
||||||
|
knex('app').select()
|
||||||
|
.map (app) ->
|
||||||
|
app.imageId + ':latest'
|
||||||
|
.then (apps) ->
|
||||||
|
# Make sure not to delete the supervisor image!
|
||||||
|
apps.push(config.localImage + ':latest')
|
||||||
|
apps.push(config.remoteImage + ':latest')
|
||||||
|
|
||||||
|
# Cleanup containers first, so that they don't block image removal.
|
||||||
|
docker.listContainersAsync(all: true)
|
||||||
|
.filter (containerInfo) ->
|
||||||
|
!_.contains(apps, containerInfo.Image)
|
||||||
|
.map (containerInfo) ->
|
||||||
|
docker.getContainer(containerInfo.Id).removeAsync()
|
||||||
|
.then ->
|
||||||
|
console.log('Deleted container:', containerInfo.Id, containerInfo.Image)
|
||||||
|
.catch (err) ->
|
||||||
|
console.log('Error deleting container:', containerInfo.Id, containerInfo.Image, err)
|
||||||
|
.then ->
|
||||||
|
# And then clean up the images, as long as we aren't currently trying to fetch any.
|
||||||
|
return if imagesBeingFetched > 0
|
||||||
|
docker.listImagesAsync()
|
||||||
|
.filter (image) ->
|
||||||
|
!_.any image.RepoTags, (imageId) ->
|
||||||
|
_.contains(apps, imageId)
|
||||||
|
.map (image) ->
|
||||||
|
docker.getImage(image.Id).removeAsync()
|
||||||
|
.then ->
|
||||||
|
console.log('Deleted image:', image.Id, image.RepoTags)
|
||||||
|
.catch (err) ->
|
||||||
|
console.log('Error deleting image:', image.Id, image.RepoTags, err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user