config: Replace supervisorOfflineMode and offlineMode with unmanaged

Change-type: major
Signed-off-by: Cameron Diver <cameron@balena.io>
This commit is contained in:
Cameron Diver 2018-12-13 14:14:15 +00:00
parent 5bea0fdc9d
commit 82602abf8d
No known key found for this signature in database
GPG Key ID: 49690ED87032539F
14 changed files with 53 additions and 52 deletions

View File

@ -57,9 +57,9 @@ module.exports = class APIBinder
@readyForUpdates = false @readyForUpdates = false
healthcheck: => healthcheck: =>
@config.getMany([ 'appUpdatePollInterval', 'offlineMode', 'connectivityCheckEnabled' ]) @config.getMany([ 'appUpdatePollInterval', 'unmanaged', 'connectivityCheckEnabled' ])
.then (conf) => .then (conf) =>
if conf.offlineMode if conf.unmanaged
return true return true
timeSinceLastFetch = process.hrtime(@lastTargetStateFetch) timeSinceLastFetch = process.hrtime(@lastTargetStateFetch)
timeSinceLastFetchMs = timeSinceLastFetch[0] * 1000 + timeSinceLastFetch[1] / 1e6 timeSinceLastFetchMs = timeSinceLastFetch[0] * 1000 + timeSinceLastFetch[1] / 1e6
@ -72,9 +72,9 @@ module.exports = class APIBinder
release() release()
initClient: => initClient: =>
@config.getMany([ 'offlineMode', 'apiEndpoint', 'currentApiKey' ]) @config.getMany([ 'unmanaged', 'apiEndpoint', 'currentApiKey' ])
.then ({ offlineMode, apiEndpoint, currentApiKey }) => .then ({ unmanaged, apiEndpoint, currentApiKey }) =>
if offlineMode if unmanaged
console.log('Offline Mode is set, skipping API client initialization') console.log('Offline Mode is set, skipping API client initialization')
return return
baseUrl = url.resolve(apiEndpoint, '/v5/') baseUrl = url.resolve(apiEndpoint, '/v5/')
@ -102,9 +102,9 @@ module.exports = class APIBinder
@loadBackupFromMigration(retryDelay) @loadBackupFromMigration(retryDelay)
start: => start: =>
@config.getMany([ 'apiEndpoint', 'offlineMode', 'bootstrapRetryDelay' ]) @config.getMany([ 'apiEndpoint', 'unmanaged', 'bootstrapRetryDelay' ])
.then ({ apiEndpoint, offlineMode, bootstrapRetryDelay }) => .then ({ apiEndpoint, unmanaged, bootstrapRetryDelay }) =>
if offlineMode if unmanaged
console.log('Offline Mode is set, skipping API binder initialization') console.log('Offline Mode is set, skipping API binder initialization')
# If we are offline because there is no apiEndpoint, there's a chance # If we are offline because there is no apiEndpoint, there's a chance
# we've went through a deprovision. We need to set the initialConfigReported # we've went through a deprovision. We need to set the initialConfigReported
@ -258,14 +258,14 @@ module.exports = class APIBinder
provisionDependentDevice: (device) => provisionDependentDevice: (device) =>
@config.getMany([ @config.getMany([
'offlineMode' 'unmanaged'
'provisioned' 'provisioned'
'apiTimeout' 'apiTimeout'
'userId' 'userId'
'deviceId' 'deviceId'
]) ])
.then (conf) => .then (conf) =>
if conf.offlineMode if conf.unmanaged
throw new Error('Cannot provision dependent device in offline mode') throw new Error('Cannot provision dependent device in offline mode')
if !conf.provisioned if !conf.provisioned
throw new Error('Device must be provisioned to provision a dependent device') throw new Error('Device must be provisioned to provision a dependent device')
@ -283,12 +283,12 @@ module.exports = class APIBinder
patchDevice: (id, updatedFields) => patchDevice: (id, updatedFields) =>
@config.getMany([ @config.getMany([
'offlineMode' 'unmanaged'
'provisioned' 'provisioned'
'apiTimeout' 'apiTimeout'
]) ])
.then (conf) => .then (conf) =>
if conf.offlineMode if conf.unmanaged
throw new Error('Cannot update dependent device in offline mode') throw new Error('Cannot update dependent device in offline mode')
if !conf.provisioned if !conf.provisioned
throw new Error('Device must be provisioned to update a dependent device') throw new Error('Device must be provisioned to update a dependent device')

View File

