mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-01-31 16:35:23 +00:00
Allow users to override HUP lock if device is stuck in invalid state
This functionality is needed when breadcrumbs aren't deleted after a HUP rollback for whatever reason. Also rename HUP lock function. Change-type: patch Connects-to: #1459 Signed-off-by: Christina Wang <christina@balena.io>
This commit is contained in:
parent
3caf608158
commit
17e740a4ba
@ -638,7 +638,7 @@ export function reportCurrentState(
|
||||
}
|
||||
|
||||
export async function reboot(force?: boolean, skipLock?: boolean) {
|
||||
await updateLock.ensureNoHUPBreadcrumbsOnHost();
|
||||
await updateLock.abortIfHUPInProgress({ force });
|
||||
await applicationManager.stopAll({ force, skipLock });
|
||||
logger.logSystemMessage('Rebooting', {}, 'Reboot');
|
||||
const $reboot = await dbus.reboot();
|
||||
@ -648,7 +648,7 @@ export async function reboot(force?: boolean, skipLock?: boolean) {
|
||||
}
|
||||
|
||||
export async function shutdown(force?: boolean, skipLock?: boolean) {
|
||||
await updateLock.ensureNoHUPBreadcrumbsOnHost();
|
||||
await updateLock.abortIfHUPInProgress({ force });
|
||||
await applicationManager.stopAll({ force, skipLock });
|
||||
logger.logSystemMessage('Shutting down', {}, 'Shutdown');
|
||||
const $shutdown = await dbus.shutdown();
|
||||
|
@ -42,7 +42,11 @@ function lockFilesOnHost(appId: number, serviceName: string): string[] {
|
||||
* prevent reboot. If the Supervisor reboots while those services are still running,
|
||||
* the device may become stuck in an invalid state during HUP.
|
||||
*/
|
||||
export function ensureNoHUPBreadcrumbsOnHost(): Promise<boolean | never> {
|
||||
export function abortIfHUPInProgress({
|
||||
force = false,
|
||||
}: {
|
||||
force: boolean | undefined;
|
||||
}): Promise<boolean | never> {
|
||||
return Promise.all(
|
||||
[
|
||||
'rollback-health-breadcrumb',
|
||||
@ -52,7 +56,7 @@ export function ensureNoHUPBreadcrumbsOnHost(): Promise<boolean | never> {
|
||||
),
|
||||
).then((existsArray) => {
|
||||
const anyExists = existsArray.some((exists) => exists);
|
||||
if (anyExists) {
|
||||
if (anyExists && !force) {
|
||||
throw new UpdatesLockedError('Waiting for Host OS update to finish');
|
||||
}
|
||||
return anyExists;
|
||||
|
@ -359,7 +359,7 @@ describe('deviceState', () => {
|
||||
|
||||
it('prevents reboot or shutdown when HUP rollback breadcrumbs are present', async () => {
|
||||
const testErrMsg = 'Waiting for Host OS updates to finish';
|
||||
stub(updateLock, 'ensureNoHUPBreadcrumbsOnHost').throws(
|
||||
stub(updateLock, 'abortIfHUPInProgress').throws(
|
||||
new UpdatesLockedError(testErrMsg),
|
||||
);
|
||||
|
||||
@ -370,6 +370,6 @@ describe('deviceState', () => {
|
||||
.to.eventually.be.rejectedWith(testErrMsg)
|
||||
.and.be.an.instanceOf(UpdatesLockedError);
|
||||
|
||||
(updateLock.ensureNoHUPBreadcrumbsOnHost as SinonStub).restore();
|
||||
(updateLock.abortIfHUPInProgress as SinonStub).restore();
|
||||
});
|
||||
});
|
||||
|
@ -79,24 +79,33 @@ describe('lib/update-lock', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('ensureNoHUPBreadcrumbsOnHost', () => {
|
||||
describe('abortIfHUPInProgress', () => {
|
||||
afterEach(() => mockFs.restore());
|
||||
|
||||
it('should throw if any breadcrumbs exist on host', async () => {
|
||||
for (const bc of breadcrumbFiles) {
|
||||
mockBreadcrumbs(bc);
|
||||
await expect(updateLock.ensureNoHUPBreadcrumbsOnHost())
|
||||
await expect(updateLock.abortIfHUPInProgress({ force: false }))
|
||||
.to.eventually.be.rejectedWith('Waiting for Host OS update to finish')
|
||||
.and.be.an.instanceOf(UpdatesLockedError);
|
||||
}
|
||||
});
|
||||
|
||||
it('should resolve to true if no breadcrumbs on host', async () => {
|
||||
it('should resolve to false if no breadcrumbs on host', async () => {
|
||||
mockBreadcrumbs();
|
||||
await expect(
|
||||
updateLock.ensureNoHUPBreadcrumbsOnHost(),
|
||||
updateLock.abortIfHUPInProgress({ force: false }),
|
||||
).to.eventually.equal(false);
|
||||
});
|
||||
|
||||
it('should resolve to true if breadcrumbs are on host but force is passed', async () => {
|
||||
for (const bc of breadcrumbFiles) {
|
||||
mockBreadcrumbs(bc);
|
||||
await expect(
|
||||
updateLock.abortIfHUPInProgress({ force: true }),
|
||||
).to.eventually.equal(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('Lock/dispose functionality', () => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user