remove all left over containers with the same action label
diff --git a/src/invoker.js b/src/invoker.js
index 287a359..d1f1125 100644
--- a/src/invoker.js
+++ b/src/invoker.js
@@ -243,29 +243,29 @@
}
async checkExistingContainers() {
+ let containers = await this.docker.listContainers();
+ const fullActionName = this.getFullActionName();
+
+ // remove all left over containers with the same action name label
+ for (const container of containers) {
+ if (container.Labels[LABEL_ACTION_NAME] === fullActionName) {
+ log.warn(`Removing container from a previous wskdebug run for this action (${dockerUtils.getContainerName(container)}).`)
+ const oldContainer = await this.docker.getContainer(container.Id);
+ await oldContainer.remove({force: true});
+ }
+ }
+
// check if the debug port is already in use
if (await isPortReachable(this.debug.port)) {
-
- const containers = await this.docker.listContainers();
- const fullActionName = this.getFullActionName();
-
- // then check if there is a left over container from a previous run with that port
+ containers = await this.docker.listContainers();
+ // then check if it's another container with that port
for (const container of containers) {
for (const port of container.Ports) {
if (port.PublicPort === this.debug.port) {
// check if wskdebug container by looking at our label
if (container.Labels[LABEL_ACTION_NAME]) {
- if (container.Labels[LABEL_ACTION_NAME] === fullActionName) {
- // same action
- log.warn(`Replacing container from a previous wskdebug run for this action (${dockerUtils.getContainerName(container)}).`)
- const oldContainer = await this.docker.getContainer(container.Id);
- await oldContainer.remove({force: true});
- return;
-
- } else {
- // wskdebug of different action
- throw new Error(`Debug port ${this.debug.port} already in use by wskdebug for action ${container.Labels[LABEL_ACTION_NAME]}, cotainer ${dockerUtils.getContainerName(container)} (id: ${container.Id}).`);
- }
+ // wskdebug of different action
+ throw new Error(`Debug port ${this.debug.port} already in use by wskdebug for action ${container.Labels[LABEL_ACTION_NAME]}, cotainer ${dockerUtils.getContainerName(container)} (id: ${container.Id}).`);
} else {
// some non-wskdebug container
throw new Error(`Debug port ${this.debug.port} already in use by another docker container ${dockerUtils.getContainerName(container)} (id: ${container.Id}).`);
diff --git a/test/invoker.test.js b/test/invoker.test.js
index 591b1ba..201bfdc 100644
--- a/test/invoker.test.js
+++ b/test/invoker.test.js
@@ -23,6 +23,7 @@
const Docker = require('dockerode');
const assert = require("assert");
+const TEST_IMAGE = "adobeapiplatform/adobe-action-nodejs-v10:3.0.21";
const ACTION_NAME = "myaction";
const ACTION_METADATA = {
exec: {
@@ -42,7 +43,7 @@
runtimes: {
nodejs: [{
kind: "nodejs",
- image: "adobeapiplatform/adobe-action-nodejs-v10:3.0.21"
+ image: TEST_IMAGE
}]
}
}
@@ -96,4 +97,66 @@
}
}
}).timeout(30000);
+
+ it("should replace all previous container for the same action", async function() {
+ // preparation: start multiple "left over" containers
+ async function startContainer(port) {
+ const createContainerConfig = {
+ name: `wskdebug-invoker.test-${port}-${Date.now()}`,
+ Labels: {
+ "org.apache.wskdebug.action": "/namespace/myaction"
+ },
+ Image: TEST_IMAGE,
+ Cmd: [ 'sh', '-c', "node --expose-gc --inspect=0.0.0.0:9229 app.js" ],
+ Env: [],
+ Volumes: {},
+ ExposedPorts: {
+ "8080/tcp": {},
+ "9229/tcp": {}
+ },
+ HostConfig: {
+ AutoRemove: true,
+ PortBindings: {
+ "8080/tcp": [{ HostPort: `${port+100}` }],
+ "9229/tcp": [{ HostPort: `${port}` }]
+ },
+ Memory: 50*1000*1000,
+ Binds: []
+ }
+ };
+ const container = await docker.createContainer(createContainerConfig);
+ await container.start();
+ return container.id;
+ }
+
+ const previousContainerIds = [];
+ previousContainerIds.push(await startContainer(9701));
+ previousContainerIds.push(await startContainer(9702));
+ previousContainerIds.push(await startContainer(9703));
+
+ // start second container
+ const invoker = new OpenWhiskInvoker(ACTION_NAME, ACTION_METADATA, {}, WSK_PROPS, WSK);
+
+ let id;
+
+ try {
+ await invoker.prepare();
+ await invoker.startContainer(() => {});
+
+ id = invoker.container.id;
+
+ // verify it replaced the container
+ for (const previousContainerId of previousContainerIds) {
+ assert.ok(!await isContainerRunning(previousContainerId), `old container was not removed: ${previousContainerId}`);
+ }
+
+ } finally {
+ await invoker.stop();
+
+ if (id) {
+ // verify the new container is gone
+ assert.ok(!await isContainerRunning(id), "container was not removed after stop()");
+ }
+ }
+ }).timeout(30000);
});