Respect an initialDeviceName field in the config.json

Closes: #909
Change-type: minor
Signed-off-by: Cameron Diver <cameron@balena.io>
This commit is contained in:
Cameron Diver 2020-02-21 13:45:27 +07:00
parent dec79e11f4
commit b5918f0d84
3 changed files with 60 additions and 5 deletions

View File

@ -169,6 +169,7 @@ export class APIBinder {
'apiEndpoint',
'unmanaged',
'bootstrapRetryDelay',
'initialDeviceName',
]);
let { apiEndpoint } = conf;
const { unmanaged, bootstrapRetryDelay } = conf;
@ -197,7 +198,19 @@ export class APIBinder {
// Either we haven't reported our initial config or we've been re-provisioned
if (apiEndpoint !== initialConfigReported) {
log.info('Reporting initial configuration');
await this.reportInitialConfig(apiEndpoint, bootstrapRetryDelay);
// We fetch the deviceId here to ensure it's been set
const deviceId = await config.get('deviceId');
if (deviceId == null) {
throw new InternalInconsistencyError(
`Attempt to report initial configuration without a device ID`,
);
}
await this.reportInitialConfig(
apiEndpoint,
deviceId,
bootstrapRetryDelay,
conf.initialDeviceName ?? undefined,
);
}
log.debug('Starting current state report');
@ -605,7 +618,11 @@ export class APIBinder {
// Creates the necessary config vars in the API to match the current device state,
// without overwriting any variables that are already set.
private async reportInitialEnv(apiEndpoint: string) {
private async reportInitialEnv(
apiEndpoint: string,
deviceId: number,
initialName?: string,
) {
if (this.balenaApi == null) {
throw new InternalInconsistencyError(
'Attempt to report initial environment without an API client',
@ -628,7 +645,6 @@ export class APIBinder {
const targetConfig = await this.deviceState.deviceConfig.formatConfigKeys(
targetConfigUnformatted,
);
const deviceId = await config.get('deviceId');
if (!currentState.local.config) {
throw new InternalInconsistencyError(
@ -660,19 +676,30 @@ export class APIBinder {
}
}
if (initialName != null) {
await this.reportInitialName(deviceId, initialName);
}
await config.set({ initialConfigReported: apiEndpoint });
}
private async reportInitialConfig(
apiEndpoint: string,
deviceId: number,
retryDelay: number,
initialName?: string,
): Promise<void> {
try {
await this.reportInitialEnv(apiEndpoint);
await this.reportInitialEnv(apiEndpoint, deviceId, initialName);
} catch (err) {
log.error('Error reporting initial configuration, will retry', err);
await Bluebird.delay(retryDelay);
await this.reportInitialConfig(apiEndpoint, retryDelay);
await this.reportInitialConfig(
apiEndpoint,
deviceId,
retryDelay,
initialName,
);
}
}
@ -897,6 +924,25 @@ export class APIBinder {
return router;
}
private async reportInitialName(
deviceId: number,
name: string,
): Promise<void> {
if (this.balenaApi == null) {
throw new InternalInconsistencyError(
`Attempt to set an initial device name without an API client`,
);
}
await this.balenaApi.patch({
resource: 'device',
id: deviceId,
body: {
device_name: name,
},
});
}
}
export default APIBinder;

View File

@ -82,6 +82,10 @@ export const schemaTypes = {
type: PermissiveBoolean,
default: false,
},
initialDeviceName: {
type: t.string,
default: NullOrUndefined,
},
// Database types
apiSecret: {

View File

@ -79,6 +79,11 @@ export const schema = {
mutable: true,
removeIfNull: false,
},
initialDeviceName: {
source: 'config.json',
mutable: false,
removeIfNull: false,
},
apiSecret: {
source: 'db',