mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-02-21 10:01:55 +00:00
Ignore the supervisor in the target state
Starting with v3 state endpoint, the supervisor may receive the configuration for the supervisor service on the target state. This commit allows the supervisor to filter out the supervisor container from the current and target state to let the update-balena-supervisor script handle the creation and update of the supervisor container. Updating and creating the supervisor container will be handled by a future commit
This commit is contained in:
parent
8e40f1c2f5
commit
b2b1b111b3
@ -26,6 +26,7 @@ import { checkTruthy, checkString } from '../lib/validation';
|
||||
import { ServiceComposeConfig, DeviceMetadata } from './types/service';
|
||||
import { ImageInspectInfo } from 'dockerode';
|
||||
import { pathExistsOnHost } from '../lib/fs-utils';
|
||||
import { getSupervisorMetadata } from '../lib/supervisor-metadata';
|
||||
|
||||
export interface AppConstructOpts {
|
||||
appId: number;
|
||||
@ -773,20 +774,26 @@ export class App {
|
||||
...opts,
|
||||
};
|
||||
|
||||
const supervisorMeta = await getSupervisorMetadata();
|
||||
|
||||
const isService = (svc: ServiceComposeConfig) =>
|
||||
!svc.labels ||
|
||||
!svc.labels['io.balena.image.class'] ||
|
||||
svc.labels?.['io.balena.image.class'] == null ||
|
||||
svc.labels['io.balena.image.class'] === 'service';
|
||||
|
||||
const isDataStore = (svc: ServiceComposeConfig) =>
|
||||
!svc.labels ||
|
||||
!svc.labels['io.balena.image.store'] ||
|
||||
svc.labels?.['io.balena.image.store'] == null ||
|
||||
svc.labels['io.balena.image.store'] === 'data';
|
||||
|
||||
const isSupervisor = (svc: ServiceComposeConfig) =>
|
||||
app.uuid === supervisorMeta.uuid &&
|
||||
(svc.serviceName === supervisorMeta.serviceName ||
|
||||
// keep compatibility with older supervisor releases
|
||||
svc.serviceName === 'main');
|
||||
|
||||
// In the db, the services are an array, but here we switch them to an
|
||||
// object so that they are consistent
|
||||
const services: Service[] = await Promise.all(
|
||||
(JSON.parse(app.services) ?? [])
|
||||
JSON.parse(app.services ?? [])
|
||||
.filter(
|
||||
// For the host app, `io.balena.image.*` labels indicate special way
|
||||
// to install the service image, so we ignore those we don't know how to
|
||||
@ -795,6 +802,9 @@ export class App {
|
||||
(svc: ServiceComposeConfig) =>
|
||||
!app.isHost || (isService(svc) && isDataStore(svc)),
|
||||
)
|
||||
// Ignore the supervisor service itself from the target state for now
|
||||
// until the supervisor can update itself
|
||||
.filter((svc: ServiceComposeConfig) => !isSupervisor(svc))
|
||||
.map(async (svc: ServiceComposeConfig) => {
|
||||
// Try to fill the image id if the image is downloaded
|
||||
let imageInfo: ImageInspectInfo | undefined;
|
||||
@ -819,6 +829,7 @@ export class App {
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
return new App(
|
||||
{
|
||||
appId: app.appId,
|
||||
|
64
src/lib/supervisor-metadata.ts
Normal file
64
src/lib/supervisor-metadata.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import * as memoizee from 'memoizee';
|
||||
import * as config from '../config';
|
||||
import { InternalInconsistencyError } from './errors';
|
||||
|
||||
export type SupervisorMetadata = {
|
||||
uuid: string;
|
||||
serviceName: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Although it might feel unsettling to hardcode these ids here.
|
||||
* the main purpose of app uuids is to have environment independent
|
||||
* apps. These ids will be the same in balena-cloud.com and balena-staging.com
|
||||
* and they should be the same in open-balena instances for target state
|
||||
* v3 to work with those instances.
|
||||
*
|
||||
* This will only be necessary until the supervisor becomes an actual app
|
||||
* on balena
|
||||
*/
|
||||
const SUPERVISOR_APPS: { [arch: string]: SupervisorMetadata } = {
|
||||
amd64: {
|
||||
uuid: '52e35121417640b1b28a680504e4039b',
|
||||
serviceName: 'balena-supervisor',
|
||||
},
|
||||
aarch64: {
|
||||
uuid: '900de4f3cbac4b9bbd232885a35e407b',
|
||||
serviceName: 'balena-supervisor',
|
||||
},
|
||||
armv7hf: {
|
||||
uuid: '2e66a95795c149959c69472a8c2f92b8',
|
||||
serviceName: 'balena-supervisor',
|
||||
},
|
||||
i386: {
|
||||
uuid: '531b357e155c480cbec0fdd33041a1f5',
|
||||
serviceName: 'balena-supervisor',
|
||||
},
|
||||
rpi: {
|
||||
uuid: '6822565f766e413e96d9bebe2227cdcc',
|
||||
serviceName: 'balena-supervisor',
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the metadata from the supervisor container
|
||||
*
|
||||
* This is needed for the supervisor to identify itself on the target
|
||||
* state and on getStatus() in device-state.ts
|
||||
*
|
||||
* TODO: remove this once the supervisor knows how to update itself
|
||||
*/
|
||||
export const getSupervisorMetadata = memoizee(
|
||||
async () => {
|
||||
const deviceArch = await config.get('deviceArch');
|
||||
const meta: SupervisorMetadata = SUPERVISOR_APPS[deviceArch];
|
||||
if (meta == null) {
|
||||
throw new InternalInconsistencyError(
|
||||
`Unknown device architecture ${deviceArch}. Could not find matching supervisor metadata.`,
|
||||
);
|
||||
}
|
||||
|
||||
return meta;
|
||||
},
|
||||
{ promise: true },
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user