mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2024-12-22 06:57:49 +00:00
Improve net alias comparison to prevent unwanted restarts
Network aliases are now compared checking that the target state is a subset of the current state. This will prevent service restarts due to additional aliases created by docker in the container. Closes: #2134 Change-type: patch
This commit is contained in:
parent
cb98133717
commit
27f0d2e655
@ -1074,20 +1074,17 @@ export class Service {
|
||||
if (current.aliases == null) {
|
||||
sameNetwork = false;
|
||||
} else {
|
||||
// Take out the container id from both aliases, as it *will* be present
|
||||
// in a currently running container, and can also be present in the target
|
||||
// for example when doing a start-service
|
||||
// Also sort the aliases, so we can do a simple comparison
|
||||
const [currentAliases, targetAliases] = [
|
||||
current.aliases,
|
||||
target.aliases,
|
||||
].map((aliases) =>
|
||||
_.sortBy(
|
||||
aliases.filter((a) => !_.startsWith(this.containerId || '', a)),
|
||||
),
|
||||
);
|
||||
];
|
||||
|
||||
sameNetwork = _.isEqual(currentAliases, targetAliases);
|
||||
// Docker may add keep old container ids as aliases for a specific service after
|
||||
// restarts, this means that the target aliases really needs to be a subset of the
|
||||
// current aliases to prevent service restarts when re-applying the same target state
|
||||
sameNetwork =
|
||||
_.intersection(currentAliases, targetAliases).length ===
|
||||
targetAliases.length;
|
||||
}
|
||||
}
|
||||
if (target.ipv4Address != null) {
|
||||
|
@ -574,6 +574,80 @@ describe('compose/service: unit tests', () => {
|
||||
expect(svc1.isEqualConfig(svc2, {})).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
it('should accept that target network aliases are a subset of current network aliases', async () => {
|
||||
const svc1 = await Service.fromComposeObject(
|
||||
{
|
||||
appId: 1,
|
||||
serviceId: 1,
|
||||
serviceName: 'test',
|
||||
composition: {
|
||||
networks: {
|
||||
test: {
|
||||
aliases: ['hello', 'world'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ appName: 'test' } as any,
|
||||
);
|
||||
const svc2 = await Service.fromComposeObject(
|
||||
{
|
||||
appId: 1,
|
||||
serviceId: 1,
|
||||
serviceName: 'test',
|
||||
composition: {
|
||||
networks: {
|
||||
test: {
|
||||
aliases: ['hello', 'sweet', 'world'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ appName: 'test' } as any,
|
||||
);
|
||||
|
||||
// All aliases in target service (svc1) are contained in service 2
|
||||
expect(svc2.isEqualConfig(svc1, {})).to.be.true;
|
||||
// But the opposite is not true
|
||||
expect(svc1.isEqualConfig(svc2, {})).to.be.false;
|
||||
});
|
||||
|
||||
it('should accept equal lists of network aliases', async () => {
|
||||
const svc1 = await Service.fromComposeObject(
|
||||
{
|
||||
appId: 1,
|
||||
serviceId: 1,
|
||||
serviceName: 'test',
|
||||
composition: {
|
||||
networks: {
|
||||
test: {
|
||||
aliases: ['hello', 'world'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ appName: 'test' } as any,
|
||||
);
|
||||
const svc2 = await Service.fromComposeObject(
|
||||
{
|
||||
appId: 1,
|
||||
serviceId: 1,
|
||||
serviceName: 'test',
|
||||
composition: {
|
||||
networks: {
|
||||
test: {
|
||||
aliases: ['hello', 'world'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ appName: 'test' } as any,
|
||||
);
|
||||
|
||||
expect(svc1.isEqualConfig(svc2, {})).to.be.true;
|
||||
expect(svc2.isEqualConfig(svc1, {})).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('Feature labels', () => {
|
||||
|
Loading…
Reference in New Issue
Block a user