Only start a container once in its lifetime

This will ensure the restart policy specified is not violated

Change-type: patch
Closes: #1668
Signed-off-by: 20k-ultra <3946250+20k-ultra@users.noreply.github.com>
This commit is contained in:
20k-ultra 2022-04-12 02:05:56 -04:00
parent 9aa50eea8a
commit ca9945bdfb
3 changed files with 14 additions and 21 deletions

View File

@ -336,15 +336,13 @@ export class App {
return false; return false;
} }
// Check if we previously remember starting it // Only start a Service if we have never started it before and the service matches target!
if ( // This is so the engine can handle the restart policy configured for the container.
applicationManager.containerStarted[serviceCurrent.containerId!] != null return (
) { (serviceCurrent.status === 'Installing' ||
return false; serviceCurrent.status === 'Installed') &&
} isEqualExceptForRunningState(serviceCurrent, serviceTarget)
);
// If the config otherwise matches, then we should be running
return isEqualExceptForRunningState(serviceCurrent, serviceTarget);
}; };
/** /**

View File

@ -951,7 +951,7 @@ describe('compose/app', () => {
applicationManager.containerStarted = {}; applicationManager.containerStarted = {};
}); });
it('should create a start step when all that changes is a running state', async () => { it('should not create a start step when all that changes is a running state', async () => {
const contextWithImages = { const contextWithImages = {
...defaultContext, ...defaultContext,
...{ ...{
@ -972,13 +972,10 @@ describe('compose/app', () => {
isTarget: true, isTarget: true,
}); });
// now should see a 'start'
const steps = current.nextStepsForAppUpdate(contextWithImages, target); const steps = current.nextStepsForAppUpdate(contextWithImages, target);
const [startStep] = expectSteps('start', steps); // There should be no steps since the engine manages restart policy for stopped containers
expect(startStep) expect(steps.length).to.equal(0);
.to.have.property('target')
.that.deep.includes({ serviceName: 'main' });
}); });
it('should create a kill step when a service release has to be updated but the strategy is kill-then-download', async () => { it('should create a kill step when a service release has to be updated but the strategy is kill-then-download', async () => {

View File

@ -208,7 +208,7 @@ describe('compose/application-manager', () => {
// TODO: missing tests for getCurrentApps // TODO: missing tests for getCurrentApps
it('infers a start step when all that changes is a running state', async () => { it('should not infer a start step when all that changes is a running state', async () => {
const targetApps = createApps( const targetApps = createApps(
{ {
services: [await createService({ running: true, appId: 1 })], services: [await createService({ running: true, appId: 1 })],
@ -226,7 +226,7 @@ describe('compose/application-manager', () => {
networks: [DEFAULT_NETWORK], networks: [DEFAULT_NETWORK],
}); });
const [startStep] = await applicationManager.inferNextSteps( const steps = await applicationManager.inferNextSteps(
currentApps, currentApps,
targetApps, targetApps,
{ {
@ -236,10 +236,8 @@ describe('compose/application-manager', () => {
}, },
); );
expect(startStep).to.have.property('action').that.equals('start'); // There should be no steps since the engine manages restart policy for stopped containers
expect(startStep) expect(steps.length).to.equal(0);
.to.have.property('target')
.that.deep.includes({ serviceName: 'main' });
}); });
it('infers a kill step when a service has to be removed', async () => { it('infers a kill step when a service has to be removed', async () => {