@ -9,7 +9,6 @@ import supervisorVersion = require('../lib/supervisor-version');
import * as constants from '../lib/constants'; import * as constants from '../lib/constants';
import * as osRelease from '../lib/os-release'; import * as osRelease from '../lib/os-release';
import { ConfigValue } from '../lib/types'; import { ConfigValue } from '../lib/types';
import { checkTruthy } from '../lib/validation';
// A provider for schema entries with source 'func' // A provider for schema entries with source 'func'
type ConfigProviderFunctionGetter = () => Bluebird<any>; type ConfigProviderFunctionGetter = () => Bluebird<any>;
@ -47,17 +46,6 @@ export function createProviderFunctions(
}); });
}, },
}, },
offlineMode: {
get: () => {
return config
.getMany(['apiEndpoint', 'supervisorOfflineMode'])
.then(({ apiEndpoint, supervisorOfflineMode }) => {
return (
checkTruthy(supervisorOfflineMode as boolean) || !apiEndpoint
);
});
},
},
provisioned: { provisioned: {
get: () => { get: () => {
return config return config

View File

@ -46,13 +46,11 @@ class Config extends EventEmitter {
default: constants.defaultMixpanelToken, default: constants.defaultMixpanelToken,
}, },
bootstrapRetryDelay: { source: 'config.json', default: 30000 }, bootstrapRetryDelay: { source: 'config.json', default: 30000 },
supervisorOfflineMode: { source: 'config.json', default: false },
hostname: { source: 'config.json', mutable: true }, hostname: { source: 'config.json', mutable: true },
persistentLogging: { source: 'config.json', default: false, mutable: true }, persistentLogging: { source: 'config.json', default: false, mutable: true },
version: { source: 'func' }, version: { source: 'func' },
currentApiKey: { source: 'func' }, currentApiKey: { source: 'func' },
offlineMode: { source: 'func' },
provisioned: { source: 'func' }, provisioned: { source: 'func' },
osVersion: { source: 'func' }, osVersion: { source: 'func' },
osVariant: { source: 'func' }, osVariant: { source: 'func' },
@ -282,15 +280,15 @@ class Config extends EventEmitter {
'uuid', 'uuid',
'deviceApiKey', 'deviceApiKey',
'apiSecret', 'apiSecret',
'offlineMode', 'unmanaged',
]).then(({ uuid, deviceApiKey, apiSecret, offlineMode }) => { ]).then(({ uuid, deviceApiKey, apiSecret, unmanaged }) => {
// These fields need to be set regardless // These fields need to be set regardless
if (uuid == null || apiSecret == null) { if (uuid == null || apiSecret == null) {
uuid = uuid || this.newUniqueKey(); uuid = uuid || this.newUniqueKey();
apiSecret = apiSecret || this.newUniqueKey(); apiSecret = apiSecret || this.newUniqueKey();
} }
return this.set({ uuid, apiSecret }).then(() => { return this.set({ uuid, apiSecret }).then(() => {
if (offlineMode) { if (unmanaged) {
return; return;
} }
if (!deviceApiKey) { if (!deviceApiKey) {

View File

@ -132,10 +132,10 @@ module.exports = class DeviceConfig
target = _.clone(targetState.local?.config ? {}) target = _.clone(targetState.local?.config ? {})
steps = [] steps = []
Promise.all [ Promise.all [
@config.getMany([ 'deviceType', 'offlineMode' ]) @config.getMany([ 'deviceType', 'unmanaged' ])
@getConfigBackend() @getConfigBackend()
] ]
.then ([{ deviceType, offlineMode }, configBackend ]) => .then ([{ deviceType, unmanaged }, configBackend ]) =>
configChanges = {} configChanges = {}
humanReadableConfigChanges = {} humanReadableConfigChanges = {}
match = { match = {
@ -163,7 +163,7 @@ module.exports = class DeviceConfig
return return
# Check if we need to perform special case actions for the VPN # Check if we need to perform special case actions for the VPN
if !checkTruthy(offlineMode) && if !checkTruthy(unmanaged) &&
!_.isEmpty(target['SUPERVISOR_VPN_CONTROL']) && !_.isEmpty(target['SUPERVISOR_VPN_CONTROL']) &&
@checkBoolChanged(current, target, 'SUPERVISOR_VPN_CONTROL') @checkBoolChanged(current, target, 'SUPERVISOR_VPN_CONTROL')
steps.push({ steps.push({

View File

@ -140,12 +140,12 @@ module.exports = class DeviceState extends EventEmitter
@applications.on('change', @reportCurrentState) @applications.on('change', @reportCurrentState)
healthcheck: => healthcheck: =>
@config.getMany([ 'appUpdatePollInterval', 'offlineMode' ]) @config.getMany([ 'appUpdatePollInterval', 'unmanaged' ])
.then (conf) => .then (conf) =>
cycleTime = process.hrtime(@lastApplyStart) cycleTime = process.hrtime(@lastApplyStart)
cycleTimeMs = cycleTime[0] * 1000 + cycleTime[1] / 1e6 cycleTimeMs = cycleTime[0] * 1000 + cycleTime[1] / 1e6
cycleTimeWithinInterval = cycleTimeMs - @applications.timeSpentFetching < 2 * conf.appUpdatePollInterval cycleTimeWithinInterval = cycleTimeMs - @applications.timeSpentFetching < 2 * conf.appUpdatePollInterval
applyTargetHealthy = conf.offlineMode or !@applyInProgress or @applications.fetchesInProgress > 0 or cycleTimeWithinInterval applyTargetHealthy = conf.unmanaged or !@applyInProgress or @applications.fetchesInProgress > 0 or cycleTimeWithinInterval
return applyTargetHealthy return applyTargetHealthy
migrateLegacyApps: (balenaApi) => migrateLegacyApps: (balenaApi) =>
@ -255,7 +255,7 @@ module.exports = class DeviceState extends EventEmitter
@config.getMany([ @config.getMany([
'initialConfigSaved', 'listenPort', 'apiSecret', 'osVersion', 'osVariant', 'initialConfigSaved', 'listenPort', 'apiSecret', 'osVersion', 'osVariant',
'version', 'provisioned', 'apiEndpoint', 'connectivityCheckEnabled', 'legacyAppsPresent', 'version', 'provisioned', 'apiEndpoint', 'connectivityCheckEnabled', 'legacyAppsPresent',
'targetStateSet', 'offlineMode' 'targetStateSet', 'unmanaged'
]) ])
.then (conf) => .then (conf) =>
@applications.init() @applications.init()
@ -297,8 +297,8 @@ module.exports = class DeviceState extends EventEmitter
.then => .then =>
@triggerApplyTarget({ initial: true }) @triggerApplyTarget({ initial: true })
initNetworkChecks: ({ apiEndpoint, connectivityCheckEnabled, offlineMode }) => initNetworkChecks: ({ apiEndpoint, connectivityCheckEnabled, unmanaged }) =>
return if validation.checkTruthy(offlineMode) return if validation.checkTruthy(unmanaged)
network.startConnectivityCheck apiEndpoint, connectivityCheckEnabled, (connected) => network.startConnectivityCheck apiEndpoint, connectivityCheckEnabled, (connected) =>
@connected = connected @connected = connected
@config.on 'change', (changedConfig) -> @config.on 'change', (changedConfig) ->

View File

@ -11,7 +11,7 @@ export type EventTrackProperties = Dictionary<any>;
interface InitArgs { interface InitArgs {
uuid: string; uuid: string;
offlineMode: boolean; unmanaged: boolean;
mixpanelHost: { host: string; path: string } | null; mixpanelHost: { host: string; path: string } | null;
mixpanelToken: string; mixpanelToken: string;
} }
@ -41,7 +41,7 @@ export class EventTracker {
} }
public init({ public init({
offlineMode, unmanaged,
mixpanelHost, mixpanelHost,
mixpanelToken, mixpanelToken,
uuid, uuid,
@ -52,7 +52,7 @@ export class EventTracker {
uuid, uuid,
supervisorVersion, supervisorVersion,
}; };
if (offlineMode || mixpanelHost == null) { if (unmanaged || mixpanelHost == null) {
return; return;
} }
this.client = Mixpanel.init(mixpanelToken, { this.client = Mixpanel.init(mixpanelToken, {

View File

@ -17,7 +17,7 @@ interface LoggerSetupOptions {
apiEndpoint: string; apiEndpoint: string;
uuid: string; uuid: string;
deviceApiKey: string; deviceApiKey: string;
offlineMode: boolean; unmanaged: boolean;
enableLogs: boolean; enableLogs: boolean;
localMode: boolean; localMode: boolean;
} }
@ -59,7 +59,7 @@ export class Logger {
apiEndpoint, apiEndpoint,
uuid, uuid,
deviceApiKey, deviceApiKey,
offlineMode, unmanaged,
enableLogs, enableLogs,
localMode, localMode,
}: LoggerSetupOptions) { }: LoggerSetupOptions) {
@ -68,7 +68,7 @@ export class Logger {
this.backend = localMode ? this.localBackend : this.balenaBackend; this.backend = localMode ? this.localBackend : this.balenaBackend;
this.backend.offlineMode = offlineMode; this.backend.unmanaged = unmanaged;
this.backend.publishEnabled = enableLogs; this.backend.publishEnabled = enableLogs;
} }

View File

@ -70,7 +70,7 @@ export class BalenaLogBackend extends LogBackend {
} }
public log(message: LogMessage) { public log(message: LogMessage) {
if (this.offlineMode || !this.publishEnabled) { if (this.unmanaged || !this.publishEnabled) {
return; return;
} }

View File

@ -1,7 +1,7 @@
export type LogMessage = Dictionary<any>; export type LogMessage = Dictionary<any>;
export abstract class LogBackend { export abstract class LogBackend {
public offlineMode: boolean; public unmanaged: boolean;
public publishEnabled: boolean = true; public publishEnabled: boolean = true;
public abstract log(message: LogMessage): void; public abstract log(message: LogMessage): void;

View File

@ -17,7 +17,7 @@ startupConfigFields = [
'apiEndpoint' 'apiEndpoint'
'apiSecret' 'apiSecret'
'apiTimeout' 'apiTimeout'
'offlineMode' 'unmanaged'
'deviceApiKey' 'deviceApiKey'
'mixpanelToken' 'mixpanelToken'
'mixpanelHost' 'mixpanelHost'
@ -57,7 +57,7 @@ module.exports = class Supervisor extends EventEmitter
apiEndpoint: conf.apiEndpoint, apiEndpoint: conf.apiEndpoint,
uuid: conf.uuid, uuid: conf.uuid,
deviceApiKey: conf.deviceApiKey, deviceApiKey: conf.deviceApiKey,
offlineMode: checkTruthy(conf.offlineMode), unmanaged: checkTruthy(conf.unmanaged),
enableLogs: checkTruthy(conf.loggingEnabled), enableLogs: checkTruthy(conf.loggingEnabled),
localMode: checkTruthy(conf.localMode) localMode: checkTruthy(conf.localMode)
}) })

View File

@ -25,7 +25,7 @@ describe 'EventTracker', ->
it 'initializes in offline mode', -> it 'initializes in offline mode', ->
promise = @eventTrackerOffline.init({ promise = @eventTrackerOffline.init({
offlineMode: true unmanaged: true
uuid: 'foobar' uuid: 'foobar'
mixpanelHost: { host: '', path: '' } mixpanelHost: { host: '', path: '' }
}) })

View File

@ -140,7 +140,7 @@ describe 'APIBinder', ->
initModels.call(this, '/config-apibinder-offline.json') initModels.call(this, '/config-apibinder-offline.json')
it 'does not generate a key if the device is in offline mode', -> it 'does not generate a key if the device is in offline mode', ->
@config.get('offlineMode').then (mode) => @config.get('unmanaged').then (mode) =>
# Ensure offline mode is set # Ensure offline mode is set
expect(mode).to.equal(true) expect(mode).to.equal(true)
# Check that there is no deviceApiKey # Check that there is no deviceApiKey
@ -153,7 +153,7 @@ describe 'APIBinder', ->
initModels.call(this, '/config-apibinder-offline2.json') initModels.call(this, '/config-apibinder-offline2.json')
it 'does not generate a key with the minimal config', -> it 'does not generate a key with the minimal config', ->
@config.get('offlineMode').then (mode) => @config.get('unmanaged').then (mode) =>
expect(mode).to.equal(true) expect(mode).to.equal(true)
@config.getMany([ 'deviceApiKey', 'uuid' ]).then (conf) -> @config.getMany([ 'deviceApiKey', 'uuid' ]).then (conf) ->
expect(conf['deviceApiKey']).to.be.empty expect(conf['deviceApiKey']).to.be.empty

View File

@ -31,7 +31,7 @@ describe 'Logger', ->
apiEndpoint: 'https://example.com' apiEndpoint: 'https://example.com'
uuid: 'deadbeef' uuid: 'deadbeef'
deviceApiKey: 'secretkey' deviceApiKey: 'secretkey'
offlineMode: false unmanaged: false
enableLogs: true enableLogs: true
localMode: false localMode: false
}) })

View File

@ -1 +1,16 @@
{"applicationName":"supertestrpi3","applicationId":78373,"deviceType":"raspberrypi3","userId":1001,"username":"someone","appUpdatePollInterval":3000,"listenPort":2345,"vpnPort":443,"apiEndpoint":"http://0.0.0.0:3000","vpnEndpoint":"vpn.resin.io","registryEndpoint":"registry2.resin.io","deltaEndpoint":"https://delta.resin.io","mixpanelToken":"baz","apiKey":"boo","version":"2.0.6+rev3.prod","supervisorOfflineMode":true} {
"applicationName": "supertestrpi3",
"applicationId": 78373,
"deviceType": "raspberrypi3",
"userId": 1001,
"username": "someone",
"appUpdatePollInterval": 3000,
"listenPort": 2345,
"vpnPort": 443,
"vpnEndpoint": "vpn.resin.io",
"registryEndpoint": "registry2.resin.io",
"deltaEndpoint": "https://delta.resin.io",
"mixpanelToken": "baz",
"apiKey": "boo",
"version": "2.0.6+rev3.prod"
}