mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-05-04 18:12:56 +00:00
Make service-manager module a singleton
Change-type: patch Signed-off-by: Cameron Diver <cameron@balena.io>
This commit is contained in:
parent
adaad786af
commit
0e8d92e08a
3
src/application-manager.d.ts
vendored
3
src/application-manager.d.ts
vendored
@ -7,7 +7,6 @@ import { ServiceAction } from './device-api/common';
|
||||
import { DeviceStatus, InstancedAppState } from './types/state';
|
||||
|
||||
import type { Image } from './compose/images';
|
||||
import ServiceManager from './compose/service-manager';
|
||||
import DeviceState from './device-state';
|
||||
|
||||
import { APIBinder } from './api-binder';
|
||||
@ -45,8 +44,6 @@ class ApplicationManager extends EventEmitter {
|
||||
public deviceState: DeviceState;
|
||||
public apiBinder: APIBinder;
|
||||
|
||||
public services: ServiceManager;
|
||||
|
||||
public proxyvisor: any;
|
||||
public timeSpentFetching: number;
|
||||
public fetchesInProgress: number;
|
||||
|
@ -21,11 +21,11 @@ import {
|
||||
|
||||
import * as dbFormat from './device-state/db-format';
|
||||
|
||||
import { ServiceManager } from './compose/service-manager';
|
||||
import * as Images from './compose/images';
|
||||
import { Network } from './compose/network';
|
||||
import * as networkManager from './compose/network-manager';
|
||||
import * as volumeManager from './compose/volume-manager';
|
||||
import * as serviceManager from './compose/service-manager';
|
||||
import * as compositionSteps from './compose/composition-steps';
|
||||
|
||||
import { Proxyvisor } from './proxyvisor';
|
||||
@ -159,7 +159,6 @@ export class ApplicationManager extends EventEmitter {
|
||||
this.deviceState = deviceState;
|
||||
this.apiBinder = apiBinder;
|
||||
|
||||
this.services = new ServiceManager();
|
||||
this.proxyvisor = new Proxyvisor({
|
||||
applications: this,
|
||||
});
|
||||
@ -171,7 +170,6 @@ export class ApplicationManager extends EventEmitter {
|
||||
|
||||
this.actionExecutors = compositionSteps.getExecutors({
|
||||
lockFn: this._lockingIfNecessary,
|
||||
services: this.services,
|
||||
applications: this,
|
||||
callbacks: {
|
||||
containerStarted: (id) => {
|
||||
@ -198,7 +196,7 @@ export class ApplicationManager extends EventEmitter {
|
||||
);
|
||||
this.router = createApplicationManagerRouter(this);
|
||||
Images.on('change', this.reportCurrentState);
|
||||
this.services.on('change', this.reportCurrentState);
|
||||
serviceManager.on('change', this.reportCurrentState);
|
||||
}
|
||||
|
||||
reportCurrentState(data) {
|
||||
@ -223,14 +221,14 @@ export class ApplicationManager extends EventEmitter {
|
||||
// But also run it in on startup
|
||||
await cleanup();
|
||||
await this.localModeManager.init();
|
||||
await this.services.attachToRunning();
|
||||
await this.services.listenToEvents();
|
||||
await serviceManager.attachToRunning();
|
||||
await serviceManager.listenToEvents();
|
||||
}
|
||||
|
||||
// Returns the status of applications and their services
|
||||
getStatus() {
|
||||
return Promise.join(
|
||||
this.services.getStatus(),
|
||||
serviceManager.getStatus(),
|
||||
Images.getStatus(),
|
||||
config.get('currentCommit'),
|
||||
function (services, images, currentCommit) {
|
||||
@ -362,7 +360,7 @@ export class ApplicationManager extends EventEmitter {
|
||||
|
||||
getCurrentForComparison() {
|
||||
return Promise.join(
|
||||
this.services.getAll(),
|
||||
serviceManager.getAll(),
|
||||
networkManager.getAll(),
|
||||
volumeManager.getAll(),
|
||||
config.get('currentCommit'),
|
||||
@ -372,7 +370,7 @@ export class ApplicationManager extends EventEmitter {
|
||||
|
||||
getCurrentApp(appId) {
|
||||
return Promise.join(
|
||||
this.services.getAllByAppId(appId),
|
||||
serviceManager.getAllByAppId(appId),
|
||||
networkManager.getAllByAppId(appId),
|
||||
volumeManager.getAllByAppId(appId),
|
||||
config.get('currentCommit'),
|
||||
@ -1339,13 +1337,13 @@ export class ApplicationManager extends EventEmitter {
|
||||
}
|
||||
|
||||
stopAll({ force = false, skipLock = false } = {}) {
|
||||
return Promise.resolve(this.services.getAll())
|
||||
return Promise.resolve(serviceManager.getAll())
|
||||
.map((service) => {
|
||||
return this._lockingIfNecessary(
|
||||
service.appId,
|
||||
{ force, skipLock },
|
||||
() => {
|
||||
return this.services
|
||||
return serviceManager
|
||||
.kill(service, { removeContainer: false, wait: true })
|
||||
.then(() => {
|
||||
delete this._containerStarted[service.containerId];
|
||||
@ -1391,7 +1389,7 @@ export class ApplicationManager extends EventEmitter {
|
||||
if (intId == null) {
|
||||
throw new Error(`Invalid id: ${id}`);
|
||||
}
|
||||
containerIdsByAppId[intId] = this.services.getContainerIdMap(intId);
|
||||
containerIdsByAppId[intId] = serviceManager.getContainerIdMap(intId);
|
||||
});
|
||||
|
||||
return config.get('localMode').then((localMode) => {
|
||||
|
@ -7,7 +7,7 @@ import type { Image } from './images';
|
||||
import * as images from './images';
|
||||
import Network from './network';
|
||||
import Service from './service';
|
||||
import ServiceManager from './service-manager';
|
||||
import * as serviceManager from './service-manager';
|
||||
import Volume from './volume';
|
||||
|
||||
import { checkTruthy } from '../lib/validation';
|
||||
@ -136,7 +136,6 @@ interface CompositionCallbacks {
|
||||
|
||||
export function getExecutors(app: {
|
||||
lockFn: LockingFn;
|
||||
services: ServiceManager;
|
||||
applications: ApplicationManager;
|
||||
callbacks: CompositionCallbacks;
|
||||
}) {
|
||||
@ -150,7 +149,7 @@ export function getExecutors(app: {
|
||||
},
|
||||
async () => {
|
||||
const wait = _.get(step, ['options', 'wait'], false);
|
||||
await app.services.kill(step.current, {
|
||||
await serviceManager.kill(step.current, {
|
||||
removeContainer: false,
|
||||
wait,
|
||||
});
|
||||
@ -166,7 +165,7 @@ export function getExecutors(app: {
|
||||
skipLock: step.skipLock || _.get(step, ['options', 'skipLock']),
|
||||
},
|
||||
async () => {
|
||||
await app.services.kill(step.current);
|
||||
await serviceManager.kill(step.current);
|
||||
app.callbacks.containerKilled(step.current.containerId);
|
||||
if (_.get(step, ['options', 'removeImage'])) {
|
||||
await images.removeByDockerId(step.current.config.image);
|
||||
@ -177,7 +176,7 @@ export function getExecutors(app: {
|
||||
remove: async (step) => {
|
||||
// Only called for dead containers, so no need to
|
||||
// take locks
|
||||
await app.services.remove(step.current);
|
||||
await serviceManager.remove(step.current);
|
||||
},
|
||||
updateMetadata: (step) => {
|
||||
const skipLock =
|
||||
@ -190,7 +189,7 @@ export function getExecutors(app: {
|
||||
skipLock: skipLock || _.get(step, ['options', 'skipLock']),
|
||||
},
|
||||
async () => {
|
||||
await app.services.updateMetadata(step.current, step.target);
|
||||
await serviceManager.updateMetadata(step.current, step.target);
|
||||
},
|
||||
);
|
||||
},
|
||||
@ -202,9 +201,9 @@ export function getExecutors(app: {
|
||||
skipLock: step.skipLock || _.get(step, ['options', 'skipLock']),
|
||||
},
|
||||
async () => {
|
||||
await app.services.kill(step.current, { wait: true });
|
||||
await serviceManager.kill(step.current, { wait: true });
|
||||
app.callbacks.containerKilled(step.current.containerId);
|
||||
const container = await app.services.start(step.target);
|
||||
const container = await serviceManager.start(step.target);
|
||||
app.callbacks.containerStarted(container.id);
|
||||
},
|
||||
);
|
||||
@ -216,7 +215,7 @@ export function getExecutors(app: {
|
||||
});
|
||||
},
|
||||
start: async (step) => {
|
||||
const container = await app.services.start(step.target);
|
||||
const container = await serviceManager.start(step.target);
|
||||
app.callbacks.containerStarted(container.id);
|
||||
},
|
||||
updateCommit: async (step) => {
|
||||
@ -230,7 +229,7 @@ export function getExecutors(app: {
|
||||
skipLock: step.skipLock || _.get(step, ['options', 'skipLock']),
|
||||
},
|
||||
async () => {
|
||||
await app.services.handover(step.current, step.target);
|
||||
await serviceManager.handover(step.current, step.target);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,6 +10,7 @@ import * as db from '../db';
|
||||
import * as logger from '../logger';
|
||||
import * as images from '../compose/images';
|
||||
import * as volumeManager from '../compose/volume-manager';
|
||||
import * as serviceManager from '../compose/service-manager';
|
||||
import { spawnJournalctl } from '../lib/journald';
|
||||
import {
|
||||
appNotFoundMessage,
|
||||
@ -153,7 +154,7 @@ export function createV2Api(router: Router, applications: ApplicationManager) {
|
||||
// It's kinda hacky to access the services and db via the application manager
|
||||
// maybe refactor this code
|
||||
Bluebird.join(
|
||||
applications.services.getStatus(),
|
||||
serviceManager.getStatus(),
|
||||
images.getStatus(),
|
||||
db.models('app').select(['appId', 'commit', 'name']),
|
||||
(
|
||||
@ -359,7 +360,7 @@ export function createV2Api(router: Router, applications: ApplicationManager) {
|
||||
});
|
||||
|
||||
router.get('/v2/containerId', async (req, res) => {
|
||||
const services = await applications.services.getAll();
|
||||
const services = await serviceManager.getAll();
|
||||
|
||||
if (req.query.serviceName != null || req.query.service != null) {
|
||||
const serviceName = req.query.serviceName || req.query.service;
|
||||
@ -393,7 +394,7 @@ export function createV2Api(router: Router, applications: ApplicationManager) {
|
||||
const currentRelease = await config.get('currentCommit');
|
||||
|
||||
const pending = applications.deviceState.applyInProgress;
|
||||
const containerStates = (await applications.services.getAll()).map((svc) =>
|
||||
const containerStates = (await serviceManager.getAll()).map((svc) =>
|
||||
_.pick(
|
||||
svc,
|
||||
'status',
|
||||
|
@ -13,6 +13,7 @@ import { ApplicationManager } from '../application-manager';
|
||||
import * as config from '../config';
|
||||
import * as db from '../db';
|
||||
import * as volumeManager from '../compose/volume-manager';
|
||||
import * as serviceManager from '../compose/service-manager';
|
||||
import DeviceState from '../device-state';
|
||||
import * as constants from '../lib/constants';
|
||||
import { BackupError, DatabaseParseError, NotFoundError } from '../lib/errors';
|
||||
@ -244,7 +245,7 @@ export async function normaliseLegacyDatabase(
|
||||
}
|
||||
|
||||
log.debug('Killing legacy containers');
|
||||
await application.services.killAllLegacy();
|
||||
await serviceManager.killAllLegacy();
|
||||
log.debug('Migrating legacy app volumes');
|
||||
|
||||
const targetApps = await application.getTargetApps();
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { Router } from 'express';
|
||||
import { fs } from 'mz';
|
||||
import { stub } from 'sinon';
|
||||
|
||||
import { ApplicationManager } from '../../src/application-manager';
|
||||
import * as networkManager from '../../src/compose/network-manager';
|
||||
import { ServiceManager } from '../../src/compose/service-manager';
|
||||
import * as serviceManager from '../../src/compose/service-manager';
|
||||
import * as volumeManager from '../../src/compose/volume-manager';
|
||||
import * as config from '../../src/config';
|
||||
import * as db from '../../src/db';
|
||||
@ -135,22 +134,23 @@ function buildRoutes(appManager: ApplicationManager): Router {
|
||||
|
||||
const originalNetGetAll = networkManager.getAllByAppId;
|
||||
const originalVolGetAll = volumeManager.getAllByAppId;
|
||||
const originalSvcGetStatus = serviceManager.getStatus;
|
||||
function setupStubs() {
|
||||
stub(ServiceManager.prototype, 'getStatus').resolves(STUBBED_VALUES.services);
|
||||
|
||||
// @ts-expect-error Assigning to a RO property
|
||||
networkManager.getAllByAppId = () => Promise.resolve(STUBBED_VALUES.networks);
|
||||
networkManager.getAllByAppId = async () => STUBBED_VALUES.networks;
|
||||
// @ts-expect-error Assigning to a RO property
|
||||
volumeManager.getAllByAppId = () => Promise.resolve(STUBBED_VALUES.volumes);
|
||||
volumeManager.getAllByAppId = async () => STUBBED_VALUES.volumes;
|
||||
// @ts-expect-error Assigning to a RO property
|
||||
serviceManager.getStatus = async () => STUBBED_VALUES.services;
|
||||
}
|
||||
|
||||
function restoreStubs() {
|
||||
(ServiceManager.prototype as any).getStatus.restore();
|
||||
|
||||
// @ts-expect-error Assigning to a RO property
|
||||
networkManager.getAllByAppId = originalNetGetAll;
|
||||
// @ts-expect-error Assigning to a RO property
|
||||
volumeManager.getAllByAppId = originalVolGetAll;
|
||||
// @ts-expect-error Assigning to a RO property
|
||||
serviceManager.getStatus = originalSvcGetStatus;
|
||||
}
|
||||
|
||||
interface SupervisorAPIOpts {
|
||||
|
Loading…
x
Reference in New Issue
Block a user