mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-02-14 15:02:05 +00:00
Ignore empty dtoverlay coming from target state
Before v16, the supervisor would incorrectly interpret an empty dtoverlay in config.txt (i.e. a line with `dtoverlay=`) as a proper variable and create it as config var if found on config.txt before provisioning. With the latest supervisor, an empty dtoverlay on config.txt is interpreted in the [correct way](https://www.raspberrypi.com/documentation/computers/config_txt.html#dtoverlay), but that makes an empty dtoverlay on the target state meaningless, leading to looping behavior as the current and target state won't match. This PR modifies the pre-processing function to filter out empty array variables before the comparison, to prevent this sort of looping behavior. This allows empty dtoverlay to be ignored. Change-type: patch
This commit is contained in:
parent
a71cc374db
commit
82cbc74853
@ -219,7 +219,11 @@ export class ConfigTxt extends ConfigBackend {
|
|||||||
// Split dtoverlays from their params to avoid running into char limits
|
// Split dtoverlays from their params to avoid running into char limits
|
||||||
// and write at the end to prevent overriding the base overlay
|
// and write at the end to prevent overriding the base overlay
|
||||||
if (opts.dtoverlay != null) {
|
if (opts.dtoverlay != null) {
|
||||||
for (const entry of opts.dtoverlay) {
|
for (let entry of opts.dtoverlay) {
|
||||||
|
entry = entry.trim();
|
||||||
|
if (entry.length === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const [overlay, ...params] = entry.split(',');
|
const [overlay, ...params] = entry.split(',');
|
||||||
confStatements.push(`dtoverlay=${overlay}`);
|
confStatements.push(`dtoverlay=${overlay}`);
|
||||||
confStatements.push(...params.map((p) => `dtparam=${p}`));
|
confStatements.push(...params.map((p) => `dtparam=${p}`));
|
||||||
@ -245,9 +249,16 @@ export class ConfigTxt extends ConfigBackend {
|
|||||||
public processConfigVarValue(key: string, value: string): string | string[] {
|
public processConfigVarValue(key: string, value: string): string | string[] {
|
||||||
if (isArrayConfig(key)) {
|
if (isArrayConfig(key)) {
|
||||||
if (!value.startsWith('"')) {
|
if (!value.startsWith('"')) {
|
||||||
|
if (key === 'dtoverlay' && value.trim().length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
return [value];
|
return [value];
|
||||||
} else {
|
} else {
|
||||||
return JSON.parse(`[${value}]`);
|
const res: string[] = JSON.parse(`[${value}]`);
|
||||||
|
if (key === 'dtoverlay') {
|
||||||
|
return res.filter((s) => s.trim().length > 0);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
@ -33,6 +33,7 @@ export function envToBootConfig(
|
|||||||
.mapValues((val, key) =>
|
.mapValues((val, key) =>
|
||||||
configBackend.processConfigVarValue(key, val || ''),
|
configBackend.processConfigVarValue(key, val || ''),
|
||||||
)
|
)
|
||||||
|
.pickBy((val) => !Array.isArray(val) || val.length > 0)
|
||||||
.value();
|
.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,4 +306,55 @@ describe('config/config-txt', () => {
|
|||||||
|
|
||||||
await tfs.restore();
|
await tfs.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('ignores empty dtoverlay on the target state', async () => {
|
||||||
|
const tfs = await testfs({
|
||||||
|
[hostUtils.pathOnBoot('config.txt')]: stripIndent`
|
||||||
|
enable_uart=1
|
||||||
|
dtparam=i2c_arm=on
|
||||||
|
dtparam=spi=on
|
||||||
|
disable_splash=1
|
||||||
|
dtparam=audio=on
|
||||||
|
gpu_mem=16
|
||||||
|
`,
|
||||||
|
}).enable();
|
||||||
|
|
||||||
|
const configTxt = new ConfigTxt();
|
||||||
|
|
||||||
|
await configTxt.setBootConfig({
|
||||||
|
dtparam: ['i2c=on', 'audio=on'],
|
||||||
|
dtoverlay: [''],
|
||||||
|
enable_uart: '1',
|
||||||
|
avoid_warnings: '1',
|
||||||
|
gpu_mem: '256',
|
||||||
|
initramfs: 'initramf.gz 0x00800000',
|
||||||
|
'hdmi_force_hotplug:1': '1',
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
fs.readFile(hostUtils.pathOnBoot('config.txt'), 'utf8'),
|
||||||
|
).to.eventually.equal(
|
||||||
|
stripIndent`
|
||||||
|
dtparam=i2c=on
|
||||||
|
dtparam=audio=on
|
||||||
|
enable_uart=1
|
||||||
|
avoid_warnings=1
|
||||||
|
gpu_mem=256
|
||||||
|
initramfs initramf.gz 0x00800000
|
||||||
|
hdmi_force_hotplug:1=1
|
||||||
|
` + '\n',
|
||||||
|
);
|
||||||
|
|
||||||
|
// Will try to parse /test/data/mnt/boot/config.txt
|
||||||
|
await expect(configTxt.getBootConfig()).to.eventually.deep.equal({
|
||||||
|
dtparam: ['i2c=on', 'audio=on'],
|
||||||
|
enable_uart: '1',
|
||||||
|
avoid_warnings: '1',
|
||||||
|
gpu_mem: '256',
|
||||||
|
initramfs: 'initramf.gz 0x00800000',
|
||||||
|
'hdmi_force_hotplug:1': '1',
|
||||||
|
});
|
||||||
|
|
||||||
|
await tfs.restore();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -228,6 +228,30 @@ describe('device-config', () => {
|
|||||||
expect(logSpy).to.not.be.called;
|
expect(logSpy).to.not.be.called;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('ignores empty dtoverlay when comparing current and target state', async () => {
|
||||||
|
const current = {
|
||||||
|
HOST_CONFIG_initramfs: 'initramf.gz 0x00800000',
|
||||||
|
HOST_CONFIG_dtparam: '"i2c=on","audio=on"',
|
||||||
|
HOST_CONFIG_foobar: 'baz',
|
||||||
|
};
|
||||||
|
const target = {
|
||||||
|
HOST_CONFIG_initramfs: 'initramf.gz 0x00800000',
|
||||||
|
HOST_CONFIG_dtparam: '"i2c=on","audio=on"',
|
||||||
|
HOST_CONFIG_dtoverlay: '',
|
||||||
|
HOST_CONFIG_foobar: 'baz',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(
|
||||||
|
// @ts-expect-error accessing private value
|
||||||
|
deviceConfig.bootConfigChangeRequired(
|
||||||
|
configTxtBackend,
|
||||||
|
current,
|
||||||
|
target,
|
||||||
|
),
|
||||||
|
).to.equal(false);
|
||||||
|
expect(logSpy).to.not.be.called;
|
||||||
|
});
|
||||||
|
|
||||||
it('writes the target config.txt', async () => {
|
it('writes the target config.txt', async () => {
|
||||||
const current = {
|
const current = {
|
||||||
HOST_CONFIG_initramfs: 'initramf.gz 0x00800000',
|
HOST_CONFIG_initramfs: 'initramf.gz 0x00800000',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user