mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-01-03 04:26:44 +00:00
Support for several compose features
Plus a few bugfixes. * Add support for cgroup_parent * Add support for specifying a single value in tmpfs * Fix support for extra_hosts * Add support for group_add * Add support for pid mode (only host and empty value are supported for now) * Add support for pids_limit * Add support for security_opt * Add support for storage_opt * Add support for userns_mode * Add support for ipc (except for another container's) * Add support for mac_address * Add support for oom_kill_disable * Add support for 'user' compose option * Add support for working_dir and fix support for user when image specifies it * Add support for bind-mounting the balena socket using a label Signed-off-by: Pablo Carranza Velez <pablo@resin.io>
This commit is contained in:
parent
38c3a8bdf3
commit
ec22bfcb29
@ -58,6 +58,22 @@ getStopSignal = (service, imageInfo) ->
|
|||||||
sig = sig.toString()
|
sig = sig.toString()
|
||||||
return sig
|
return sig
|
||||||
|
|
||||||
|
getUser = (service, imageInfo) ->
|
||||||
|
user = ''
|
||||||
|
if service.user?
|
||||||
|
user = service.user
|
||||||
|
else if imageInfo?.Config?.User?
|
||||||
|
user = imageInfo.Config.User
|
||||||
|
return user
|
||||||
|
|
||||||
|
getWorkingDir = (service, imageInfo) ->
|
||||||
|
workingDir = ''
|
||||||
|
if service.workingDir?
|
||||||
|
workingDir = service.workingDir
|
||||||
|
else if imageInfo?.Config?.WorkingDir?
|
||||||
|
workingDir = imageInfo.Config.WorkingDir
|
||||||
|
return workingDir
|
||||||
|
|
||||||
buildHealthcheckTest = (test) ->
|
buildHealthcheckTest = (test) ->
|
||||||
if _.isString(test)
|
if _.isString(test)
|
||||||
return [ 'CMD-SHELL', test ]
|
return [ 'CMD-SHELL', test ]
|
||||||
@ -151,6 +167,7 @@ module.exports = class Service
|
|||||||
@cpuset
|
@cpuset
|
||||||
@nanoCpus
|
@nanoCpus
|
||||||
@domainname
|
@domainname
|
||||||
|
@oomKillDisable
|
||||||
@oomScoreAdj
|
@oomScoreAdj
|
||||||
@dns
|
@dns
|
||||||
@dnsSearch
|
@dnsSearch
|
||||||
@ -166,6 +183,17 @@ module.exports = class Service
|
|||||||
@readOnly
|
@readOnly
|
||||||
@sysctls
|
@sysctls
|
||||||
@hostname
|
@hostname
|
||||||
|
@cgroupParent
|
||||||
|
@groupAdd
|
||||||
|
@pid
|
||||||
|
@pidsLimit
|
||||||
|
@securityOpt
|
||||||
|
@storageOpt
|
||||||
|
@usernsMode
|
||||||
|
@ipc
|
||||||
|
@macAddress
|
||||||
|
@user
|
||||||
|
@workingDir
|
||||||
} = _.mapKeys(serviceProperties, (v, k) -> _.camelCase(k))
|
} = _.mapKeys(serviceProperties, (v, k) -> _.camelCase(k))
|
||||||
|
|
||||||
@networks ?= {}
|
@networks ?= {}
|
||||||
@ -193,6 +221,7 @@ module.exports = class Service
|
|||||||
@domainname ?= ''
|
@domainname ?= ''
|
||||||
|
|
||||||
@oomScoreAdj ?= 0
|
@oomScoreAdj ?= 0
|
||||||
|
@oomKillDisable ?= false
|
||||||
@tmpfs ?= []
|
@tmpfs ?= []
|
||||||
@extraHosts ?= []
|
@extraHosts ?= []
|
||||||
|
|
||||||
@ -200,16 +229,29 @@ module.exports = class Service
|
|||||||
@dnsSearch ?= []
|
@dnsSearch ?= []
|
||||||
@dnsOpt ?= []
|
@dnsOpt ?= []
|
||||||
@ulimitsArray ?= []
|
@ulimitsArray ?= []
|
||||||
|
@groupAdd ?= []
|
||||||
|
|
||||||
@stopSignal ?= null
|
@stopSignal ?= null
|
||||||
@stopGracePeriod ?= null
|
@stopGracePeriod ?= null
|
||||||
@healthcheck ?= null
|
@healthcheck ?= null
|
||||||
@init ?= null
|
@init ?= null
|
||||||
@readOnly ?= false
|
@readOnly ?= false
|
||||||
|
@macAddress ?= null
|
||||||
|
|
||||||
@sysctls ?= {}
|
@sysctls ?= {}
|
||||||
|
|
||||||
@hostname ?= ''
|
@hostname ?= ''
|
||||||
|
@cgroupParent ?= ''
|
||||||
|
@pid ?= ''
|
||||||
|
@pidsLimit ?= 0
|
||||||
|
@securityOpt ?= []
|
||||||
|
@storageOpt ?= {}
|
||||||
|
@usernsMode ?= ''
|
||||||
|
@user ?= ''
|
||||||
|
@workingDir ?= ''
|
||||||
|
|
||||||
|
if _.isEmpty(@ipc)
|
||||||
|
@ipc = 'shareable'
|
||||||
|
|
||||||
# If the service has no containerId, it is a target service and has to be normalised and extended
|
# If the service has no containerId, it is a target service and has to be normalised and extended
|
||||||
if !@containerId?
|
if !@containerId?
|
||||||
@ -217,7 +259,7 @@ module.exports = class Service
|
|||||||
if @networkMode not in [ 'host', 'bridge', 'none' ]
|
if @networkMode not in [ 'host', 'bridge', 'none' ]
|
||||||
@networkMode = "#{@appId}_#{@networkMode}"
|
@networkMode = "#{@appId}_#{@networkMode}"
|
||||||
|
|
||||||
@networks = _.mapKeys @networks, (v, k) ->
|
@networks = _.mapKeys @networks, (v, k) =>
|
||||||
if k not in [ 'host', 'bridge', 'none' ]
|
if k not in [ 'host', 'bridge', 'none' ]
|
||||||
return "#{@appId}_#{k}"
|
return "#{@appId}_#{k}"
|
||||||
else
|
else
|
||||||
@ -230,6 +272,8 @@ module.exports = class Service
|
|||||||
@entrypoint = getEntrypoint(serviceProperties, opts.imageInfo)
|
@entrypoint = getEntrypoint(serviceProperties, opts.imageInfo)
|
||||||
@stopSignal = getStopSignal(serviceProperties, opts.imageInfo)
|
@stopSignal = getStopSignal(serviceProperties, opts.imageInfo)
|
||||||
@healthcheck = getHealthcheck(serviceProperties, opts.imageInfo)
|
@healthcheck = getHealthcheck(serviceProperties, opts.imageInfo)
|
||||||
|
@workingDir = getWorkingDir(serviceProperties, opts.imageInfo)
|
||||||
|
@user = getUser(serviceProperties, opts.imageInfo)
|
||||||
@extendEnvVars(opts)
|
@extendEnvVars(opts)
|
||||||
@extendLabels(opts.imageInfo)
|
@extendLabels(opts.imageInfo)
|
||||||
@extendAndSanitiseVolumes(opts.imageInfo)
|
@extendAndSanitiseVolumes(opts.imageInfo)
|
||||||
@ -243,6 +287,9 @@ module.exports = class Service
|
|||||||
if @dnsSearch?
|
if @dnsSearch?
|
||||||
if !Array.isArray(@dnsSearch)
|
if !Array.isArray(@dnsSearch)
|
||||||
@dnsSearch = [ @dns ]
|
@dnsSearch = [ @dns ]
|
||||||
|
if @tmpfs?
|
||||||
|
if !Array.isArray(@tmpfs)
|
||||||
|
@tmpfs = [ @tmpfs ]
|
||||||
|
|
||||||
@nanoCpus = Math.round(Number(@cpus) * 10 ** 9)
|
@nanoCpus = Math.round(Number(@cpus) * 10 ** 9)
|
||||||
|
|
||||||
@ -258,6 +305,7 @@ module.exports = class Service
|
|||||||
d = new Duration(@stopGracePeriod)
|
d = new Duration(@stopGracePeriod)
|
||||||
@stopGracePeriod = d.seconds()
|
@stopGracePeriod = d.seconds()
|
||||||
|
|
||||||
|
@oomKillDisable = Boolean(@oomKillDisable)
|
||||||
@readOnly = Boolean(@readOnly)
|
@readOnly = Boolean(@readOnly)
|
||||||
|
|
||||||
if Array.isArray(@sysctls)
|
if Array.isArray(@sysctls)
|
||||||
@ -286,6 +334,9 @@ module.exports = class Service
|
|||||||
@volumes.push('/lib/modules:/lib/modules')
|
@volumes.push('/lib/modules:/lib/modules')
|
||||||
if checkTruthy(@labels['io.resin.features.firmware'])
|
if checkTruthy(@labels['io.resin.features.firmware'])
|
||||||
@volumes.push('/lib/firmware:/lib/firmware')
|
@volumes.push('/lib/firmware:/lib/firmware')
|
||||||
|
if checkTruthy(@labels['io.resin.features.balena-socket'])
|
||||||
|
@volumes.push('/var/run/balena.sock:/var/run/balena.sock')
|
||||||
|
@environment['DOCKER_HOST'] ?= 'unix:///var/run/balena.sock'
|
||||||
if checkTruthy(@labels['io.resin.features.supervisor-api'])
|
if checkTruthy(@labels['io.resin.features.supervisor-api'])
|
||||||
@_addSupervisorApi(opts)
|
@_addSupervisorApi(opts)
|
||||||
else
|
else
|
||||||
@ -452,6 +503,7 @@ module.exports = class Service
|
|||||||
nanoCpus: container.HostConfig.NanoCpus
|
nanoCpus: container.HostConfig.NanoCpus
|
||||||
cpuset: container.HostConfig.CpusetCpus
|
cpuset: container.HostConfig.CpusetCpus
|
||||||
domainname: container.Config.Domainname
|
domainname: container.Config.Domainname
|
||||||
|
oomKillDisable: container.HostConfig.OomKillDisable
|
||||||
oomScoreAdj: container.HostConfig.OomScoreAdj
|
oomScoreAdj: container.HostConfig.OomScoreAdj
|
||||||
dns: container.HostConfig.Dns
|
dns: container.HostConfig.Dns
|
||||||
dnsSearch: container.HostConfig.DnsSearch
|
dnsSearch: container.HostConfig.DnsSearch
|
||||||
@ -466,6 +518,16 @@ module.exports = class Service
|
|||||||
readOnly: container.HostConfig.ReadonlyRootfs
|
readOnly: container.HostConfig.ReadonlyRootfs
|
||||||
sysctls: container.HostConfig.Sysctls
|
sysctls: container.HostConfig.Sysctls
|
||||||
hostname: hostname
|
hostname: hostname
|
||||||
|
cgroupParent: container.HostConfig.CgroupParent
|
||||||
|
groupAdd: container.HostConfig.GroupAdd
|
||||||
|
pid: container.HostConfig.PidMode
|
||||||
|
pidsLimit: container.HostConfig.PidsLimit
|
||||||
|
securityOpt: container.HostConfig.SecurityOpt
|
||||||
|
storageOpt: container.HostConfig.StorageOpt
|
||||||
|
usernsMode: container.HostConfig.UsernsMode
|
||||||
|
ipc: container.HostConfig.IpcMode
|
||||||
|
macAddress: container.Config.MacAddress
|
||||||
|
user: container.Config.User
|
||||||
}
|
}
|
||||||
# I've seen docker use either 'no' or '' for no restart policy, so we normalise to 'no'.
|
# I've seen docker use either 'no' or '' for no restart policy, so we normalise to 'no'.
|
||||||
if service.restartPolicy.Name == ''
|
if service.restartPolicy.Name == ''
|
||||||
@ -523,6 +585,7 @@ module.exports = class Service
|
|||||||
ExposedPorts: @exposedPorts
|
ExposedPorts: @exposedPorts
|
||||||
Labels: @labels
|
Labels: @labels
|
||||||
Domainname: @domainname
|
Domainname: @domainname
|
||||||
|
User: @user
|
||||||
HostConfig:
|
HostConfig:
|
||||||
Memory: @memLimit
|
Memory: @memLimit
|
||||||
MemoryReservation: @memReservation
|
MemoryReservation: @memReservation
|
||||||
@ -539,6 +602,7 @@ module.exports = class Service
|
|||||||
CpuQuota: @cpuQuota
|
CpuQuota: @cpuQuota
|
||||||
CpusetCpus: @cpuset
|
CpusetCpus: @cpuset
|
||||||
OomScoreAdj: @oomScoreAdj
|
OomScoreAdj: @oomScoreAdj
|
||||||
|
OomKillDisable: @oomKillDisable
|
||||||
Tmpfs: tmpfs
|
Tmpfs: tmpfs
|
||||||
Dns: @dns
|
Dns: @dns
|
||||||
DnsSearch: @dnsSearch
|
DnsSearch: @dnsSearch
|
||||||
@ -546,6 +610,14 @@ module.exports = class Service
|
|||||||
Ulimits: @ulimitsArray
|
Ulimits: @ulimitsArray
|
||||||
ReadonlyRootfs: @readOnly
|
ReadonlyRootfs: @readOnly
|
||||||
Sysctls: @sysctls
|
Sysctls: @sysctls
|
||||||
|
CgroupParent: @cgroupParent
|
||||||
|
ExtraHosts: @extraHosts
|
||||||
|
GroupAdd: @groupAdd
|
||||||
|
PidMode: @pid
|
||||||
|
PidsLimit: @pidsLimit
|
||||||
|
SecurityOpt: @securityOpt
|
||||||
|
UsernsMode: @usernsMode
|
||||||
|
IpcMode: @ipc
|
||||||
}
|
}
|
||||||
if @stopSignal?
|
if @stopSignal?
|
||||||
conf.StopSignal = @stopSignal
|
conf.StopSignal = @stopSignal
|
||||||
@ -568,6 +640,10 @@ module.exports = class Service
|
|||||||
conf.HostConfig.Init = true
|
conf.HostConfig.Init = true
|
||||||
if !_.isEmpty(@hostname)
|
if !_.isEmpty(@hostname)
|
||||||
conf.Hostname = @hostname
|
conf.Hostname = @hostname
|
||||||
|
if !_.isEmpty(@storageOpt)
|
||||||
|
conf.HostConfig.StorageOpt = @storageOpt
|
||||||
|
if @macAddress?
|
||||||
|
conf.MacAddress = @macAddress
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
# TODO: when we support network configuration properly, return endpointConfig: conf
|
# TODO: when we support network configuration properly, return endpointConfig: conf
|
||||||
@ -599,6 +675,7 @@ module.exports = class Service
|
|||||||
'cpuset'
|
'cpuset'
|
||||||
'domainname'
|
'domainname'
|
||||||
'oomScoreAdj'
|
'oomScoreAdj'
|
||||||
|
'oomKillDisable'
|
||||||
'healthcheck'
|
'healthcheck'
|
||||||
'stopSignal'
|
'stopSignal'
|
||||||
'stopGracePeriod'
|
'stopGracePeriod'
|
||||||
@ -606,6 +683,14 @@ module.exports = class Service
|
|||||||
'readOnly'
|
'readOnly'
|
||||||
'sysctls'
|
'sysctls'
|
||||||
'hostname'
|
'hostname'
|
||||||
|
'cgroupParent'
|
||||||
|
'pid'
|
||||||
|
'pidsLimit'
|
||||||
|
'storageOpt'
|
||||||
|
'usernsMode'
|
||||||
|
'ipc'
|
||||||
|
'macAddress'
|
||||||
|
'user'
|
||||||
]
|
]
|
||||||
arraysToCompare = [
|
arraysToCompare = [
|
||||||
'volumes'
|
'volumes'
|
||||||
@ -618,6 +703,8 @@ module.exports = class Service
|
|||||||
'tmpfs'
|
'tmpfs'
|
||||||
'extraHosts'
|
'extraHosts'
|
||||||
'ulimitsArray'
|
'ulimitsArray'
|
||||||
|
'groupAdd'
|
||||||
|
'securityOpt'
|
||||||
]
|
]
|
||||||
isEq = _.isEqual(_.pick(this, propertiesToCompare), _.pick(otherService, propertiesToCompare)) and
|
isEq = _.isEqual(_.pick(this, propertiesToCompare), _.pick(otherService, propertiesToCompare)) and
|
||||||
_.isEqual(_.omit(@environment, [ 'RESIN_DEVICE_NAME_AT_INIT' ]), _.omit(otherService.environment, [ 'RESIN_DEVICE_NAME_AT_INIT' ])) and
|
_.isEqual(_.omit(@environment, [ 'RESIN_DEVICE_NAME_AT_INIT' ]), _.omit(otherService.environment, [ 'RESIN_DEVICE_NAME_AT_INIT' ])) and
|
||||||
|
Loading…
Reference in New Issue
Block a user