mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2024-12-21 06:33:30 +00:00
Fix config checks for ConfigFS backend
When trying to apply SSDT overlays in Up Board, the supervisor currently gets stuck in a loop trying to apply target state. See #1465 This was due to a bug in parsing the configuration, which lead to the method bootConfigChangeRequired returning true when no change was needed. Change-type: patch Signed-off-by: Felipe Lalanne <felipe@balena.io> Connects-to: #1465
This commit is contained in:
parent
1ac71ea552
commit
a5f3002e70
2
.gitignore
vendored
2
.gitignore
vendored
@ -10,7 +10,7 @@ tools/dind/config/
|
|||||||
tools/dind/config.json*
|
tools/dind/config.json*
|
||||||
tools/dind/apps.json
|
tools/dind/apps.json
|
||||||
tools/dind/backup.tgz
|
tools/dind/backup.tgz
|
||||||
test/data/config*.json
|
test/data/**/config*.json
|
||||||
test/data/*.sqlite
|
test/data/*.sqlite
|
||||||
test/data/led_file
|
test/data/led_file
|
||||||
/coverage/
|
/coverage/
|
||||||
|
@ -94,7 +94,7 @@ export class ConfigFs extends ConfigBackend {
|
|||||||
`AML: ${oemId.trim()} ${oemTableId.trim()} (Rev ${oemRevision.trim()})`,
|
`AML: ${oemId.trim()} ${oemTableId.trim()} (Rev ${oemRevision.trim()})`,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.error('Issue while loading AML ${aml}', e);
|
log.error(`Issue while loading AML ${aml}`, e);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -214,7 +214,7 @@ export class ConfigFs extends ConfigBackend {
|
|||||||
return [value];
|
return [value];
|
||||||
} else {
|
} else {
|
||||||
// or, it could be parsable as the content of a JSON array; "value" | "value1","value2"
|
// or, it could be parsable as the content of a JSON array; "value" | "value1","value2"
|
||||||
return value.split(',').map((v) => v.replace('"', '').trim());
|
return value.split(',').map((v) => v.replace(/"/g, '').trim());
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return value;
|
return value;
|
||||||
|
@ -9,12 +9,15 @@ import * as logger from '../src/logger';
|
|||||||
import { Extlinux } from '../src/config/backends/extlinux';
|
import { Extlinux } from '../src/config/backends/extlinux';
|
||||||
import { ConfigTxt } from '../src/config/backends/config-txt';
|
import { ConfigTxt } from '../src/config/backends/config-txt';
|
||||||
import { Odmdata } from '../src/config/backends/odmdata';
|
import { Odmdata } from '../src/config/backends/odmdata';
|
||||||
|
import { ConfigFs } from '../src/config/backends/config-fs';
|
||||||
|
import * as constants from '../src/lib/constants';
|
||||||
|
|
||||||
import prepare = require('./lib/prepare');
|
import prepare = require('./lib/prepare');
|
||||||
|
|
||||||
const extlinuxBackend = new Extlinux();
|
const extlinuxBackend = new Extlinux();
|
||||||
const configTxtBackend = new ConfigTxt();
|
const configTxtBackend = new ConfigTxt();
|
||||||
const odmdataBackend = new Odmdata();
|
const odmdataBackend = new Odmdata();
|
||||||
|
const configFsBackend = new ConfigFs();
|
||||||
|
|
||||||
describe('Device Backend Config', () => {
|
describe('Device Backend Config', () => {
|
||||||
let logSpy: SinonSpy;
|
let logSpy: SinonSpy;
|
||||||
@ -336,94 +339,138 @@ describe('Device Backend Config', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// describe('ConfigFS', () => {
|
describe('ConfigFS files', () => {
|
||||||
// const upboardConfig = new DeviceConfig();
|
it('should correctly write to configfs.json files', async () => {
|
||||||
// let upboardConfigBackend: ConfigBackend | null;
|
stub(fsUtils, 'writeFileAtomic').resolves();
|
||||||
|
stub(child_process, 'exec').resolves();
|
||||||
|
|
||||||
// before(async () => {
|
const current = {};
|
||||||
// stub(child_process, 'exec').resolves();
|
const target = {
|
||||||
// stub(fs, 'exists').resolves(true);
|
HOST_CONFIGFS_ssdt: 'spidev1.0',
|
||||||
// stub(fs, 'mkdir').resolves();
|
};
|
||||||
// stub(fs, 'readdir').resolves([]);
|
|
||||||
// stub(fsUtils, 'writeFileAtomic').resolves();
|
|
||||||
|
|
||||||
// stub(fs, 'readFile').callsFake(file => {
|
expect(
|
||||||
// if (file === 'test/data/mnt/boot/configfs.json') {
|
// @ts-ignore accessing private value
|
||||||
// return Promise.resolve(
|
deviceConfig.bootConfigChangeRequired(
|
||||||
// JSON.stringify({
|
configFsBackend,
|
||||||
// ssdt: ['spidev1,1'],
|
current,
|
||||||
// }),
|
target,
|
||||||
// );
|
'up-board',
|
||||||
// }
|
),
|
||||||
// return Promise.resolve('');
|
).to.equal(true);
|
||||||
// });
|
|
||||||
|
|
||||||
// stub(config, 'get').callsFake(key => {
|
// @ts-ignore accessing private value
|
||||||
// return Promise.try(() => {
|
await deviceConfig.setBootConfig(configFsBackend, target);
|
||||||
// if (key === 'deviceType') {
|
expect(child_process.exec).to.be.calledOnce;
|
||||||
// return 'up-board';
|
expect(logSpy).to.be.calledTwice;
|
||||||
// }
|
expect(logSpy.getCall(1).args[2]).to.equal('Apply boot config success');
|
||||||
// throw new Error('Unknown fake config key');
|
expect(fsUtils.writeFileAtomic).to.be.calledWith(
|
||||||
// });
|
'test/data/mnt/boot/configfs.json',
|
||||||
// });
|
'{"ssdt":["spidev1.0"]}',
|
||||||
|
);
|
||||||
|
|
||||||
// // @ts-ignore accessing private value
|
// Restore stubs
|
||||||
// upboardConfigBackend = await upboardConfig.getConfigBackend();
|
(fsUtils.writeFileAtomic as SinonStub).restore();
|
||||||
// expect(upboardConfigBackend).is.not.null;
|
(child_process.exec as SinonStub).restore();
|
||||||
// expect((child_process.exec as SinonSpy).callCount).to.equal(
|
});
|
||||||
// 3,
|
|
||||||
// 'exec not called enough times',
|
|
||||||
// );
|
|
||||||
// });
|
|
||||||
|
|
||||||
// after(() => {
|
it('should correctly load the configfs.json file', async () => {
|
||||||
// (child_process.exec as SinonStub).restore();
|
stub(child_process, 'exec').resolves();
|
||||||
// (fs.exists as SinonStub).restore();
|
stub(fsUtils, 'writeFileAtomic').resolves();
|
||||||
// (fs.mkdir as SinonStub).restore();
|
stub(fs, 'exists').resolves(true);
|
||||||
// (fs.readdir as SinonStub).restore();
|
stub(fs, 'mkdir').resolves();
|
||||||
// (fs.readFile as SinonStub).restore();
|
stub(fs, 'readdir').resolves([]);
|
||||||
// (fsUtils.writeFileAtomic as SinonStub).restore();
|
stub(fs, 'readFile').callsFake((file) => {
|
||||||
// (config.get as SinonStub).restore();
|
if (file === 'test/data/mnt/boot/configfs.json') {
|
||||||
// });
|
return Promise.resolve(
|
||||||
|
JSON.stringify({
|
||||||
|
ssdt: ['spidev1.1'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Promise.resolve('');
|
||||||
|
});
|
||||||
|
|
||||||
// it('should correctly load the configfs.json file', () => {
|
await configFsBackend.initialise();
|
||||||
// expect(child_process.exec).to.be.calledWith('modprobe acpi_configfs');
|
expect(child_process.exec).to.be.calledWith('modprobe acpi_configfs');
|
||||||
// expect(child_process.exec).to.be.calledWith(
|
expect(child_process.exec).to.be.calledWith(
|
||||||
// 'cat test/data/boot/acpi-tables/spidev1,1.aml > test/data/sys/kernel/config/acpi/table/spidev1,1/aml',
|
`mount -t vfat -o remount,rw ${constants.bootBlockDevice} ./test/data/mnt/boot`,
|
||||||
// );
|
);
|
||||||
// expect((fs.exists as SinonSpy).callCount).to.equal(2);
|
expect(child_process.exec).to.be.calledWith(
|
||||||
// expect((fs.readFile as SinonSpy).callCount).to.equal(4);
|
'cat test/data/boot/acpi-tables/spidev1.1.aml > test/data/sys/kernel/config/acpi/table/spidev1.1/aml',
|
||||||
// });
|
);
|
||||||
|
expect((fs.exists as SinonSpy).callCount).to.equal(2);
|
||||||
|
expect((fs.readFile as SinonSpy).callCount).to.equal(4);
|
||||||
|
|
||||||
// it('should correctly write the configfs.json file', async () => {
|
// Restore stubs
|
||||||
// const current = {};
|
(fsUtils.writeFileAtomic as SinonStub).restore();
|
||||||
// const target = {
|
(child_process.exec as SinonStub).restore();
|
||||||
// HOST_CONFIGFS_ssdt: 'spidev1,1',
|
(fs.exists as SinonStub).restore();
|
||||||
// };
|
(fs.mkdir as SinonStub).restore();
|
||||||
|
(fs.readdir as SinonStub).restore();
|
||||||
|
(fs.readFile as SinonStub).restore();
|
||||||
|
});
|
||||||
|
|
||||||
// (child_process.exec as SinonSpy).resetHistory();
|
it('requires change when target is different', () => {
|
||||||
// (fs.exists as SinonSpy).resetHistory();
|
expect(
|
||||||
// (fs.mkdir as SinonSpy).resetHistory();
|
deviceConfig.bootConfigChangeRequired(
|
||||||
// (fs.readdir as SinonSpy).resetHistory();
|
configFsBackend,
|
||||||
// (fs.readFile as SinonSpy).resetHistory();
|
{ HOST_CONFIGFS_ssdt: '' },
|
||||||
|
{ HOST_CONFIGFS_ssdt: 'spidev1.0' },
|
||||||
|
'up-board',
|
||||||
|
),
|
||||||
|
).to.equal(true);
|
||||||
|
expect(
|
||||||
|
deviceConfig.bootConfigChangeRequired(
|
||||||
|
configFsBackend,
|
||||||
|
{ HOST_CONFIGFS_ssdt: '' },
|
||||||
|
{ HOST_CONFIGFS_ssdt: '"spidev1.0"' },
|
||||||
|
'up-board',
|
||||||
|
),
|
||||||
|
).to.equal(true);
|
||||||
|
expect(
|
||||||
|
deviceConfig.bootConfigChangeRequired(
|
||||||
|
configFsBackend,
|
||||||
|
{ HOST_CONFIGFS_ssdt: '"spidev1.0"' },
|
||||||
|
{ HOST_CONFIGFS_ssdt: '"spidev1.0","spidev1.1"' },
|
||||||
|
'up-board',
|
||||||
|
),
|
||||||
|
).to.equal(true);
|
||||||
|
});
|
||||||
|
|
||||||
// // @ts-ignore accessing private value
|
it('should not report change when target is equal to current', () => {
|
||||||
// upboardConfig.bootConfigChangeRequired(upboardConfigBackend, current, target);
|
expect(
|
||||||
// // @ts-ignore accessing private value
|
deviceConfig.bootConfigChangeRequired(
|
||||||
// await upboardConfig.setBootConfig(upboardConfigBackend, target);
|
configFsBackend,
|
||||||
|
{ HOST_CONFIGFS_ssdt: '' },
|
||||||
// expect(child_process.exec).to.be.calledOnce;
|
{ HOST_CONFIGFS_ssdt: '' },
|
||||||
// expect(fsUtils.writeFileAtomic).to.be.calledWith(
|
'up-board',
|
||||||
// 'test/data/mnt/boot/configfs.json',
|
),
|
||||||
// JSON.stringify({
|
).to.equal(false);
|
||||||
// ssdt: ['spidev1,1'],
|
expect(
|
||||||
// }),
|
deviceConfig.bootConfigChangeRequired(
|
||||||
// );
|
configFsBackend,
|
||||||
// expect(logSpy).to.be.calledTwice;
|
{ HOST_CONFIGFS_ssdt: 'spidev1.0' },
|
||||||
// expect(logSpy.getCall(1).args[2]).to.equal('Apply boot config success');
|
{ HOST_CONFIGFS_ssdt: 'spidev1.0' },
|
||||||
// });
|
'up-board',
|
||||||
// });
|
),
|
||||||
|
).to.equal(false);
|
||||||
// // This will require stubbing device.reboot, gosuper.post, config.get/set
|
expect(
|
||||||
// it('applies the target state');
|
deviceConfig.bootConfigChangeRequired(
|
||||||
|
configFsBackend,
|
||||||
|
{ HOST_CONFIGFS_ssdt: 'spidev1.0' },
|
||||||
|
{ HOST_CONFIGFS_ssdt: '"spidev1.0"' },
|
||||||
|
'up-board',
|
||||||
|
),
|
||||||
|
).to.equal(false);
|
||||||
|
expect(
|
||||||
|
deviceConfig.bootConfigChangeRequired(
|
||||||
|
configFsBackend,
|
||||||
|
{ HOST_CONFIGFS_ssdt: '"spidev1.0"' },
|
||||||
|
{ HOST_CONFIGFS_ssdt: 'spidev1.0' },
|
||||||
|
'up-board',
|
||||||
|
),
|
||||||
|
).to.equal(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user