Skip to content

Death Note :)#545

Merged
bsideup merged 9 commits into
masterfrom
death_note
Jan 27, 2018
Merged

Death Note :)#545
bsideup merged 9 commits into
masterfrom
death_note

Conversation

@bsideup
Copy link
Copy Markdown
Member

@bsideup bsideup commented Jan 15, 2018

Start a helper "Ryuk" container to make sure that we clean the containers after the execution even if the JVM was "kill -9"ed.

Based on https://github.com/bsideup/moby-ryuk and uses my public automated build for now:
https://hub.docker.com/r/bsideup/moby-ryuk/builds/bhcmbnqyhtnvcqg8ijvnh6n/

Will move to TC org & hub once we get a name

}
}

private void checkExposedPort(String hostIpAddress, DockerClient dockerClient, String id) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this check is not needed anymore, Ryuk demands a connectivity hence implicitly checks for the exposed port

log.info("Docker host IP address is {}", hostIpAddress);
DockerClient client = strategy.getClient();

if (!preconditionsChecked) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

had to change the name because it's not just preconditionsChecked anymore


// Use a unique identifier so that containers created for this compose environment can be identified
this.identifier = identifier;
project = identifier + Base58.randomString(6).toLowerCase();
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

without this change, compose.start(); compose.stop(); compose.start() would use the same randomIndentifier and might lead to some unpredictable side effects

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to move this code into the starting() method and remove the duplicate line (245) in finished()? Else we should wrap this line in a private method generateProjectName(String identifier)

}

private void registerContainersForShutdown() {
// Ensure that all service containers that were launched by compose will be killed at shutdown
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😍

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome 🗡️

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✂️ 😄


String ryukContainerId = client.createContainerCmd(ryukImage)
.withHostConfig(new HostConfig() {
@JsonProperty("AutoRemove")
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docker-java is behind, but this flag will remove the container if it stops (and it will stop when the cleanup happen)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, I was wondering what would remove this container 😄

@bsideup bsideup added this to the 1.6.0 milestone Jan 15, 2018
// Cached client configuration
private DockerClientProviderStrategy strategy;
private boolean preconditionsChecked = false;
private boolean initialized = false;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This boolean is of course false by default, or did you want to make it explicitly?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just renamed the variable :) But yes, explicit false helps to understand the logic

DockerClient client = strategy.getClient();

if (!preconditionsChecked) {
if (!initialized) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can encapsulate the following block like:

if (!initialized) {
  initialize();
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not do it in this PR.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem, but why not? 😉

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it's out of scope, and if somebody submits another PR where they change DockerClientFactory, but we didn't merge "Death Note" PR yet, it will create more conflicts.
I'm happy to extract method as a follow up, or before, or in parallel, but don't want to increase the scope of this change :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also think about reverts in case we discover some major bug :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes okay, makes sense 🙂

}

private void registerContainersForShutdown() {
// Ensure that all service containers that were launched by compose will be killed at shutdown
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome 🗡️


// Use a unique identifier so that containers created for this compose environment can be identified
this.identifier = identifier;
project = identifier + Base58.randomString(6).toLowerCase();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to move this code into the starting() method and remove the duplicate line (245) in finished()? Else we should wrap this line in a private method generateProjectName(String identifier)

}

createCommand.withLabels(Collections.singletonMap("org.testcontainers", "true"));
createContainerCmdModifiers.forEach(hook -> hook.accept(createCommand));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you have to do this now?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just moved the call from another place because we must add our labels after user sets his own


private static final Logger LOGGER = LoggerFactory.getLogger(ResourceReaper.class);

private static final List<List<Map.Entry<String, String>>> REGISTERED_FILTERS = new ArrayList<>();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicking, but I would not write this variable in capital letters, since the collection is mutable.

.withName("tc-ryuk-" + DockerClientFactory.SESSION_ID)
.withLabels(Collections.singletonMap(DockerClientFactory.TESTCONTAINERS_LABEL, "true"))
.withBinds(
new Bind("/var/run/docker.sock", new Volume("/var/run/docker.sock")),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for Docker for Windows, we need to add a leading slash here 😞 (that's what we also did in ContainerisedDockerCompose). Also see this SO answer (without real explanation) 😆 https://stackoverflow.com/questions/36765138/bind-to-docker-socket-on-windows/41005007#41005007

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird, but nice catch :) Will do

}

/**
* Register a container to be cleaned up, either on explicit call to stopAndRemoveContainer, or at JVM shutdown.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we remove this method now?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's public. We can not remove it now

Copy link
Copy Markdown
Member

@rnorth rnorth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Just a few queries/requests then I think it's good to merge!


MountableFile mountableFile = MountableFile.forClasspathResource(this.getClass().getName().replace(".", "/") + ".class");
String ryukContainerId = ResourceReaper.start(hostIpAddress, client);
log.info("Ryuk started");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super-trivial, but please could we change the message a bit for people who don't/won't grok the name? Something like "Ryuk started - will monitor and terminate Testcontainers containers on JVM exit" perhaps?

It's a bit wordy, but less mysterious.

}

private void registerContainersForShutdown() {
// Ensure that all service containers that were launched by compose will be killed at shutdown
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✂️ 😄

})
.withExposedPorts(new ExposedPort(8080))
.withPublishAllPorts(true)
.withName("tc-ryuk-" + DockerClientFactory.SESSION_ID)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to name the container 😄
Please could we just expand tc to testcontainers though? It's just a thing that people can google more easily if they're wondering what this container is.


String ryukContainerId = client.createContainerCmd(ryukImage)
.withHostConfig(new HostConfig() {
@JsonProperty("AutoRemove")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, I was wondering what would remove this container 😄

}
}
},
"tc-ryuk"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, please could you expand tc to testcontainers for googlability?

@bsideup
Copy link
Copy Markdown
Member Author

bsideup commented Jan 22, 2018

@rnorth done 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants