mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2024-12-20 06:07:57 +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()
|
||||
else if headerKey? && bufferEq(new Buffer(headerKey), new Buffer(secret))
|
||||
next()
|
||||
else if application.localMode
|
||||
next()
|
||||
else
|
||||
res.sendStatus(401)
|
||||
.catch (err) ->
|
||||
|
@ -31,6 +31,12 @@ logTypes =
|
||||
stopAppSuccess:
|
||||
eventName: 'Application stop'
|
||||
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:
|
||||
eventName: 'Application stop error'
|
||||
humanName: 'Failed to kill application'
|
||||
@ -160,10 +166,12 @@ application.kill = kill = (app, { updateDB = true, removeContainer = true } = {}
|
||||
statusCode = '' + err.statusCode
|
||||
# 304 means the container was already stopped - so we can just remove it
|
||||
if statusCode is '304'
|
||||
logSystemEvent(logTypes.stopAppNoop, app)
|
||||
container.removeAsync(v: true) if removeContainer
|
||||
return
|
||||
# 404 means the container doesn't exist, precisely what we want! :D
|
||||
if statusCode is '404'
|
||||
logSystemEvent(logTypes.stopRemoveAppNoop, app)
|
||||
return
|
||||
throw err
|
||||
.tap ->
|
||||
@ -412,22 +420,27 @@ apiPollInterval = (val) ->
|
||||
|
||||
setLocalMode = (val) ->
|
||||
mode = checkTruthy(val) ? false
|
||||
Promise.try ->
|
||||
if mode and !application.localMode
|
||||
logSystemMessage('Entering local mode, app will be forcefully stopped', {}, 'Enter local mode')
|
||||
Promise.map utils.getKnexApps(), (theApp) ->
|
||||
Promise.using application.lockUpdates(theApp.appId, true), ->
|
||||
# There's a slight chance the app changed after the previous select
|
||||
# So we fetch it again now the lock is acquired
|
||||
utils.getKnexApp(theApp.appId)
|
||||
.then (app) ->
|
||||
application.kill(app, removeContainer: false) if app?
|
||||
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
|
||||
device.getOSVariant()
|
||||
.then (variant) ->
|
||||
if variant is not 'dev'
|
||||
logSystemMessage('Not a development OS, ignoring local mode', {}, 'Ignore local mode')
|
||||
return
|
||||
Promise.try ->
|
||||
if mode and !application.localMode
|
||||
logSystemMessage('Entering local mode, app will be forcefully stopped', {}, 'Enter local mode')
|
||||
Promise.map utils.getKnexApps(), (theApp) ->
|
||||
Promise.using application.lockUpdates(theApp.appId, true), ->
|
||||
# There's a slight chance the app changed after the previous select
|
||||
# So we fetch it again now the lock is acquired
|
||||
utils.getKnexApp(theApp.appId)
|
||||
.then (app) ->
|
||||
application.kill(app) if app?
|
||||
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 = [
|
||||
[ 'RESIN_SUPERVISOR_LOCAL_MODE', setLocalMode ]
|
||||
|
@ -229,4 +229,10 @@ exports.getOSVersion = memoizePromise ->
|
||||
exports.isResinOSv1 = memoizePromise ->
|
||||
exports.getOSVersion().then (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) ->
|
||||
knex('app').select(columns)
|
||||
|
||||
exports.getOSVersion = (path) ->
|
||||
exports.getOSReleaseField = (path, field) ->
|
||||
fs.readFileAsync(path)
|
||||
.then (releaseData) ->
|
||||
lines = releaseData.toString().split('\n')
|
||||
@ -239,7 +239,10 @@ exports.getOSVersion = (path) ->
|
||||
[ key, val ] = line.split('=')
|
||||
releaseItems[_.trim(key)] = _.trim(val)
|
||||
# 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) ->
|
||||
console.log('Could not get OS Version: ', err, err.stack)
|
||||
return undefined
|
||||
|
Loading…
Reference in New Issue
Block a user