mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-05-07 03:18:12 +00:00
Make local mode only work in development OS, and make it remove app containers and allow unauthenticated API requests
Local mode makes the API accept unauthenticated requests. Local mode now also removes app containers when stopping them. Local mode only works on a host OS that has `VARIANT_ID = "dev"` in /etc/os-release. Also add more explicit logging when stopping an app and it was already stopped or the container was already removed. Change-Type: patch Signed-off-by: Pablo Carranza Velez <pablo@resin.io>
This commit is contained in:
parent
72f6b2cea5
commit
208b799c4b
@ -27,6 +27,8 @@ module.exports = (application) ->
|
|||||||
next()
|
next()
|
||||||
else if headerKey? && bufferEq(new Buffer(headerKey), new Buffer(secret))
|
else if headerKey? && bufferEq(new Buffer(headerKey), new Buffer(secret))
|
||||||
next()
|
next()
|
||||||
|
else if application.localMode
|
||||||
|
next()
|
||||||
else
|
else
|
||||||
res.sendStatus(401)
|
res.sendStatus(401)
|
||||||
.catch (err) ->
|
.catch (err) ->
|
||||||
|
@ -31,6 +31,12 @@ logTypes =
|
|||||||
stopAppSuccess:
|
stopAppSuccess:
|
||||||
eventName: 'Application stop'
|
eventName: 'Application stop'
|
||||||
humanName: 'Killed application'
|
humanName: 'Killed application'
|
||||||
|
stopAppNoop:
|
||||||
|
eventName: 'Application already stopped'
|
||||||
|
humanName: 'Application is already stopped, removing container'
|
||||||
|
stopRemoveAppNoop:
|
||||||
|
eventName: 'Application already stopped and container removed'
|
||||||
|
humanName: 'Application is already stopped and the container removed'
|
||||||
stopAppError:
|
stopAppError:
|
||||||
eventName: 'Application stop error'
|
eventName: 'Application stop error'
|
||||||
humanName: 'Failed to kill application'
|
humanName: 'Failed to kill application'
|
||||||
@ -160,10 +166,12 @@ application.kill = kill = (app, { updateDB = true, removeContainer = true } = {}
|
|||||||
statusCode = '' + err.statusCode
|
statusCode = '' + err.statusCode
|
||||||
# 304 means the container was already stopped - so we can just remove it
|
# 304 means the container was already stopped - so we can just remove it
|
||||||
if statusCode is '304'
|
if statusCode is '304'
|
||||||
|
logSystemEvent(logTypes.stopAppNoop, app)
|
||||||
container.removeAsync(v: true) if removeContainer
|
container.removeAsync(v: true) if removeContainer
|
||||||
return
|
return
|
||||||
# 404 means the container doesn't exist, precisely what we want! :D
|
# 404 means the container doesn't exist, precisely what we want! :D
|
||||||
if statusCode is '404'
|
if statusCode is '404'
|
||||||
|
logSystemEvent(logTypes.stopRemoveAppNoop, app)
|
||||||
return
|
return
|
||||||
throw err
|
throw err
|
||||||
.tap ->
|
.tap ->
|
||||||
@ -412,22 +420,27 @@ apiPollInterval = (val) ->
|
|||||||
|
|
||||||
setLocalMode = (val) ->
|
setLocalMode = (val) ->
|
||||||
mode = checkTruthy(val) ? false
|
mode = checkTruthy(val) ? false
|
||||||
Promise.try ->
|
device.getOSVariant()
|
||||||
if mode and !application.localMode
|
.then (variant) ->
|
||||||
logSystemMessage('Entering local mode, app will be forcefully stopped', {}, 'Enter local mode')
|
if variant is not 'dev'
|
||||||
Promise.map utils.getKnexApps(), (theApp) ->
|
logSystemMessage('Not a development OS, ignoring local mode', {}, 'Ignore local mode')
|
||||||
Promise.using application.lockUpdates(theApp.appId, true), ->
|
return
|
||||||
# There's a slight chance the app changed after the previous select
|
Promise.try ->
|
||||||
# So we fetch it again now the lock is acquired
|
if mode and !application.localMode
|
||||||
utils.getKnexApp(theApp.appId)
|
logSystemMessage('Entering local mode, app will be forcefully stopped', {}, 'Enter local mode')
|
||||||
.then (app) ->
|
Promise.map utils.getKnexApps(), (theApp) ->
|
||||||
application.kill(app, removeContainer: false) if app?
|
Promise.using application.lockUpdates(theApp.appId, true), ->
|
||||||
else if !mode and application.localMode
|
# There's a slight chance the app changed after the previous select
|
||||||
logSystemMessage('Exiting local mode, app will be resumed', {}, 'Exit local mode')
|
# So we fetch it again now the lock is acquired
|
||||||
Promise.map utils.getKnexApps(), (app) ->
|
utils.getKnexApp(theApp.appId)
|
||||||
unlockAndStart(app)
|
.then (app) ->
|
||||||
.then ->
|
application.kill(app) if app?
|
||||||
application.localMode = mode
|
else if !mode and application.localMode
|
||||||
|
logSystemMessage('Exiting local mode, app will be resumed', {}, 'Exit local mode')
|
||||||
|
Promise.map utils.getKnexApps(), (app) ->
|
||||||
|
unlockAndStart(app)
|
||||||
|
.then ->
|
||||||
|
application.localMode = mode
|
||||||
|
|
||||||
specialActionConfigVars = [
|
specialActionConfigVars = [
|
||||||
[ 'RESIN_SUPERVISOR_LOCAL_MODE', setLocalMode ]
|
[ 'RESIN_SUPERVISOR_LOCAL_MODE', setLocalMode ]
|
||||||
|
@ -229,4 +229,10 @@ exports.getOSVersion = memoizePromise ->
|
|||||||
exports.isResinOSv1 = memoizePromise ->
|
exports.isResinOSv1 = memoizePromise ->
|
||||||
exports.getOSVersion().then (osVersion) ->
|
exports.getOSVersion().then (osVersion) ->
|
||||||
return true if /^Resin OS 1./.test(osVersion)
|
return true if /^Resin OS 1./.test(osVersion)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
exports.getOSVariant = memoizePromise ->
|
||||||
|
utils.getOSReleaseField(config.hostOsVersionPath, 'VARIANT_ID')
|
||||||
|
.catch (err) ->
|
||||||
|
console.error('Failed to get OS variant', err, err.stack)
|
||||||
|
return undefined
|
@ -230,7 +230,7 @@ exports.getKnexApp = (appId, columns) ->
|
|||||||
exports.getKnexApps = (columns) ->
|
exports.getKnexApps = (columns) ->
|
||||||
knex('app').select(columns)
|
knex('app').select(columns)
|
||||||
|
|
||||||
exports.getOSVersion = (path) ->
|
exports.getOSReleaseField = (path, field) ->
|
||||||
fs.readFileAsync(path)
|
fs.readFileAsync(path)
|
||||||
.then (releaseData) ->
|
.then (releaseData) ->
|
||||||
lines = releaseData.toString().split('\n')
|
lines = releaseData.toString().split('\n')
|
||||||
@ -239,7 +239,10 @@ exports.getOSVersion = (path) ->
|
|||||||
[ key, val ] = line.split('=')
|
[ key, val ] = line.split('=')
|
||||||
releaseItems[_.trim(key)] = _.trim(val)
|
releaseItems[_.trim(key)] = _.trim(val)
|
||||||
# Remove enclosing quotes: http://stackoverflow.com/a/19156197/2549019
|
# Remove enclosing quotes: http://stackoverflow.com/a/19156197/2549019
|
||||||
return releaseItems['PRETTY_NAME'].replace(/^"(.+(?="$))"$/, '$1')
|
return releaseItems[field].replace(/^"(.+(?="$))"$/, '$1')
|
||||||
|
|
||||||
|
exports.getOSVersion = (path) ->
|
||||||
|
exports.getOSReleaseField(path, 'PRETTY_NAME')
|
||||||
.catch (err) ->
|
.catch (err) ->
|
||||||
console.log('Could not get OS Version: ', err, err.stack)
|
console.log('Could not get OS Version: ', err, err.stack)
|
||||||
return undefined
|
return undefined
|
||||||
|
Loading…
x
Reference in New Issue
Block a user