mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-04-24 21:09:47 +00:00
config: Replace supervisorOfflineMode and offlineMode with unmanaged
Change-type: major Signed-off-by: Cameron Diver <cameron@balena.io>
This commit is contained in:
parent
5bea0fdc9d
commit
82602abf8d
@ -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')
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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({
|
||||||
|
@ -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) ->
|
||||||
|
@ -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, {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
})
|
})
|
||||||
|
@ -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: '' }
|
||||||
})
|
})
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
})
|
})
|
||||||
|
@ -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"
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user