Also create update lock bind mount dirs on host on startup

Since Supervisor now uses Mounts API, the engine will not auto-create
the bind mount directories. Because update lock directories are in
/tmp, they are removed with every device reboot, so need to be created
on Supervisor startup so that all containers can access them.

Signed-off-by: Christina Wang <christina@balena.io>
This commit is contained in:
Christina Wang 2022-04-20 15:41:14 -07:00
parent f226a355ad
commit cc9f96b739
3 changed files with 20 additions and 6 deletions

View File

@ -135,6 +135,7 @@ export const initialized = (async () => {
await cleanup();
await localModeManager.init();
await serviceManager.createBindDirs();
await serviceManager.attachToRunning();
serviceManager.listenToEvents();

View File

@ -275,12 +275,7 @@ async function create(service: Service) {
logger.logSystemEvent(LogTypes.installService, { service });
reportNewStatus(mockContainerId, service, 'Installing');
// Create directories on host for update lock binds, since Supervisor uses the
// Docker Mounts API which means an engine error is thrown if bind doesn't exist on host.
const lockDirPath = getPathOnHost(
`${BASE_LOCK_DIR}/${service.appId}/${service.serviceName}`,
);
await mkdirp(lockDirPath);
await createBindDir(service.appId, service.serviceName);
const container = await docker.createContainer(conf);
service.containerId = container.id;
@ -491,6 +486,20 @@ export async function attachToRunning() {
}
}
async function createBindDir(appId: number, serviceName: string) {
const lockDirPath = getPathOnHost(`${BASE_LOCK_DIR}/${appId}/${serviceName}`);
await mkdirp(lockDirPath);
}
// Create directories on host for update lock binds, since Supervisor uses the
// Docker Mounts API which means an engine error is thrown if bind doesn't exist on host.
export async function createBindDirs() {
const services = await getAll();
for (const service of services) {
await createBindDir(service.appId, service.serviceName);
}
}
async function getContainerIdMap(
appIdOrUuid: number | string,
): Promise<Dictionary<string>> {

View File

@ -15,6 +15,7 @@ import log from '../../../src/lib/supervisor-console';
import { InstancedAppState } from '../../../src/types/state';
import * as dbHelper from '../../lib/db-helper';
import * as fsUtils from '../../../src/lib/fs-utils';
const DEFAULT_NETWORK = Network.fromComposeObject('default', 1, 'appuuid', {});
@ -179,6 +180,9 @@ describe('compose/application-manager', () => {
// Stub methods that depend on external dependencies
stub(imageManager, 'isCleanupNeeded');
stub(networkManager, 'supervisorNetworkReady');
// Stub mkdirp call for service manager bind directory creation
stub(fsUtils, 'mkdirp').resolves();
});
beforeEach(() => {