mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-01-27 22:59:23 +00:00
Take update locks for host-config changes
This adds update-lock support to hostname changes via the host-config endpoint, in addition to proxy changes as changing the hostname may cause an engine restart from the OS. Change-type: minor
This commit is contained in:
parent
21becded50
commit
a2d4b31b23
@ -92,40 +92,47 @@ export async function patch(
|
||||
conf: HostConfiguration | LegacyHostConfiguration,
|
||||
force: boolean = false,
|
||||
): Promise<void> {
|
||||
const apps = await applicationManager.getCurrentApps();
|
||||
const appIds = Object.keys(apps).map((strId) => parseInt(strId, 10));
|
||||
|
||||
const ops: Array<() => Promise<void>> = [];
|
||||
if (conf.network.hostname != null) {
|
||||
await setHostname(conf.network.hostname);
|
||||
const hostname = conf.network.hostname;
|
||||
ops.push(async () => await setHostname(hostname));
|
||||
}
|
||||
|
||||
if (conf.network.proxy != null) {
|
||||
const { noProxy, ...targetConf } = conf.network.proxy;
|
||||
ops.push(async () => {
|
||||
const proxyConf = await readProxy();
|
||||
let currentConf: ProxyConfig | undefined = undefined;
|
||||
if (proxyConf) {
|
||||
delete proxyConf.noProxy;
|
||||
currentConf = proxyConf;
|
||||
}
|
||||
|
||||
// Merge current & target redsocks.conf
|
||||
const patchedConf = patchProxy(
|
||||
{
|
||||
redsocks: currentConf,
|
||||
},
|
||||
{
|
||||
redsocks: targetConf,
|
||||
},
|
||||
);
|
||||
await setProxy(patchedConf, noProxy);
|
||||
});
|
||||
}
|
||||
|
||||
if (ops.length > 0) {
|
||||
// It's possible for appIds to be an empty array, but patch shouldn't fail
|
||||
// as it's not dependent on there being any running user applications.
|
||||
const apps = await applicationManager.getCurrentApps();
|
||||
const appIds = Object.keys(apps).map((strId) => parseInt(strId, 10));
|
||||
const lockOverride = await config.get('lockOverride');
|
||||
return updateLock.withLock(
|
||||
await updateLock.withLock(
|
||||
appIds,
|
||||
async () => {
|
||||
const proxyConf = await readProxy();
|
||||
let currentConf: ProxyConfig | undefined = undefined;
|
||||
if (proxyConf) {
|
||||
delete proxyConf.noProxy;
|
||||
currentConf = proxyConf;
|
||||
}
|
||||
|
||||
// Merge current & target redsocks.conf
|
||||
const patchedConf = patchProxy(
|
||||
{
|
||||
redsocks: currentConf,
|
||||
},
|
||||
{
|
||||
redsocks: targetConf,
|
||||
},
|
||||
);
|
||||
await setProxy(patchedConf, noProxy);
|
||||
() => Promise.all(ops.map((fn) => fn())),
|
||||
{
|
||||
force: force || lockOverride,
|
||||
},
|
||||
{ force: force || lockOverride },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ describe('host-config', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('patches if update locks are present but force is specified', async () => {
|
||||
it('patches proxy if update locks are present but force is specified', async () => {
|
||||
(applicationManager.getCurrentApps as SinonStub).resolves(currentApps);
|
||||
|
||||
try {
|
||||
@ -129,17 +129,21 @@ describe('host-config', () => {
|
||||
expect(await config.get('hostname')).to.equal(defaultConf.hostname);
|
||||
});
|
||||
|
||||
it('patches hostname regardless of update locks', async () => {
|
||||
it('prevents hostname patch if there are update locks', async () => {
|
||||
(applicationManager.getCurrentApps as SinonStub).resolves(currentApps);
|
||||
|
||||
try {
|
||||
await patch({ network: { hostname: 'test' } });
|
||||
// /etc/hostname isn't changed until the balena-hostname service
|
||||
// is restarted by the OS.
|
||||
expect(await config.get('hostname')).to.equal('test');
|
||||
} catch (e: unknown) {
|
||||
expect.fail(`Expected hostConfig.patch to not throw, but got ${e}`);
|
||||
}
|
||||
await expect(patch({ network: { hostname: 'test' } }, true)).to.not.be
|
||||
.rejected;
|
||||
// /etc/hostname isn't changed until the balena-hostname service
|
||||
// is restarted by the OS.
|
||||
expect(await config.get('hostname')).to.equal('test');
|
||||
});
|
||||
|
||||
it('patches hostname if update locks are present but force is specified', async () => {
|
||||
(applicationManager.getCurrentApps as SinonStub).resolves(currentApps);
|
||||
|
||||
await expect(patch({ network: { hostname: 'test' } })).to.be.rejected;
|
||||
expect(await config.get('hostname')).to.equal(defaultConf.hostname);
|
||||
});
|
||||
|
||||
it('patches hostname without modifying other fields', async () => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user