mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2024-12-19 13:47:54 +00:00
Merge pull request #969 from balena-io/968-multiple-ports
Handle multiple host ports pointing to a single container port
This commit is contained in:
commit
84c03f89ba
@ -90,24 +90,25 @@ export class PortMap {
|
|||||||
public static fromDockerOpts(portBindings: PortBindings): PortMap[] {
|
public static fromDockerOpts(portBindings: PortBindings): PortMap[] {
|
||||||
// Create a list of portBindings, rather than the map (which we can't
|
// Create a list of portBindings, rather than the map (which we can't
|
||||||
// order)
|
// order)
|
||||||
const portMaps = _.map(portBindings, (hostObj, internalStr) => {
|
const portMaps = _.flatMap(portBindings, (hostObj, internalStr) => {
|
||||||
const match = internalStr.match(DOCKER_OPTS_PORTS_REGEX);
|
const match = internalStr.match(DOCKER_OPTS_PORTS_REGEX);
|
||||||
if (match == null) {
|
if (match == null) {
|
||||||
throw new Error(`Could not parse docker port output: ${internalStr}`);
|
throw new Error(`Could not parse docker port output: ${internalStr}`);
|
||||||
}
|
}
|
||||||
const internal = parseInt(match[1], 10);
|
const internal = parseInt(match[1], 10);
|
||||||
const external = parseInt(hostObj[0].HostPort, 10);
|
|
||||||
|
|
||||||
const host = hostObj[0].HostIp;
|
|
||||||
const proto = match[2] || 'tcp';
|
const proto = match[2] || 'tcp';
|
||||||
|
|
||||||
return new PortMap({
|
return _.map(hostObj, ({ HostIp, HostPort }) => {
|
||||||
internalStart: internal,
|
const external = parseInt(HostPort, 10);
|
||||||
internalEnd: internal,
|
const host = HostIp;
|
||||||
externalStart: external,
|
return new PortMap({
|
||||||
externalEnd: external,
|
internalStart: internal,
|
||||||
protocol: proto,
|
internalEnd: internal,
|
||||||
host,
|
externalStart: external,
|
||||||
|
externalEnd: external,
|
||||||
|
protocol: proto,
|
||||||
|
host,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -775,7 +775,12 @@ export class Service {
|
|||||||
_.each(this.config.portMaps, pmap => {
|
_.each(this.config.portMaps, pmap => {
|
||||||
const { exposedPorts, portBindings } = pmap.toDockerOpts();
|
const { exposedPorts, portBindings } = pmap.toDockerOpts();
|
||||||
_.merge(exposed, exposedPorts);
|
_.merge(exposed, exposedPorts);
|
||||||
_.merge(ports, portBindings);
|
_.mergeWith(ports, portBindings, (destVal, srcVal) => {
|
||||||
|
if (destVal == null) {
|
||||||
|
return srcVal;
|
||||||
|
}
|
||||||
|
return destVal.concat(srcVal);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// We also want to merge the compose and image exposedPorts
|
// We also want to merge the compose and image exposedPorts
|
||||||
|
@ -198,13 +198,16 @@ describe 'deviceState', ->
|
|||||||
prepare()
|
prepare()
|
||||||
@db = new DB()
|
@db = new DB()
|
||||||
@config = new Config({ @db })
|
@config = new Config({ @db })
|
||||||
|
@logger = {
|
||||||
|
clearOutOfDateDBLogs: ->
|
||||||
|
}
|
||||||
eventTracker = {
|
eventTracker = {
|
||||||
track: console.log
|
track: console.log
|
||||||
}
|
}
|
||||||
stub(Service, 'extendEnvVars').callsFake (env) ->
|
stub(Service, 'extendEnvVars').callsFake (env) ->
|
||||||
env['ADDITIONAL_ENV_VAR'] = 'foo'
|
env['ADDITIONAL_ENV_VAR'] = 'foo'
|
||||||
return env
|
return env
|
||||||
@deviceState = new DeviceState({ @db, @config, eventTracker })
|
@deviceState = new DeviceState({ @db, @config, eventTracker, @logger })
|
||||||
stub(@deviceState.applications.docker, 'getNetworkGateway').returns(Promise.resolve('172.17.0.1'))
|
stub(@deviceState.applications.docker, 'getNetworkGateway').returns(Promise.resolve('172.17.0.1'))
|
||||||
stub(@deviceState.applications.images, 'inspectByName').callsFake ->
|
stub(@deviceState.applications.images, 'inspectByName').callsFake ->
|
||||||
Promise.try ->
|
Promise.try ->
|
||||||
|
@ -20,7 +20,10 @@ initModels = (filename) ->
|
|||||||
track: stub().callsFake (ev, props) ->
|
track: stub().callsFake (ev, props) ->
|
||||||
console.log(ev, props)
|
console.log(ev, props)
|
||||||
}
|
}
|
||||||
@deviceState = new DeviceState({ @db, @config, @eventTracker })
|
@logger = {
|
||||||
|
clearOutOfDateDBLogs: ->
|
||||||
|
}
|
||||||
|
@deviceState = new DeviceState({ @db, @config, @eventTracker, @logger })
|
||||||
@apiBinder = new APIBinder({ @db, @config, @eventTracker, @deviceState })
|
@apiBinder = new APIBinder({ @db, @config, @eventTracker, @deviceState })
|
||||||
@db.init()
|
@db.init()
|
||||||
.then =>
|
.then =>
|
||||||
|
@ -123,7 +123,10 @@ describe 'ApplicationManager', ->
|
|||||||
eventTracker = {
|
eventTracker = {
|
||||||
track: console.log
|
track: console.log
|
||||||
}
|
}
|
||||||
@deviceState = new DeviceState({ @db, @config, eventTracker })
|
@logger = {
|
||||||
|
clearOutOfDateDBLogs: ->
|
||||||
|
}
|
||||||
|
@deviceState = new DeviceState({ @db, @config, eventTracker, @logger })
|
||||||
@applications = @deviceState.applications
|
@applications = @deviceState.applications
|
||||||
stub(@applications.images, 'inspectByName').callsFake (imageName) ->
|
stub(@applications.images, 'inspectByName').callsFake (imageName) ->
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
|
@ -243,6 +243,28 @@ describe 'Ports', ->
|
|||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
|
||||||
|
it 'should correctly detect multiple hosts ports on an internal port', ->
|
||||||
|
expect(PortMap.fromDockerOpts({
|
||||||
|
'100/tcp': [{ HostIp: '123', HostPort: 200 }, { HostIp: '123', HostPort: 201 }]
|
||||||
|
})).to.deep.equal([
|
||||||
|
new PortMap({
|
||||||
|
internalStart: 100,
|
||||||
|
internalEnd: 100,
|
||||||
|
externalStart: 200,
|
||||||
|
externalEnd: 200,
|
||||||
|
protocol: 'tcp',
|
||||||
|
host: '123'
|
||||||
|
})
|
||||||
|
new PortMap({
|
||||||
|
internalStart: 100,
|
||||||
|
internalEnd: 100,
|
||||||
|
externalStart: 201,
|
||||||
|
externalEnd: 201,
|
||||||
|
protocol: 'tcp',
|
||||||
|
host: '123'
|
||||||
|
})
|
||||||
|
])
|
||||||
|
|
||||||
describe 'Running container comparison', ->
|
describe 'Running container comparison', ->
|
||||||
it 'should not consider order when comparing current and target state', ->
|
it 'should not consider order when comparing current and target state', ->
|
||||||
portBindings = require('./data/ports/not-ascending/port-bindings.json')
|
portBindings = require('./data/ports/not-ascending/port-bindings.json')
|
||||||
|
Loading…
Reference in New Issue
Block a user