mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2024-12-20 06:07:57 +00:00
local mode: Add local mode manager module to handle cleanup
Change-type: minor Signed-off-by: Cameron Diver <cameron@resin.io>
This commit is contained in:
parent
3e665c0f4a
commit
5906e1427c
@ -9,6 +9,7 @@ path = require 'path'
|
||||
constants = require './lib/constants'
|
||||
|
||||
Docker = require './lib/docker-utils'
|
||||
{ LocalModeManager } = require './local-mode'
|
||||
updateLock = require './lib/update-lock'
|
||||
{ checkTruthy, checkInt, checkString } = require './lib/validation'
|
||||
{ NotFoundError } = require './lib/errors'
|
||||
@ -72,6 +73,7 @@ module.exports = class ApplicationManager extends EventEmitter
|
||||
@networks = new NetworkManager({ @docker, @logger })
|
||||
@volumes = new Volumes({ @docker, @logger })
|
||||
@proxyvisor = new Proxyvisor({ @config, @logger, @db, @docker, @images, applications: this })
|
||||
@localModeManager = new LocalModeManager(@config, @docker, @logger, @db)
|
||||
@timeSpentFetching = 0
|
||||
@fetchesInProgress = 0
|
||||
@_targetVolatilePerImageId = {}
|
||||
@ -181,6 +183,8 @@ module.exports = class ApplicationManager extends EventEmitter
|
||||
|
||||
init: =>
|
||||
@images.cleanupDatabase()
|
||||
.then =>
|
||||
@localModeManager.init()
|
||||
.then =>
|
||||
@services.attachToRunning()
|
||||
.then =>
|
||||
|
86
src/local-mode.ts
Normal file
86
src/local-mode.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import * as Bluebird from 'bluebird';
|
||||
import * as Docker from 'dockerode';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import Config = require('./config');
|
||||
import Database = require('./db');
|
||||
import { checkTruthy } from './lib/validation';
|
||||
import { Logger } from './logger';
|
||||
|
||||
/**
|
||||
* This class handles any special cases necessary for switching
|
||||
* modes in localMode.
|
||||
*
|
||||
* Currently this is needed because of inconsistencies in the way
|
||||
* that the state machine handles local mode and normal operation.
|
||||
* We should aim to remove these inconsistencies in the future.
|
||||
*/
|
||||
export class LocalModeManager {
|
||||
public constructor(
|
||||
public config: Config,
|
||||
public docker: Docker,
|
||||
public logger: Logger,
|
||||
public db: Database,
|
||||
) { }
|
||||
|
||||
public async init() {
|
||||
// Setup a listener to catch state changes relating to local mode
|
||||
this.config.on('change', (changed) => {
|
||||
if (changed.localMode != null) {
|
||||
const localMode = checkTruthy(changed.localMode) || false;
|
||||
|
||||
// First switch the logger to it's correct state
|
||||
this.logger.switchBackend(localMode);
|
||||
|
||||
// If we're leaving local mode, make sure to remove all of the
|
||||
// leftover artifacts
|
||||
if (!localMode) {
|
||||
this.removeLocalModeArtifacts();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const localMode = checkTruthy(await this.config.get('localMode') || false);
|
||||
if (!localMode) {
|
||||
// Remove any leftovers if necessary
|
||||
await this.removeLocalModeArtifacts();
|
||||
}
|
||||
}
|
||||
|
||||
public async removeLocalModeArtifacts(): Promise<void> {
|
||||
try {
|
||||
const images = await this.getLocalModeImages();
|
||||
const containers = await this.getLocalModeContainers(images);
|
||||
|
||||
await Bluebird.map(containers, (containerId) => {
|
||||
console.log('Removing local mode container: ', containerId);
|
||||
return this.docker.getContainer(containerId).remove({ force: true });
|
||||
});
|
||||
await Bluebird.map(images, (imageId) => {
|
||||
console.log('Removing local mode image: ', imageId);
|
||||
return this.docker.getImage(imageId).remove({ force: true });
|
||||
});
|
||||
|
||||
// Remove any local mode state added to the database
|
||||
await this.db.models('app').del().where({ source: 'local' });
|
||||
} catch (e) {
|
||||
console.log('There was an error clearing local mode artifacts: ', e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async getLocalModeImages(): Promise<string[]> {
|
||||
// Return all local mode images present on the local docker daemon
|
||||
return _.map(await this.docker.listImages({ filters: { label: [ 'io.resin.local.image=1' ] } }), 'Id');
|
||||
}
|
||||
|
||||
private async getLocalModeContainers(localModeImageIds: string[]): Promise<string[]> {
|
||||
return _(await this.docker.listContainers())
|
||||
.filter(({ Image }) => _.includes(localModeImageIds, Image))
|
||||
.map('Id')
|
||||
.value();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default LocalModeManager;
|
@ -60,11 +60,6 @@ module.exports = class Supervisor extends EventEmitter
|
||||
enableLogs: checkTruthy(conf.loggingEnabled),
|
||||
localMode: checkTruthy(conf.localMode)
|
||||
})
|
||||
|
||||
# Setup log backend switching for local mode changes
|
||||
@config.on 'change', (changed) =>
|
||||
if changed.localMode?
|
||||
@logger.switchBackend(checkTruthy(changed.localMode))
|
||||
.then =>
|
||||
@deviceState.init()
|
||||
.then =>
|
||||
|
Loading…
Reference in New Issue
Block a user