mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2024-12-23 15:32:24 +00:00
Report device state in local mode
In local mode, we now update device status on the backend, but omit applications info in our updates. Closes: #959 Change-type: minor Signed-off-by: Roman Mazur <roman@balena.io>
This commit is contained in:
parent
f662a6be39
commit
024b9c45f4
@ -38,7 +38,7 @@ const INTERNAL_STATE_KEYS = [
|
||||
'update_failed',
|
||||
];
|
||||
|
||||
interface APIBinderConstructOpts {
|
||||
export interface APIBinderConstructOpts {
|
||||
config: Config;
|
||||
// FIXME: Remove this
|
||||
db: Database;
|
||||
@ -450,7 +450,7 @@ export class APIBinder {
|
||||
|
||||
private async sendReportPatch(
|
||||
stateDiff: DeviceApplicationState,
|
||||
conf: { apiEndpoint: string; uuid: string },
|
||||
conf: { apiEndpoint: string; uuid: string; localMode: boolean },
|
||||
) {
|
||||
if (this.cachedBalenaApi == null) {
|
||||
throw new InternalInconsistencyError(
|
||||
@ -458,6 +458,16 @@ export class APIBinder {
|
||||
);
|
||||
}
|
||||
|
||||
let body = stateDiff;
|
||||
if (conf.localMode) {
|
||||
body = this.stripDeviceStateInLocalMode(stateDiff);
|
||||
// In local mode, check if it still makes sense to send any updates after data strip.
|
||||
if (_.isEmpty(body.local)) {
|
||||
// Nothing to send.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const endpoint = url.resolve(
|
||||
conf.apiEndpoint,
|
||||
`/device/v2/${conf.uuid}/state`,
|
||||
@ -467,7 +477,7 @@ export class APIBinder {
|
||||
{
|
||||
method: 'PATCH',
|
||||
url: endpoint,
|
||||
body: stateDiff,
|
||||
body,
|
||||
},
|
||||
this.cachedBalenaApi.passthrough,
|
||||
);
|
||||
@ -475,6 +485,18 @@ export class APIBinder {
|
||||
await this.cachedBalenaApi._request(requestParams);
|
||||
}
|
||||
|
||||
// Returns an object that contains only status fields relevant for the local mode.
|
||||
// It basically removes information about applications state.
|
||||
public stripDeviceStateInLocalMode(
|
||||
state: DeviceApplicationState,
|
||||
): DeviceApplicationState {
|
||||
return {
|
||||
local: _.cloneDeep(
|
||||
_.omit(state.local, 'apps', 'is_on__commit', 'logs_channel'),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
private async report() {
|
||||
const conf = await this.config.getMany([
|
||||
'deviceId',
|
||||
@ -484,17 +506,12 @@ export class APIBinder {
|
||||
'localMode',
|
||||
]);
|
||||
|
||||
if (conf.localMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
const stateDiff = this.getStateDiff();
|
||||
if (_.size(stateDiff) === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const apiEndpoint = conf.apiEndpoint;
|
||||
const uuid = conf.uuid;
|
||||
const { apiEndpoint, uuid, localMode } = conf;
|
||||
if (uuid == null || apiEndpoint == null) {
|
||||
throw new InternalInconsistencyError(
|
||||
'No uuid or apiEndpoint provided to ApiBinder.report',
|
||||
@ -503,7 +520,7 @@ export class APIBinder {
|
||||
|
||||
try {
|
||||
await Bluebird.resolve(
|
||||
this.sendReportPatch(stateDiff, { apiEndpoint, uuid }),
|
||||
this.sendReportPatch(stateDiff, { apiEndpoint, uuid, localMode }),
|
||||
).timeout(conf.apiTimeout);
|
||||
|
||||
this.stateReportErrors = 0;
|
||||
@ -526,9 +543,6 @@ export class APIBinder {
|
||||
|
||||
private reportCurrentState(): null {
|
||||
(async () => {
|
||||
if ((await this.config.get('localMode')) === true) {
|
||||
return;
|
||||
}
|
||||
this.reportPending = true;
|
||||
try {
|
||||
const currentDeviceState = await this.deviceState.getStatus();
|
||||
|
44
test/api-binder.ts
Normal file
44
test/api-binder.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { expect } from 'chai';
|
||||
import { APIBinder, APIBinderConstructOpts } from '../src/api-binder';
|
||||
import { DeviceApplicationState } from '../src/types/state';
|
||||
|
||||
describe('APIBinder', () => {
|
||||
let apiBinder: APIBinder;
|
||||
|
||||
before(() => {
|
||||
apiBinder = new APIBinder({} as APIBinderConstructOpts);
|
||||
});
|
||||
|
||||
describe('stripDeviceStateInLocalMode', () => {
|
||||
const sampleState = {
|
||||
local: {
|
||||
ip_address: '192.168.1.42 192.168.1.99',
|
||||
api_port: 48484,
|
||||
api_secret:
|
||||
'20ffbd6e15aba827dca6381912d6aeb6c3a7a7c7206d4dfadf0d2f0a9e1136',
|
||||
os_version: 'balenaOS 2.32.0+rev4',
|
||||
os_variant: 'dev',
|
||||
supervisor_version: '9.16.3',
|
||||
provisioning_progress: null,
|
||||
provisioning_state: '',
|
||||
status: 'Idle',
|
||||
logs_channel: null,
|
||||
apps: {},
|
||||
is_on__commit: 'whatever',
|
||||
},
|
||||
dependent: { apps: {} },
|
||||
} as DeviceApplicationState;
|
||||
|
||||
it('should strip applications data', () => {
|
||||
const result = apiBinder.stripDeviceStateInLocalMode(
|
||||
sampleState,
|
||||
) as Dictionary<any>;
|
||||
expect(result).to.not.have.property('dependent');
|
||||
|
||||
const local = result['local'];
|
||||
expect(local).to.not.have.property('apps');
|
||||
expect(local).to.not.have.property('is_on__commit');
|
||||
expect(local).to.not.have.property('logs_channel');
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user