mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-06-06 17:41:40 +00:00
Verify that LED_FILE exists on blinking setup
Before v1, the blinking module would not throw when the passed led file does not exist. This change checks for file existence and defaults to `/dev/null` otherwise Change-type: patch
This commit is contained in:
parent
8f5131c680
commit
a255001c2e
@ -19,7 +19,7 @@ import type { Service } from '../compose/service';
|
|||||||
import { getApp } from '../device-state/db-format';
|
import { getApp } from '../device-state/db-format';
|
||||||
import * as TargetState from '../api-binder/poll';
|
import * as TargetState from '../api-binder/poll';
|
||||||
import log from '../lib/supervisor-console';
|
import log from '../lib/supervisor-console';
|
||||||
import blink = require('../lib/blink');
|
import { getBlink } from '../lib/blink';
|
||||||
import * as constants from '../lib/constants';
|
import * as constants from '../lib/constants';
|
||||||
import {
|
import {
|
||||||
InternalInconsistencyError,
|
InternalInconsistencyError,
|
||||||
@ -56,7 +56,8 @@ export const runHealthchecks = async (
|
|||||||
* - POST /v1/blink
|
* - POST /v1/blink
|
||||||
*/
|
*/
|
||||||
const DEFAULT_IDENTIFY_DURATION = 15000;
|
const DEFAULT_IDENTIFY_DURATION = 15000;
|
||||||
export const identify = (ms: number = DEFAULT_IDENTIFY_DURATION) => {
|
export const identify = async (ms: number = DEFAULT_IDENTIFY_DURATION) => {
|
||||||
|
const blink = await getBlink();
|
||||||
eventTracker.track('Device blink');
|
eventTracker.track('Device blink');
|
||||||
blink.pattern.start();
|
blink.pattern.start();
|
||||||
setTimeout(blink.pattern.stop, ms);
|
setTimeout(blink.pattern.stop, ms);
|
||||||
|
@ -43,8 +43,8 @@ export class SupervisorAPI {
|
|||||||
|
|
||||||
this.api.use(middleware.auth);
|
this.api.use(middleware.auth);
|
||||||
|
|
||||||
this.api.post('/v1/blink', (_req, res) => {
|
this.api.post('/v1/blink', async (_req, res) => {
|
||||||
actions.identify();
|
await actions.identify();
|
||||||
return res.sendStatus(200);
|
return res.sendStatus(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,18 @@
|
|||||||
import blinking = require('blinking');
|
import blinking from 'blinking';
|
||||||
|
import memoizee from 'memoizee';
|
||||||
|
|
||||||
|
export type Blink = ReturnType<typeof blinking>;
|
||||||
|
|
||||||
|
import { exists } from './fs-utils';
|
||||||
import { ledFile } from './constants';
|
import { ledFile } from './constants';
|
||||||
|
|
||||||
export = blinking(ledFile);
|
export const getBlink = memoizee(
|
||||||
|
async (): Promise<Blink> => {
|
||||||
|
if (!(await exists(ledFile))) {
|
||||||
|
return blinking('/dev/null');
|
||||||
|
}
|
||||||
|
|
||||||
|
return blinking(ledFile);
|
||||||
|
},
|
||||||
|
{ promise: true },
|
||||||
|
);
|
||||||
|
@ -8,7 +8,7 @@ import * as constants from './lib/constants';
|
|||||||
import { isEEXIST } from './lib/errors';
|
import { isEEXIST } from './lib/errors';
|
||||||
import { checkFalsey } from './lib/validation';
|
import { checkFalsey } from './lib/validation';
|
||||||
|
|
||||||
import blink = require('./lib/blink');
|
import { getBlink } from './lib/blink';
|
||||||
|
|
||||||
import log from './lib/supervisor-console';
|
import log from './lib/supervisor-console';
|
||||||
|
|
||||||
@ -85,6 +85,7 @@ export const startConnectivityCheck = _.once(
|
|||||||
|
|
||||||
const parsedUrl = url.parse(apiEndpoint);
|
const parsedUrl = url.parse(apiEndpoint);
|
||||||
const port = parseInt(parsedUrl.port!, 10);
|
const port = parseInt(parsedUrl.port!, 10);
|
||||||
|
const blink = await getBlink();
|
||||||
|
|
||||||
customMonitor(
|
customMonitor(
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import type { SinonStub } from 'sinon';
|
import type { SinonStub } from 'sinon';
|
||||||
import { stub } from 'sinon';
|
import { stub, spy, useFakeTimers } from 'sinon';
|
||||||
import Docker from 'dockerode';
|
import Docker from 'dockerode';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { setTimeout } from 'timers/promises';
|
import { setTimeout } from 'timers/promises';
|
||||||
@ -17,6 +17,8 @@ import { pathOnRoot } from '~/lib/host-utils';
|
|||||||
import { exec } from '~/lib/fs-utils';
|
import { exec } from '~/lib/fs-utils';
|
||||||
import * as lockfile from '~/lib/lockfile';
|
import * as lockfile from '~/lib/lockfile';
|
||||||
import { cleanupDocker } from '~/test-lib/docker-helper';
|
import { cleanupDocker } from '~/test-lib/docker-helper';
|
||||||
|
import { getBlink } from '~/lib/blink';
|
||||||
|
import type { Blink } from '~/lib/blink';
|
||||||
|
|
||||||
export async function dbusSend(
|
export async function dbusSend(
|
||||||
dest: string,
|
dest: string,
|
||||||
@ -1268,6 +1270,30 @@ describe('updates target state cache', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('identifies device', () => {
|
||||||
|
let blink: Blink;
|
||||||
|
before(async () => {
|
||||||
|
blink = await getBlink();
|
||||||
|
});
|
||||||
|
|
||||||
|
// This suite doesn't test that the blink submodule writes to the correct
|
||||||
|
// led file location on host. That test should be part of the blink module.
|
||||||
|
it('directs device to blink for set duration', async () => {
|
||||||
|
const blinkStartSpy = spy(blink.pattern, 'start');
|
||||||
|
const blinkStopSpy = spy(blink.pattern, 'stop');
|
||||||
|
const clock = useFakeTimers();
|
||||||
|
|
||||||
|
await actions.identify();
|
||||||
|
expect(blinkStartSpy.callCount).to.equal(1);
|
||||||
|
clock.tick(15000);
|
||||||
|
expect(blinkStopSpy.callCount).to.equal(1);
|
||||||
|
|
||||||
|
blinkStartSpy.restore();
|
||||||
|
blinkStopSpy.restore();
|
||||||
|
clock.restore();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('patches host config', () => {
|
describe('patches host config', () => {
|
||||||
// Stub external dependencies
|
// Stub external dependencies
|
||||||
let hostConfigPatch: SinonStub;
|
let hostConfigPatch: SinonStub;
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import type { SinonStub } from 'sinon';
|
import type { SinonStub } from 'sinon';
|
||||||
import { spy, useFakeTimers, stub } from 'sinon';
|
import { stub } from 'sinon';
|
||||||
|
|
||||||
import * as hostConfig from '~/src/host-config';
|
import * as hostConfig from '~/src/host-config';
|
||||||
import * as actions from '~/src/device-api/actions';
|
import * as actions from '~/src/device-api/actions';
|
||||||
import blink = require('~/lib/blink');
|
|
||||||
|
|
||||||
describe('device-api/actions', () => {
|
describe('device-api/actions', () => {
|
||||||
describe('runs healthchecks', () => {
|
describe('runs healthchecks', () => {
|
||||||
@ -27,25 +26,6 @@ describe('device-api/actions', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('identifies device', () => {
|
|
||||||
// This suite doesn't test that the blink submodule writes to the correct
|
|
||||||
// led file location on host. That test should be part of the blink module.
|
|
||||||
it('directs device to blink for set duration', async () => {
|
|
||||||
const blinkStartSpy = spy(blink.pattern, 'start');
|
|
||||||
const blinkStopSpy = spy(blink.pattern, 'stop');
|
|
||||||
const clock = useFakeTimers();
|
|
||||||
|
|
||||||
actions.identify();
|
|
||||||
expect(blinkStartSpy.callCount).to.equal(1);
|
|
||||||
clock.tick(15000);
|
|
||||||
expect(blinkStopSpy.callCount).to.equal(1);
|
|
||||||
|
|
||||||
blinkStartSpy.restore();
|
|
||||||
blinkStopSpy.restore();
|
|
||||||
clock.restore();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('gets host config', () => {
|
describe('gets host config', () => {
|
||||||
// Stub external dependencies
|
// Stub external dependencies
|
||||||
// TODO: host-config module integration tests
|
// TODO: host-config module integration tests
|
||||||
|
Loading…
x
Reference in New Issue
Block a user