Merge pull request #949 from balena-io/use-default-device-config

When a device config variables requested value is not valid, fallback to the default
This commit is contained in:
CameronDiver 2019-03-28 09:43:30 +00:00 committed by GitHub
commit e956242d45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 17 deletions

View File

@ -2,18 +2,18 @@ ARG ARCH=amd64
# The node version here should match the version of the runtime image which is
# specified in the base-image subdirectory in the project
FROM resin/rpi-node:6.13.1-slim as rpi-node-base
FROM resin/armv7hf-node:6.13.1-slim as armv7hf-node-base
FROM resin/aarch64-node:6.13.1-slim as aarch64-node-base
FROM balenalib/rpi-node:6.16.0 as rpi-node-base
FROM balenalib/armv7hf-node:6.16.0 as armv7hf-node-base
FROM balenalib/aarch64-node:6.16.0 as aarch64-node-base
RUN [ "cross-build-start" ]
RUN sed -i '/security.debian.org jessie/d' /etc/apt/sources.list
RUN [ "cross-build-end" ]
FROM resin/amd64-node:6.13.1-slim as amd64-node-base
FROM balenalib/amd64-node:6.16.0 as amd64-node-base
RUN echo '#!/bin/sh\nexit 0' > /usr/bin/cross-build-start && chmod +x /usr/bin/cross-build-start \
&& echo '#!/bin/sh\nexit 0' > /usr/bin/cross-build-end && chmod +x /usr/bin/cross-build-end
FROM resin/i386-node:6.13.1-slim as i386-node-base
FROM balenalib/i386-node:6.16.0 as i386-node-base
RUN echo '#!/bin/sh\nexit 0' > /usr/bin/cross-build-start && chmod +x /usr/bin/cross-build-start \
&& echo '#!/bin/sh\nexit 0' > /usr/bin/cross-build-end && chmod +x /usr/bin/cross-build-end

View File

@ -223,6 +223,23 @@ export class Config extends (EventEmitter as {
return generateUniqueKey();
}
public valueIsValid<T extends SchemaTypeKey>(
key: T,
value: unknown,
): boolean {
// If the default entry in the schema is a type and not a value,
// use this in the validation of the value
const schemaTypesEntry = schemaTypes[key as SchemaTypeKey];
let type: t.Type<unknown>;
if (schemaTypesEntry.default instanceof t.Type) {
type = t.union([schemaTypesEntry.type, schemaTypesEntry.default]);
} else {
type = schemaTypesEntry.type;
}
return type.decode(value).isRight();
}
private async getSchema<T extends Schema.SchemaKey>(
key: T,
db: Transaction,

View File

@ -1,11 +1,12 @@
import * as _ from 'lodash';
import { inspect } from 'util';
import Config from './config';
import { SchemaTypeKey } from './config/schema-type';
import Database, { Transaction } from './db';
import Logger from './logger';
import { DeviceConfigBackend, ConfigOptions } from './config/backend';
import { ConfigOptions, DeviceConfigBackend } from './config/backend';
import * as configUtils from './config/utils';
import { UnitNotLoadedError } from './lib/errors';
import * as systemd from './lib/systemd';
@ -386,7 +387,8 @@ export class DeviceConfig {
_.each(
DeviceConfig.configKeys,
({ envVarName, varType, rebootRequired }, key) => {
({ envVarName, varType, rebootRequired, defaultValue }, key) => {
let changingValue: null | string = null;
// Test if the key is different
if (
!DeviceConfig.configTest(
@ -395,10 +397,39 @@ export class DeviceConfig {
target[envVarName],
)
) {
// Save the change if it is
configChanges[key] = target[envVarName];
humanReadableConfigChanges[envVarName] = target[envVarName];
reboot = rebootRequired || reboot;
// Check that the difference is not due to the variable having an invalid
// value set from the cloud
if (
this.config.valueIsValid(key as SchemaTypeKey, target[envVarName])
) {
// Save the change if it is both valid and different
changingValue = target[envVarName];
} else {
if (
!DeviceConfig.configTest(
varType,
current[envVarName],
defaultValue,
)
) {
const message = `Warning: Ignoring invalid device configuration value for ${key}, value: ${inspect(
target[envVarName],
)}. Falling back to default (${defaultValue})`;
this.logger.logSystemMessage(
message,
{ key: envVarName, value: target[envVarName] },
'invalidDeviceConfig',
false,
);
// Set it to the default value if it is different to the current
changingValue = defaultValue;
}
}
if (changingValue != null) {
configChanges[key] = changingValue;
humanReadableConfigChanges[envVarName] = changingValue;
reboot = rebootRequired || reboot;
}
}
},
);

View File

@ -113,16 +113,19 @@ export class Logger {
message: string,
eventObj?: LogEventObject,
eventName?: string,
track: boolean = true,
) {
const msgObj: LogMessage = { message, isSystem: true };
if (eventObj != null && eventObj.error != null) {
msgObj.isStdErr = true;
}
this.log(msgObj);
this.eventTracker.track(
eventName != null ? eventName : message,
eventObj != null ? eventObj : {},
);
if (track) {
this.eventTracker.track(
eventName != null ? eventName : message,
eventObj != null ? eventObj : {},
);
}
}
public lock(containerId: string): Bluebird.Disposer<() => void> {
@ -153,7 +156,11 @@ export class Logger {
});
}
public logSystemEvent(logType: LogType, obj: LogEventObject): void {
public logSystemEvent(
logType: LogType,
obj: LogEventObject,
track: boolean = true,
): void {
let message = logType.humanName;
const objectName = this.objectNameForLogs(obj);
if (objectName != null) {
@ -168,7 +175,7 @@ export class Logger {
}
message += ` due to '${errorMessage}'`;
}
this.logSystemMessage(message, obj, logType.eventName);
this.logSystemMessage(message, obj, logType.eventName, track);
}
public logConfigChange(