fix: Correctly compare and generate network membership aliases

Before this change, service name resolution would only occur in the
default network. This was because we were not explicitly adding aliases
of the service names to the aliases fields.

We also fix the comparison, which would do funny things based on
container IDs, which was correct but unnecessary.

Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
This commit is contained in:
Cameron Diver 2019-03-13 12:28:42 +00:00
parent f1c6dd46c3
commit b3192679c7
No known key found for this signature in database
GPG Key ID: 49690ED87032539F
3 changed files with 23 additions and 20 deletions

View File

@ -20,6 +20,7 @@ import {
import * as LogTypes from '../lib/log-types';
import { checkInt, isValidDeviceName } from '../lib/validation';
import { Service } from './service';
import { serviceNetworksToDockerNetworks } from './utils';
interface ServiceConstructOpts {
docker: Docker;
@ -266,7 +267,9 @@ export class ServiceManager extends (EventEmitter as {
}
const conf = service.toDockerContainer({ deviceName });
const nets = service.extraNetworksToJoin();
const nets = serviceNetworksToDockerNetworks(
service.extraNetworksToJoin(),
);
this.logger.logSystemEvent(LogTypes.installService, { service });
this.reportNewStatus(mockContainerId, service, 'Installing');
@ -275,7 +278,7 @@ export class ServiceManager extends (EventEmitter as {
service.containerId = container.id;
await Promise.all(
_.map(nets, (endpointConfig, name) =>
_.map((nets || {}).EndpointsConfig, (endpointConfig, name) =>
this.docker.getNetwork(name).connect({
Container: container.id,
EndpointConfig: endpointConfig,

View File

@ -122,6 +122,17 @@ export class Service {
}
// Prefix the network entries with the app id
networks = _.mapKeys(networks, (_v, k) => `${service.appId}_${k}`);
// Ensure that we add an alias of the service name
networks = _.mapValues(networks, v => {
if (v.aliases == null) {
v.aliases = [];
}
const serviceName: string = service.serviceName || '';
if (!_.includes(v.aliases, serviceName)) {
v.aliases.push(serviceName);
}
return v;
});
delete config.networks;
// Check for unsupported networkMode entries
@ -837,24 +848,11 @@ export class Service {
const currentAliases = _.filter(current.aliases, (alias: string) => {
return !_.startsWith(this.containerId!, alias);
});
const targetAliases = _.filter(current.aliases, (alias: string) => {
return !_.startsWith(this.containerId!, alias);
});
const targetAliases = target.aliases || [];
// Docker adds container ids to the alias list, directly after
// the service name, to detect this, check for both target having
// exactly half of the amount of entries as the current, and check
// that every second entry (starting from 0) is equal
if (currentAliases.length === targetAliases.length * 2) {
sameNetwork = _(currentAliases)
.filter((_v, k) => k % 2 === 0)
.isEqual(targetAliases);
} else {
// Otherwise compare them literally
sameNetwork = _.isEmpty(
_.xorWith(currentAliases, targetAliases, _.isEqual),
);
}
sameNetwork = _.isEmpty(
_.xorWith(currentAliases, targetAliases, _.isEqual),
);
}
}
if (target.ipv4Address != null) {

View File

@ -311,7 +311,9 @@ describe 'compose/service', ->
IPAMConfig: {
IPv4Address: '1.2.3.4'
},
Aliases: []
Aliases: [
'test'
]
}
}
})