Skip to content

Commit

Permalink
Allow configuration of files that are copied for docker compose (test…
Browse files Browse the repository at this point in the history
…containers#8847)

This commit adds support for a `withFileCopyInclusions` method on `ComposeContainer` and `DockerComposeContainer`. It allows to specify what files or directories should be copied, instead of just copying all files. If not used, the current behaviour is preserved.
  • Loading branch information
wimdeblauwe committed Jul 4, 2024
1 parent 7989b20 commit b1d39fd
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ public class ComposeContainer extends FailureDetectingExternalResource implement

private String project;

private List<String> fileCopyInclusions = new ArrayList<>();

public ComposeContainer(File... composeFiles) {
this(Arrays.asList(composeFiles));
}
Expand Down Expand Up @@ -134,7 +136,8 @@ public void start() {
this.options,
this.services,
this.scalingPreferences,
this.env
this.env,
this.fileCopyInclusions
);
this.composeDelegate.startAmbassadorContainer();
this.composeDelegate.waitUntilServiceStarted(this.tailChildContainers);
Expand Down Expand Up @@ -165,7 +168,7 @@ public void stop() {
if (removeImages != null) {
cmd += " --rmi " + removeImages.dockerRemoveImagesType();
}
this.composeDelegate.runWithCompose(this.localCompose, cmd, this.env);
this.composeDelegate.runWithCompose(this.localCompose, cmd, this.env, this.fileCopyInclusions);
} finally {
this.project = this.composeDelegate.randomProjectId();
}
Expand Down Expand Up @@ -352,6 +355,11 @@ public ComposeContainer withStartupTimeout(Duration startupTimeout) {
return this;
}

public ComposeContainer withFileCopyInclusions(String... fileCopyInclusions) {
this.fileCopyInclusions = Arrays.asList(fileCopyInclusions);
return this;
}

public Optional<ContainerState> getContainerByServiceName(String serviceName) {
return this.composeDelegate.getContainerByServiceName(serviceName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ void createServices(
final Set<String> options,
final List<String> services,
final Map<String, Integer> scalingPreferences,
Map<String, String> env
Map<String, String> env,
List<String> fileCopyInclusions
) {
// services that have been explicitly requested to be started. If empty, all services should be started.
final String serviceNameArgs = Stream
Expand Down Expand Up @@ -160,7 +161,7 @@ void createServices(
}

// Run the docker compose container, which starts up the services
runWithCompose(localCompose, command, env);
runWithCompose(localCompose, command, env, fileCopyInclusions);
}

private String getUpCommand(String options) {
Expand Down Expand Up @@ -237,18 +238,18 @@ private String getServiceNameFromContainer(com.github.dockerjava.api.model.Conta
}

public void runWithCompose(boolean localCompose, String cmd) {
runWithCompose(localCompose, cmd, Collections.emptyMap());
runWithCompose(localCompose, cmd, Collections.emptyMap(), Collections.emptyList());
}

public void runWithCompose(boolean localCompose, String cmd, Map<String, String> env) {
public void runWithCompose(boolean localCompose, String cmd, Map<String, String> env, List<String> fileCopyInclusions) {
Preconditions.checkNotNull(composeFiles);
Preconditions.checkArgument(!composeFiles.isEmpty(), "No docker compose file have been provided");

final DockerCompose dockerCompose;
if (localCompose) {
dockerCompose = new LocalDockerCompose(this.executable, composeFiles, project);
} else {
dockerCompose = new ContainerisedDockerCompose(this.defaultImageName, composeFiles, project);
dockerCompose = new ContainerisedDockerCompose(this.defaultImageName, composeFiles, project, fileCopyInclusions);
}

dockerCompose.withCommand(cmd).withEnv(env).invoke();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ContainerisedDockerCompose extends GenericContainer<ContainerisedDockerCom

public static final char UNIX_PATH_SEPARATOR = ':';

public ContainerisedDockerCompose(DockerImageName dockerImageName, List<File> composeFiles, String identifier) {
public ContainerisedDockerCompose(DockerImageName dockerImageName, List<File> composeFiles, String identifier, List<String> fileCopyInclusions) {
super(dockerImageName);
addEnv(ENV_PROJECT_NAME, identifier);

Expand All @@ -43,7 +43,19 @@ public ContainerisedDockerCompose(DockerImageName dockerImageName, List<File> co
final String composeFileEnvVariableValue = Joiner.on(UNIX_PATH_SEPARATOR).join(absoluteDockerComposeFiles); // we always need the UNIX path separator
logger().debug("Set env COMPOSE_FILE={}", composeFileEnvVariableValue);
addEnv(ENV_COMPOSE_FILE, composeFileEnvVariableValue);
withCopyFileToContainer(MountableFile.forHostPath(pwd), containerPwd);
if (fileCopyInclusions.isEmpty()) {
logger().info("Copying all files in {} into the container", pwd);
withCopyFileToContainer(MountableFile.forHostPath(pwd), containerPwd);
} else {
// Always copy the compose file itself
logger().info("Copying docker compose file: {}", dockerComposeBaseFile.getAbsolutePath());
withCopyFileToContainer(MountableFile.forHostPath(dockerComposeBaseFile.getAbsolutePath()), convertToUnixFilesystemPath(dockerComposeBaseFile.getAbsolutePath()));
for (String pathToCopy : fileCopyInclusions) {
String hostPath = pwd + "/" + pathToCopy;
logger().info("Copying inclusion file: {}", hostPath);
withCopyFileToContainer(MountableFile.forHostPath(hostPath), convertToUnixFilesystemPath(hostPath));
}
}

// Ensure that compose can access docker. Since the container is assumed to be running on the same machine
// as the docker daemon, just mapping the docker control socket is OK.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public class DockerComposeContainer<SELF extends DockerComposeContainer<SELF>>

private String project;

private List<String> fileCopyInclusions = new ArrayList<>();

@Deprecated
public DockerComposeContainer(File composeFile, String identifier) {
this(identifier, composeFile);
Expand Down Expand Up @@ -140,8 +142,9 @@ public void start() {
this.options,
this.services,
this.scalingPreferences,
this.env
);
this.env,
this.fileCopyInclusions
);
this.composeDelegate.startAmbassadorContainer();
this.composeDelegate.waitUntilServiceStarted(this.tailChildContainers);
}
Expand Down Expand Up @@ -172,7 +175,7 @@ public void stop() {
if (removeImages != null) {
cmd += " --rmi " + removeImages.dockerRemoveImagesType();
}
this.composeDelegate.runWithCompose(this.localCompose, cmd, this.env);
this.composeDelegate.runWithCompose(this.localCompose, cmd, this.env, this.fileCopyInclusions);
} finally {
this.project = this.composeDelegate.randomProjectId();
}
Expand Down Expand Up @@ -355,6 +358,12 @@ public SELF withStartupTimeout(Duration startupTimeout) {
return self();
}

public SELF withFileCopyInclusions(String... fileCopyInclusions) {
this.fileCopyInclusions = Arrays.asList(fileCopyInclusions);
return self();
}


public Optional<ContainerState> getContainerByServiceName(String serviceName) {
return this.composeDelegate.getContainerByServiceName(serviceName);
}
Expand Down

0 comments on commit b1d39fd

Please sign in to comment.