Skip to content

Commit

Permalink
#14 make SakuliContainerStrategy "docker-in-docker" ready & small ref…
Browse files Browse the repository at this point in the history
…actoring
  • Loading branch information
Tobias Schneck committed Feb 23, 2018
1 parent cca0323 commit 20f13c1
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@
@Configuration
public class ApplicationConfig {

private static final String SAKULI_UI_PREFIX = "sakuli.ui.";
public static final String ROOT_DIRECTORY = SAKULI_UI_PREFIX + "root.directory";
public static final String PROJECT_DEFAULT = SAKULI_UI_PREFIX + "testSuite.default";
private static final String SAKULI_UI_ENV_PREFIX = "SAKULI_UI_";
public static final String ROOT_DIRECTORY_ENV = SAKULI_UI_ENV_PREFIX + "ROOT_DIRECTORY";
public static final String PROJECT_DEFAULT_ENV = SAKULI_UI_ENV_PREFIX + "PROJECT_DEFAULT";
public static final String ROOT_DIRECTORY = "sakuli.ui.root.directory";
public static final String PROJECT_DEFAULT = "sakuli.ui.testSuite.default";
public static final String ROOT_DIRECTORY_ENV = "SAKULI_UI_ROOT_DIRECTORY";
public static final String PROJECT_DEFAULT_ENV = "SAKULI_UI_PROJECT_DEFAULT";
public static final String DOCKER_CONTAINER_SAKULI_UI_USER = "SAKULI_UI_DOCKER_USER_ID";

@Bean(name = "rootDirectory")
public static String getRootDirectory() {
Expand All @@ -33,10 +32,10 @@ public static String getRootDirectory() {
@Bean(name = "defaultProject")
@Deprecated
public static String getDefaultProject() {
if(System.getProperty(PROJECT_DEFAULT) != null) {
if (System.getProperty(PROJECT_DEFAULT) != null) {
return System.getProperty(PROJECT_DEFAULT);
}
if(System.getenv(PROJECT_DEFAULT_ENV) != null) {
if (System.getenv(PROJECT_DEFAULT_ENV) != null) {
return System.getenv(PROJECT_DEFAULT_ENV);
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateContainerCmd;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.InspectContainerResponse;
import com.github.dockerjava.api.model.*;
Expand Down Expand Up @@ -35,14 +36,14 @@
import java.util.stream.Collectors;

import static com.github.dockerjava.api.model.Ports.Binding.bindPort;
import static org.sweetest.platform.server.ApplicationConfig.DOCKER_CONTAINER_SAKULI_UI_USER;

@Service
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.INTERFACES)
public class SakuliContainerStrategy extends AbstractTestExecutionStrategy<SakuliExecutionConfiguration> {

private static final Logger log = LoggerFactory.getLogger(SakuliContainerStrategy.class);
private static final String INTERNAL_READY_TO_RUN = "internal.ready-to-run";

@Value("${docker.userid:1000}")
private String dockerUserId;

Expand All @@ -53,8 +54,6 @@ public class SakuliContainerStrategy extends AbstractTestExecutionStrategy<Sakul
@Qualifier("rootDirectory")
private String rootDirectory;

private String mountPath;
private Volume volume;
private ExposedPort vncPort;
private ExposedPort vncWebPort;
private Ports ports;
Expand All @@ -64,7 +63,7 @@ public class SakuliContainerStrategy extends AbstractTestExecutionStrategy<Sakul

private SakuliEventResultCallback eventsResultCallback;

private CreateContainerResponse container;
private CreateContainerResponse runningContainer;
private String executionId;
private String containerToRunWithoutTag;
private String containerToRunWithTag;
Expand All @@ -77,24 +76,22 @@ public TestRunInfo execute(Observer<TestExecutionEvent> testExecutionEventObserv
subject.subscribe(testExecutionEventObserver);
subject.subscribe(e -> {
if (e.equals(readyToRun)) {
createContainer();
startContainer();
runningContainer = createContainer();
startContainer(runningContainer);
Info i = dockerClient.infoCmd().exec();
InspectContainerResponse response = dockerClient.inspectContainerCmd(container.getId())
InspectContainerResponse response = dockerClient.inspectContainerCmd(runningContainer.getId())
.exec();
log.info(
ReflectionToStringBuilder.toString(response, ToStringStyle.MULTI_LINE_STYLE)
+ ReflectionToStringBuilder.toString(i, ToStringStyle.MULTI_LINE_STYLE)
+ ReflectionToStringBuilder.toString(i, ToStringStyle.MULTI_LINE_STYLE)
);
attachToContainer();
attachToContainer(runningContainer);
}
//TODO show TestExecutionErrorEvent on UI
});
executionId = UUID.randomUUID().toString();
eventsResultCallback = new SakuliEventResultCallback(executionId, subject, dockerClient);
readyToRun = new TestExecutionEvent(INTERNAL_READY_TO_RUN, "", executionId);
mountPath = ("/" + getWorkspace()).replace("//", "/");
volume = new Volume(mountPath);
vncPort = ExposedPort.tcp(5901);
vncWebPort = ExposedPort.tcp(6901);
ports = new Ports();
Expand Down Expand Up @@ -132,19 +129,23 @@ public TestRunInfo execute(Observer<TestExecutionEvent> testExecutionEventObserv
}

public void stop() {
log.info("Will stop containers " + container.getId());
try {
if(callback != null) {
callback.close();
if (runningContainer != null && runningContainer.getId() != null) {
log.info("Will stop containers " + runningContainer.getId());
try {
if (callback != null) {
callback.close();
}
dockerClient
.killContainerCmd(runningContainer.getId())
.withSignal("9")
.exec();
runningContainer = null;
} catch (Exception e) {
e.printStackTrace();
next(new TestExecutionErrorEvent("Cannot stop containers " + runningContainer.getId(), executionId, e));
}
dockerClient
.killContainerCmd(container.getId())
.withSignal("9")
.exec();

} catch (Exception e) {
e.printStackTrace();
next(new TestExecutionErrorEvent("Cannot stop containers " + container.getId(), executionId, e));
} else {
next(new TestExecutionLogEvent("no-container-id", "Cannot stop container: no container is started!"));
}
}

Expand Down Expand Up @@ -184,7 +185,7 @@ public void onComplete() {
});
}

private void attachToContainer() {
private void attachToContainer(CreateContainerResponse container) {
callback = dockerClient
.logContainerCmd(container.getId())
.withStdOut(true)
Expand All @@ -205,7 +206,7 @@ public void onNext(Frame item) {

}

private void startContainer() {
private void startContainer(CreateContainerResponse container) {
dockerClient.eventsCmd().exec(eventsResultCallback);
subject.next(new TestExecutionStartEvent(executionId));
dockerClient.startContainerCmd(container.getId())
Expand All @@ -217,18 +218,29 @@ private void startContainer() {
});
}

private void createContainer() {
container = dockerClient
private CreateContainerResponse createContainer() {
final String testSuitePath = Paths.get(rootDirectory, testSuite.getRoot()).toString();
final CreateContainerCmd basicContainerCmd = dockerClient
.createContainerCmd(containerToRunWithTag)
.withCmd("run", "/" + testSuite.getRoot())
.withExposedPorts(vncPort, vncWebPort)
.withEnv(getEnvFromConfig())
.withPortBindings(ports)
.withUser(dockerUserId)
.withPublishAllPorts(true)
.withVolumes(volume)
.withBinds(new Bind(Paths.get(rootDirectory, mountPath).toString(), volume))
.exec();
.withCmd("run", testSuitePath);

if (System.getenv().containsKey(DOCKER_CONTAINER_SAKULI_UI_USER)) {
//Sakuli UI is running in container itself -> start "docker-in-docker" container
basicContainerCmd
.withUser(System.getenv(DOCKER_CONTAINER_SAKULI_UI_USER))
//ID of docker-ui-container is set on HOSTNAME
.withVolumesFrom(new VolumesFrom(System.getenv("HOSTNAME"), AccessMode.rw));
} else {
final Volume volume = new Volume(testSuitePath);
basicContainerCmd
.withVolumes(volume)
.withBinds(new Bind(testSuitePath, volume));
}
return basicContainerCmd.exec();
}

private List<String> getEnvFromConfig() {
Expand Down

0 comments on commit 20f13c1

Please sign in to comment.