mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-02-22 18:22:41 +00:00
Merge pull request #1847 from balena-os/apps-json-rename
Rename apps.json after initial preload
This commit is contained in:
commit
70ec8c9af4
@ -8,21 +8,19 @@ import * as deviceConfig from '../device-config';
|
||||
import * as eventTracker from '../event-tracker';
|
||||
import * as images from '../compose/images';
|
||||
|
||||
import constants = require('../lib/constants');
|
||||
import { AppsJsonParseError, EISDIR, ENOENT } from '../lib/errors';
|
||||
import log from '../lib/supervisor-console';
|
||||
|
||||
import { convertLegacyAppsJson } from '../lib/migration';
|
||||
import { AppsJsonFormat } from '../types/state';
|
||||
import * as fsUtils from '../lib/fs-utils';
|
||||
|
||||
export async function loadTargetFromFile(
|
||||
appsPath: Nullable<string>,
|
||||
): Promise<void> {
|
||||
export function appsJsonBackup(appsPath: string) {
|
||||
return `${appsPath}.preloaded`;
|
||||
}
|
||||
|
||||
export async function loadTargetFromFile(appsPath: string): Promise<void> {
|
||||
log.info('Attempting to load any preloaded applications');
|
||||
if (!appsPath) {
|
||||
appsPath = constants.appsJsonPath;
|
||||
}
|
||||
|
||||
try {
|
||||
const content = await fs.readFile(appsPath, 'utf8');
|
||||
|
||||
@ -73,7 +71,7 @@ export async function loadTargetFromFile(
|
||||
}
|
||||
|
||||
for (const image of imgs) {
|
||||
const name = await images.normalise(image.name);
|
||||
const name = images.normalise(image.name);
|
||||
image.name = name;
|
||||
await images.save(image);
|
||||
}
|
||||
@ -114,5 +112,23 @@ export async function loadTargetFromFile(
|
||||
error: e,
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
const targetPath = appsJsonBackup(appsPath);
|
||||
if (!(await fsUtils.exists(targetPath))) {
|
||||
// Try to rename the path so the preload target state won't
|
||||
// be used again if the database gets deleted for any reason.
|
||||
// If the target file already exists or something fails, just debug
|
||||
// the failure.
|
||||
await fsUtils
|
||||
.safeRename(appsPath, targetPath)
|
||||
.then(() => fsUtils.writeFileAtomic(appsPath, '{}'))
|
||||
.then(() => log.debug(`Migrated existing apps.json`))
|
||||
.catch((e) =>
|
||||
log.debug(
|
||||
`Continuing without migrating apps.json because of`,
|
||||
e.message,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import * as path from 'path';
|
||||
import { checkString } from './validation';
|
||||
|
||||
const bootMountPointFromEnv = checkString(process.env.BOOT_MOUNTPOINT);
|
||||
@ -49,7 +50,9 @@ const constants = {
|
||||
'lo',
|
||||
supervisorNetworkInterface,
|
||||
],
|
||||
appsJsonPath: process.env.APPS_JSON_PATH || '/boot/apps.json',
|
||||
appsJsonPath:
|
||||
process.env.APPS_JSON_PATH ||
|
||||
path.join(rootMountPoint, '/mnt/data', 'apps.json'),
|
||||
ipAddressUpdateInterval: 30 * 1000,
|
||||
imageCleanupErrorIgnoreTimeout: 3600 * 1000,
|
||||
maxDeltaDownloads: 3,
|
||||
|
@ -10,10 +10,14 @@ import * as images from '../src/compose/images';
|
||||
import { ConfigTxt } from '../src/config/backends/config-txt';
|
||||
import * as deviceState from '../src/device-state';
|
||||
import * as deviceConfig from '../src/device-config';
|
||||
import { loadTargetFromFile } from '../src/device-state/preload';
|
||||
import {
|
||||
loadTargetFromFile,
|
||||
appsJsonBackup,
|
||||
} from '../src/device-state/preload';
|
||||
import Service from '../src/compose/service';
|
||||
import { intialiseContractRequirements } from '../src/lib/contracts';
|
||||
import * as updateLock from '../src/lib/update-lock';
|
||||
import * as fsUtils from '../src/lib/fs-utils';
|
||||
|
||||
const mockedInitialConfig = {
|
||||
RESIN_SUPERVISOR_CONNECTIVITY_CHECK: 'true',
|
||||
@ -224,8 +228,10 @@ describe('deviceState', () => {
|
||||
});
|
||||
|
||||
it('loads a target state from an apps.json file and saves it as target state, then returns it', async () => {
|
||||
await loadTargetFromFile(process.env.ROOT_MOUNTPOINT + '/apps.json');
|
||||
const appsJson = process.env.ROOT_MOUNTPOINT + '/apps.json';
|
||||
await loadTargetFromFile(appsJson);
|
||||
const targetState = await deviceState.getTarget();
|
||||
expect(await fsUtils.exists(appsJsonBackup(appsJson))).to.be.true;
|
||||
|
||||
expect(targetState)
|
||||
.to.have.property('local')
|
||||
@ -283,14 +289,22 @@ describe('deviceState', () => {
|
||||
.to.have.property('labels')
|
||||
.that.has.property('io.balena.something')
|
||||
.that.equals('bar');
|
||||
|
||||
// Restore renamed apps.json
|
||||
await fsUtils.safeRename(appsJsonBackup(appsJson), appsJson);
|
||||
});
|
||||
|
||||
it('stores info for pinning a device after loading an apps.json with a pinDevice field', async () => {
|
||||
await loadTargetFromFile(process.env.ROOT_MOUNTPOINT + '/apps-pin.json');
|
||||
const appsJson = process.env.ROOT_MOUNTPOINT + '/apps-pin.json';
|
||||
await loadTargetFromFile(appsJson);
|
||||
|
||||
const pinned = await config.get('pinDevice');
|
||||
expect(pinned).to.have.property('app').that.equals(1234);
|
||||
expect(pinned).to.have.property('commit').that.equals('abcdef');
|
||||
expect(await fsUtils.exists(appsJsonBackup(appsJson))).to.be.true;
|
||||
|
||||
// Restore renamed apps.json
|
||||
await fsUtils.safeRename(appsJsonBackup(appsJson), appsJson);
|
||||
});
|
||||
|
||||
it('emits a change event when a new state is reported', (done) => {
|
||||
@ -303,7 +317,7 @@ describe('deviceState', () => {
|
||||
|
||||
const services: Service[] = [];
|
||||
for (const service of testTarget.local.apps['1234'].services) {
|
||||
const imageName = await images.normalise(service.image);
|
||||
const imageName = images.normalise(service.image);
|
||||
service.image = imageName;
|
||||
(service as any).imageName = imageName;
|
||||
services.push(
|
||||
|
Loading…
x
Reference in New Issue
Block a user