mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-02-05 10:39:57 +00:00
Support "os" key with object values in ConfigJsonConfigBackend
Signed-off-by: Christina Ying Wang <christina@balena.io>
This commit is contained in:
parent
9ec45a724b
commit
54fcfa22a7
@ -39,14 +39,10 @@ export default class ConfigJsonConfigBackend {
|
||||
await Bluebird.using(this.writeLockConfigJson(), async () => {
|
||||
let changed = false;
|
||||
_.forOwn(keyVals, (value, key: T) => {
|
||||
if (this.cache[key] !== value) {
|
||||
if (this.schema[key] != null && !_.isEqual(this.cache[key], value)) {
|
||||
this.cache[key] = value;
|
||||
|
||||
if (
|
||||
value == null &&
|
||||
this.schema[key] != null &&
|
||||
this.schema[key].removeIfNull
|
||||
) {
|
||||
if (value == null && this.schema[key].removeIfNull) {
|
||||
delete this.cache[key];
|
||||
}
|
||||
|
||||
@ -59,7 +55,7 @@ export default class ConfigJsonConfigBackend {
|
||||
});
|
||||
}
|
||||
|
||||
public async get(key: string): Promise<unknown> {
|
||||
public async get(key: Schema.SchemaKey): Promise<unknown> {
|
||||
await this.init();
|
||||
return Bluebird.using(
|
||||
this.readLockConfigJson(),
|
||||
@ -67,7 +63,7 @@ export default class ConfigJsonConfigBackend {
|
||||
);
|
||||
}
|
||||
|
||||
public async remove(key: string) {
|
||||
public async remove(key: Schema.SchemaKey) {
|
||||
await this.init();
|
||||
return Bluebird.using(this.writeLockConfigJson(), async () => {
|
||||
let changed = false;
|
||||
|
@ -84,6 +84,10 @@ export const schemaTypes = {
|
||||
type: t.string,
|
||||
default: NullOrUndefined,
|
||||
},
|
||||
os: {
|
||||
type: t.union([t.record(t.string, t.any), t.undefined]),
|
||||
default: NullOrUndefined,
|
||||
},
|
||||
|
||||
// Database types
|
||||
name: {
|
||||
|
@ -84,6 +84,11 @@ export const schema = {
|
||||
mutable: false,
|
||||
removeIfNull: false,
|
||||
},
|
||||
os: {
|
||||
source: 'config.json',
|
||||
mutable: true,
|
||||
removeIfNull: false,
|
||||
},
|
||||
|
||||
name: {
|
||||
source: 'db',
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { expect } from 'chai';
|
||||
import type { TestFs } from 'mocha-pod';
|
||||
import { testfs } from 'mocha-pod';
|
||||
import { promises as fs } from 'fs';
|
||||
|
||||
@ -7,46 +8,150 @@ import { schema } from '~/src/config/schema';
|
||||
|
||||
describe('ConfigJsonConfigBackend', () => {
|
||||
const CONFIG_PATH = '/mnt/boot/config.json';
|
||||
const os = {
|
||||
power: {
|
||||
mode: 'high',
|
||||
},
|
||||
fan: {
|
||||
profile: 'cool',
|
||||
},
|
||||
network: {
|
||||
connectivity: {
|
||||
uri: 'https://api.balena-cloud.com/connectivity-check',
|
||||
interval: '300',
|
||||
response: 'optional value in the response',
|
||||
},
|
||||
wifi: {
|
||||
randomMacAddressScan: false,
|
||||
},
|
||||
},
|
||||
udevRules: {
|
||||
'56': 'ENV{ID_FS_LABEL_ENC}=="resin-root*", IMPORT{program}="resin_update_state_probe $devnode", SYMLINK+="disk/by-state/$env{RESIN_UPDATE_STATE}"',
|
||||
'64': 'ACTION!="add|change", GOTO="modeswitch_rules_end"\nKERNEL=="ttyACM*", ATTRS{idVendor}=="1546", ATTRS{idProduct}=="1146", TAG+="systemd", ENV{SYSTEMD_WANTS}="u-blox-switch@\'%E{DEVNAME}\'.service"\nLBEL="modeswitch_rules_end"\n',
|
||||
},
|
||||
sshKeys: [
|
||||
'ssh-rsa AAAAB3Nza...M2JB balena@macbook-pro',
|
||||
'ssh-rsa AAAAB3Nza...nFTQ balena@zenbook',
|
||||
],
|
||||
};
|
||||
let configJsonConfigBackend: ConfigJsonConfigBackend;
|
||||
let tfs: TestFs.Enabled;
|
||||
|
||||
beforeEach(() => {
|
||||
configJsonConfigBackend = new ConfigJsonConfigBackend(schema);
|
||||
});
|
||||
|
||||
it('should get value for config.json key', async () => {
|
||||
await testfs({
|
||||
afterEach(async () => {
|
||||
await tfs.restore();
|
||||
});
|
||||
|
||||
it('should get primitive values for config.json key', async () => {
|
||||
tfs = await testfs({
|
||||
[CONFIG_PATH]: JSON.stringify({
|
||||
apiEndpoint: 'foo',
|
||||
deviceId: 123,
|
||||
persistentLogging: true,
|
||||
}),
|
||||
'/mnt/root/etc/os-release': testfs.from('test/data/etc/os-release'),
|
||||
}).enable();
|
||||
|
||||
expect(await configJsonConfigBackend.get('apiEndpoint')).to.equal('foo');
|
||||
|
||||
await testfs.restore();
|
||||
expect(await configJsonConfigBackend.get('deviceId')).to.equal(123);
|
||||
expect(await configJsonConfigBackend.get('persistentLogging')).to.equal(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it('should set value for config.json key', async () => {
|
||||
await testfs({
|
||||
it('should get object values for config.json "os" key', async () => {
|
||||
tfs = await testfs({
|
||||
[CONFIG_PATH]: JSON.stringify({
|
||||
os,
|
||||
}),
|
||||
'/mnt/root/etc/os-release': testfs.from('test/data/etc/os-release'),
|
||||
}).enable();
|
||||
|
||||
expect(await configJsonConfigBackend.get('os')).to.deep.equal(os);
|
||||
});
|
||||
|
||||
it('should get object values for config.json "os" key while "os" is empty', async () => {
|
||||
tfs = await testfs({
|
||||
[CONFIG_PATH]: JSON.stringify({}),
|
||||
'/mnt/root/etc/os-release': testfs.from('test/data/etc/os-release'),
|
||||
}).enable();
|
||||
|
||||
expect(await configJsonConfigBackend.get('os')).to.be.undefined;
|
||||
});
|
||||
|
||||
it('should set primitive values for config.json key', async () => {
|
||||
tfs = await testfs({
|
||||
[CONFIG_PATH]: JSON.stringify({
|
||||
apiEndpoint: 'foo',
|
||||
deviceId: 123,
|
||||
persistentLogging: true,
|
||||
}),
|
||||
'/mnt/root/etc/os-release': testfs.from('test/data/etc/os-release'),
|
||||
}).enable();
|
||||
|
||||
await configJsonConfigBackend.set({
|
||||
apiEndpoint: 'bar',
|
||||
deviceId: 456,
|
||||
persistentLogging: false,
|
||||
});
|
||||
|
||||
expect(await configJsonConfigBackend.get('apiEndpoint')).to.equal('bar');
|
||||
expect(await configJsonConfigBackend.get('deviceId')).to.equal(456);
|
||||
expect(await configJsonConfigBackend.get('persistentLogging')).to.equal(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
await testfs.restore();
|
||||
it('should set object values for config.json "os" key', async () => {
|
||||
tfs = await testfs({
|
||||
[CONFIG_PATH]: JSON.stringify({
|
||||
os,
|
||||
}),
|
||||
'/mnt/root/etc/os-release': testfs.from('test/data/etc/os-release'),
|
||||
}).enable();
|
||||
|
||||
const newOs = {
|
||||
power: {
|
||||
mode: 'low',
|
||||
},
|
||||
network: {
|
||||
wifi: {
|
||||
randomMacAddressScan: true,
|
||||
},
|
||||
},
|
||||
udevRules: {
|
||||
'56': 'ENV{ID_FS_LABEL_ENC}=="resin-root*", IMPORT{program}="resin_update_state_probe $devnode", SYMLINK+="disk/by-state/$env{RESIN_UPDATE_STATE}"',
|
||||
},
|
||||
sshKeys: ['ssh-rsa AAAAB3Nza...M2JB balena@macbook-pro'],
|
||||
};
|
||||
|
||||
await configJsonConfigBackend.set({
|
||||
os: newOs,
|
||||
});
|
||||
|
||||
expect(await configJsonConfigBackend.get('os')).to.deep.equal(newOs);
|
||||
});
|
||||
|
||||
it('should set object values for config.json "os" key while "os" is empty', async () => {
|
||||
tfs = await testfs({
|
||||
[CONFIG_PATH]: JSON.stringify({}),
|
||||
'/mnt/root/etc/os-release': testfs.from('test/data/etc/os-release'),
|
||||
}).enable();
|
||||
|
||||
await configJsonConfigBackend.set({
|
||||
os,
|
||||
});
|
||||
|
||||
expect(await configJsonConfigBackend.get('os')).to.deep.equal(os);
|
||||
});
|
||||
|
||||
// The following test cases may be unnecessary as they test cases where another party
|
||||
// writes to config.json directly (instead of through setting config vars on the API).
|
||||
it('should get cached value even if actual value has changed', async () => {
|
||||
await testfs({
|
||||
tfs = await testfs({
|
||||
[CONFIG_PATH]: JSON.stringify({
|
||||
apiEndpoint: 'foo',
|
||||
}),
|
||||
@ -66,12 +171,10 @@ describe('ConfigJsonConfigBackend', () => {
|
||||
|
||||
// Unintended behavior: the cached value should not be overwritten
|
||||
expect(await configJsonConfigBackend.get('apiEndpoint')).to.equal('foo');
|
||||
|
||||
await testfs.restore();
|
||||
});
|
||||
|
||||
it('should set value and refresh cache to equal new value', async () => {
|
||||
await testfs({
|
||||
tfs = await testfs({
|
||||
[CONFIG_PATH]: JSON.stringify({
|
||||
apiEndpoint: 'foo',
|
||||
}),
|
||||
@ -88,6 +191,7 @@ describe('ConfigJsonConfigBackend', () => {
|
||||
);
|
||||
|
||||
// Unintended behavior: cached value should not have been updated
|
||||
// as the change was not written to config.json by the Supervisor
|
||||
expect(await configJsonConfigBackend.get('apiEndpoint')).to.equal('foo');
|
||||
|
||||
await configJsonConfigBackend.set({
|
||||
@ -95,7 +199,5 @@ describe('ConfigJsonConfigBackend', () => {
|
||||
});
|
||||
|
||||
expect(await configJsonConfigBackend.get('apiEndpoint')).to.equal('baz');
|
||||
|
||||
await testfs.restore();
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user