下面列出了org.apache.maven.plugin.PluginParameterExpressionEvaluator#com.spotify.docker.client.exceptions.DockerException 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void killAndRemoveStartedContainer() {
// assure that we do not have multiple threads clearing the started container at once.
synchronized (clearStartedContainerLock) {
if (nonNull(startedContainer)) {
String containerId = startedContainer.id();
String shortId = left(containerId, SHORT_ID_LENGTH);
startedContainer = null;
try {
log.info("Attempting to kill and remove container '{}' for image '{}'", shortId, image);
dockerClient.killContainer(containerId);
dockerClient.removeContainer(containerId);
log.info("Successfully killed and removed container '{}' for image '{}'", shortId, image);
}
catch (DockerException | InterruptedException e) { // NOSONAR
log.error("Failed to kill and/or remove container '{}'", shortId, log.isDebugEnabled() ? e : null);
}
}
}
}
@Test
public void shouldErrorOutWhenFailedToPull() throws DockerException, InterruptedException {
final ArtifactStoreConfig storeConfig = new ArtifactStoreConfig("localhost:5000", "other", "admin", "admin123");
final HashMap<String, String> artifactMetadata = new HashMap<>();
artifactMetadata.put("image", "localhost:5000/alpine:v1");
artifactMetadata.put("digest", "foo");
final FetchArtifactRequest fetchArtifactRequest = new FetchArtifactRequest(storeConfig, artifactMetadata, new FetchArtifactConfig());
when(request.requestBody()).thenReturn(new Gson().toJson(fetchArtifactRequest));
doThrow(new RuntimeException("Some error")).when(dockerClient).pull("localhost:5000/alpine:v1", dockerProgressHandler);
final GoPluginApiResponse response = new FetchArtifactExecutor(request, consoleLogger, dockerProgressHandler, dockerClientFactory).execute();
assertThat(response.responseCode()).isEqualTo(500);
assertThat(response.responseBody()).isEqualTo("Failed pull docker image: java.lang.RuntimeException: Some error");
}
@Test
public void shouldPublishArtifactUsingBuildFile() throws IOException, DockerException, InterruptedException {
final ArtifactPlan artifactPlan = new ArtifactPlan("id", "storeId", "build.json");
final ArtifactStoreConfig storeConfig = new ArtifactStoreConfig("localhost:5000", "other", "admin", "admin123");
final ArtifactStore artifactStore = new ArtifactStore(artifactPlan.getId(), storeConfig);
final PublishArtifactRequest publishArtifactRequest = new PublishArtifactRequest(artifactStore, artifactPlan, agentWorkingDir.getAbsolutePath());
Path path = Paths.get(agentWorkingDir.getAbsolutePath(), "build.json");
Files.write(path, "{\"image\":\"localhost:5000/alpine\",\"tag\":\"3.6\"}".getBytes());
when(request.requestBody()).thenReturn(publishArtifactRequest.toJSON());
when(dockerProgressHandler.getDigest()).thenReturn("foo");
final GoPluginApiResponse response = new PublishArtifactExecutor(request, consoleLogger, dockerProgressHandler, dockerClientFactory).execute();
verify(dockerClient).push(eq("localhost:5000/alpine:3.6"), any(ProgressHandler.class));
assertThat(response.responseCode()).isEqualTo(200);
assertThat(response.responseBody()).isEqualTo("{\"metadata\":{\"image\":\"localhost:5000/alpine:3.6\",\"digest\":\"foo\"}}");
}
@Test
public void shouldPublishArtifactUsingImageAndTag() throws IOException, DockerException, InterruptedException {
final ArtifactPlan artifactPlan = new ArtifactPlan("id", "storeId", "alpine", Optional.of("3.6"));
final ArtifactStoreConfig storeConfig = new ArtifactStoreConfig("localhost:5000", "other", "admin", "admin123");
final ArtifactStore artifactStore = new ArtifactStore(artifactPlan.getId(), storeConfig);
final PublishArtifactRequest publishArtifactRequest = new PublishArtifactRequest(artifactStore, artifactPlan, agentWorkingDir.getAbsolutePath());
when(request.requestBody()).thenReturn(publishArtifactRequest.toJSON());
when(dockerProgressHandler.getDigest()).thenReturn("foo");
final GoPluginApiResponse response = new PublishArtifactExecutor(request, consoleLogger, dockerProgressHandler, dockerClientFactory).execute();
verify(dockerClient).push(eq("alpine:3.6"), any(ProgressHandler.class));
assertThat(response.responseCode()).isEqualTo(200);
assertThat(response.responseBody()).isEqualTo("{\"metadata\":{\"image\":\"alpine:3.6\",\"digest\":\"foo\"}}");
}
@Test
public void shouldAddErrorToPublishArtifactResponseWhenFailedToPublishImage() throws IOException, DockerException, InterruptedException {
final ArtifactPlan artifactPlan = new ArtifactPlan("id", "storeId", "build.json");
final ArtifactStoreConfig artifactStoreConfig = new ArtifactStoreConfig("localhost:5000", "other", "admin", "admin123");
final ArtifactStore artifactStore = new ArtifactStore(artifactPlan.getId(), artifactStoreConfig);
final PublishArtifactRequest publishArtifactRequest = new PublishArtifactRequest(artifactStore, artifactPlan, agentWorkingDir.getAbsolutePath());
final ArgumentCaptor<DockerProgressHandler> argumentCaptor = ArgumentCaptor.forClass(DockerProgressHandler.class);
Path path = Paths.get(agentWorkingDir.getAbsolutePath(), "build.json");
Files.write(path, "{\"image\":\"localhost:5000/alpine\",\"tag\":\"3.6\"}".getBytes());
when(request.requestBody()).thenReturn(publishArtifactRequest.toJSON());
doThrow(new RuntimeException("Some error")).when(dockerClient).push(eq("localhost:5000/alpine:3.6"), argumentCaptor.capture());
final GoPluginApiResponse response = new PublishArtifactExecutor(request, consoleLogger, dockerProgressHandler, dockerClientFactory).execute();
assertThat(response.responseCode()).isEqualTo(500);
assertThat(response.responseBody()).contains("Failed to publish Artifact[id=id, storeId=storeId, artifactPlanConfig={\"BuildFile\":\"build.json\"}]: Some error");
}
@Test
public void shouldReadEnvironmentVariablesPassedFromServer() throws IOException, DockerException, InterruptedException {
final ArtifactPlan artifactPlan = new ArtifactPlan("id", "storeId", "${IMAGE_NAME}", Optional.of("3.6"));
final ArtifactStoreConfig storeConfig = new ArtifactStoreConfig("localhost:5000", "other", "admin", "admin123");
final ArtifactStore artifactStore = new ArtifactStore(artifactPlan.getId(), storeConfig);
final PublishArtifactRequest publishArtifactRequest = new PublishArtifactRequest(artifactStore, artifactPlan, agentWorkingDir.getAbsolutePath(), Collections.singletonMap("IMAGE_NAME", "alpine"));
when(request.requestBody()).thenReturn(publishArtifactRequest.toJSON());
when(dockerProgressHandler.getDigest()).thenReturn("foo");
final GoPluginApiResponse response = new PublishArtifactExecutor(request, consoleLogger, dockerProgressHandler, dockerClientFactory).execute();
verify(dockerClient).push(eq("alpine:3.6"), any(ProgressHandler.class));
assertThat(response.responseCode()).isEqualTo(200);
assertThat(response.responseBody()).isEqualTo("{\"metadata\":{\"image\":\"alpine:3.6\",\"digest\":\"foo\"}}");
}
@Test
public void shouldReadEnvironmentVariablesFromTheSystem() throws IOException, DockerException, InterruptedException {
environmentVariables.set("IMAGE_NAME", "alpine");
final ArtifactPlan artifactPlan = new ArtifactPlan("id", "storeId", "${IMAGE_NAME}", Optional.of("3.6"));
final ArtifactStoreConfig storeConfig = new ArtifactStoreConfig("localhost:5000", "other", "admin", "admin123");
final ArtifactStore artifactStore = new ArtifactStore(artifactPlan.getId(), storeConfig);
final PublishArtifactRequest publishArtifactRequest = new PublishArtifactRequest(artifactStore, artifactPlan, agentWorkingDir.getAbsolutePath());
when(request.requestBody()).thenReturn(publishArtifactRequest.toJSON());
when(dockerProgressHandler.getDigest()).thenReturn("foo");
final GoPluginApiResponse response = new PublishArtifactExecutor(request, consoleLogger, dockerProgressHandler, dockerClientFactory).execute();
verify(dockerClient).push(eq("alpine:3.6"), any(ProgressHandler.class));
assertThat(response.responseCode()).isEqualTo(200);
assertThat(response.responseBody()).isEqualTo("{\"metadata\":{\"image\":\"alpine:3.6\",\"digest\":\"foo\"}}");
}
private static void closeDocker(DockerDBInfo dockerDBInfo) {
if (dockerDBInfo != null && dockerDBInfo.docker != null) {
try {
// Kill container
dockerDBInfo.docker.killContainer(dockerDBInfo.containerID);
// Remove container
dockerDBInfo.docker.removeContainer(dockerDBInfo.containerID);
// Close the docker client
dockerDBInfo.docker.close();
} catch (DockerException | InterruptedException ex) {
logger.warn("Could not kill the database container with connection string: " + dockerDBInfo.connectionString + "!", ex);
}
}
}
private static void closeDocker(DockerDBInfo dockerDBInfo) {
if (dockerDBInfo != null && dockerDBInfo.docker != null) {
try {
// Kill container
dockerDBInfo.docker.killContainer(dockerDBInfo.containerID);
// Remove container
dockerDBInfo.docker.removeContainer(dockerDBInfo.containerID);
// Close the docker client
dockerDBInfo.docker.close();
} catch (DockerException | InterruptedException ex) {
logger.warn("Could not kill the database container with connection string: " + dockerDBInfo.connectionString + "!", ex);
}
}
}
private boolean setHubUrl(BrowserInstance browserInstance,
String versionFromLabel) throws MalformedURLException,
DockerException, InterruptedException {
String seleniumServerUrl = getConfig().getSeleniumServerUrl();
boolean seleniumServerUrlAvailable = seleniumServerUrl != null
&& !seleniumServerUrl.isEmpty();
hubUrl = new URL(seleniumServerUrlAvailable ? seleniumServerUrl
: startDockerBrowser(browserInstance, versionFromLabel));
if (remoteUrl != null) {
try {
String remoteHost = remoteUrl.getHost();
log.trace("Converting {} to use {}", hubUrl, remoteHost);
URI uri = new URI(hubUrl.toString());
hubUrl = new URI(uri.getScheme(), null, remoteHost,
uri.getPort(), uri.getPath(), uri.getQuery(),
uri.getFragment()).toURL();
} catch (URISyntaxException e) {
log.warn("Exception converting URL {}", remoteUrl, e);
}
}
return seleniumServerUrlAvailable;
}
private void execInContainer(String containerId, String execCommand, boolean logout)
throws DockerException, InterruptedException {
LOGGER.info("exec container commmand: " + execCommand);
final String[] command = {"sh", "-c", execCommand};
final ExecCreation execCreation = docker.execCreate(
containerId, command, DockerClient.ExecCreateParam.attachStdout(),
DockerClient.ExecCreateParam.attachStderr());
LogStream logStream = docker.execStart(execCreation.id());
while (logStream.hasNext() && logout) {
final String log = UTF_8.decode(logStream.next().content()).toString();
LOGGER.info(log);
}
}
public String startDockerBrowser(BrowserInstance browserInstance,
String version) throws DockerException, InterruptedException {
String browserImage;
BrowserType browserType = browserInstance.getBrowserType();
if (version == null || version.isEmpty()
|| version.equalsIgnoreCase(LATEST)) {
log.info("Using {} version {} (latest)", browserType,
selenoidConfig.getDefaultBrowser(browserType));
browserImage = selenoidConfig.getLatestImage(browserInstance);
} else {
log.info("Using {} version {}", browserType, version);
browserImage = selenoidConfig.getImageFromVersion(browserType,
version);
}
if (browserType != EDGE && browserType != IEXPLORER) {
dockerService.pullImage(browserImage);
}
DockerContainer selenoidContainer = startSelenoidContainer();
return selenoidContainer.getContainerUrl();
}
public String execCommandInContainer(String containerId, String... command)
throws DockerException, InterruptedException {
String commandStr = Arrays.toString(command);
log.trace("Running command {} in container {}", commandStr,
containerId);
String execId = dockerClient.execCreate(containerId, command,
DockerClient.ExecCreateParam.attachStdout(),
DockerClient.ExecCreateParam.attachStderr()).id();
String output = null;
try (LogStream stream = dockerClient.execStart(execId)) {
if (stream.hasNext()) {
output = UTF_8.decode(stream.next().content()).toString();
}
} catch (Exception e) {
log.trace("Exception executing command in container", e);
}
log.trace("Result of command {} in container {}: {}", commandStr,
containerId, output);
return output;
}
public void pullImage(String imageId)
throws DockerException, InterruptedException {
if (!preferences.checkKeyInPreferences(imageId)
|| !getConfig().isUsePreferences() || !localDaemon) {
log.info("Pulling Docker image {}", imageId);
dockerClient.pull(imageId, new ProgressHandler() {
@Override
public void progress(ProgressMessage message)
throws DockerException {
log.trace("Pulling Docker image {} ... {}", imageId,
message);
}
});
log.trace("Docker image {} downloaded", imageId);
if (getConfig().isUsePreferences() && localDaemon) {
preferences.putValueInPreferencesIfEmpty(imageId, "pulled");
}
}
}
private static void predownloadImagesIfRequired() throws DockerException, InterruptedException {
DockerClient client = getClient();
LOG.warning("Commencing download of images.");
Collection<MappingInfo> images = getInstance().getMapping().values();
ProgressHandler handler = new LoggingBuildHandler();
for (MappingInfo image : images) {
List<Image> foundImages = client.listImages(DockerClient.ListImagesParam.byName(image.getTarget()));
if (! foundImages.isEmpty()) {
LOG.warning(String.format("Skipping download for Image [%s] because it's already available.",
image.getTarget()));
continue;
}
client.pull(image.getTarget(), handler);
}
}
private RegistryAuth createRegistryAuth(Server server) throws DockerException {
SettingsDecryptionRequest decryptionRequest = new DefaultSettingsDecryptionRequest(server);
SettingsDecryptionResult decryptionResult = settingsDecrypter.decrypt(decryptionRequest);
if (decryptionResult.getProblems().isEmpty()) {
log.debug("Successfully decrypted Maven server password");
} else {
for (SettingsProblem problem : decryptionResult.getProblems()) {
log.error("Settings problem for server {}: {}", server.getId(), problem);
}
throw new DockerException("Failed to decrypt Maven server password");
}
return RegistryAuth.builder()
.username(server.getUsername())
.password(decryptionResult.getServer().getPassword())
.build();
}
public static String findDockerImage(String imageName, DockerClient docker) {
if (docker == null) {
throw new RuntimeException("Docker client has not been initialized. No docker image can be found.");
}
try {
List<Image> allImages = docker.listImages(DockerClient.ListImagesParam.allImages());
String imageId = null;
for (Image image : allImages) {
if (image.repoTags() != null && image.repoTags().contains(imageName)) {
imageId = image.id();
break;
}
}
if (imageId == null) {
throw new RuntimeException("There was a problem when looking for the docker image with argument \""+imageName+"\": no image has been found.");
}
return imageId;
} catch (InterruptedException|DockerException e) {
throw new RuntimeException("Error while looking for the docker image",e);
}
}
/**
* In case of timeout, we kill the container.
* @param remove if true, it will remove both the container and the volumes
*/
public void killDockerContainer(DockerClient docker, boolean remove) {
if (this.containerId == null) {
LOGGER.error("Error while trying to kill docker container: the container id is not available. Maybe the container is not started yet.");
} else {
LOGGER.info("Killing the docker container with id "+containerId+". Forced killing date: "+this.limitDateBeforeKilling);
try {
docker.killContainer(containerId);
if (remove) {
docker.removeContainer(containerId);
this.removeVolumes(docker);
}
this.poolManager.removeSubmittedRunnablePipelineContainer(this);
serialize("INTERRUPTED");
} catch (DockerException|InterruptedException e) {
LOGGER.error("Error while killing docker container "+containerId, e);
}
}
}
private static void removeVolume() throws Exception {
if (dockerApiVersionAtLeast(docker, "1.26")) {
if (docker.listVolumes().volumes() != null) {
docker.listVolumes().volumes().forEach(volume -> {
if (volume.labels() != null && volume.labels().containsKey("cd.go.contrib.elasticagents.dockerswarm.elasticagent.DockerPlugin")) {
try {
docker.removeVolume(volume.name());
} catch (DockerException | InterruptedException e) {
}
}
});
}
} else {
LOG.warn(format("Detected docker version and api version is {0} and {1} respectively. Docker with api version 1.26 or above is required to use volume mounts, secrets and host file entries. Please refer https://docs.docker.com/engine/api/v1.32/#section/Versioning for more information about docker release.", docker.version().version(), docker.version().apiVersion()));
}
}
private String getServiceID() {
Service.Criteria criteria = Service.Criteria.builder().serviceName(this.serviceName).build();
String serviceId = null;
try {
List<Service> serviceList = Exceptions.handleInterruptedCall(
() -> dockerClient.listServices(criteria));
log.info("Service list size {}", serviceList.size());
if (!serviceList.isEmpty()) {
serviceId = serviceList.get(0).id();
}
} catch (DockerException e) {
throw new TestFrameworkException(TestFrameworkException.Type.RequestFailed, "Unable to get service id", e);
}
return serviceId;
}
@Override
public CompletableFuture<Void> scaleService(final int instanceCount) {
try {
Preconditions.checkArgument(instanceCount >= 0, "negative value: %s", instanceCount);
Service.Criteria criteria = Service.Criteria.builder().serviceName(this.serviceName).build();
TaskSpec taskSpec = Exceptions.handleInterruptedCall(() -> dockerClient.listServices(criteria).get(0).spec().taskTemplate());
String serviceId = getServiceID();
EndpointSpec endpointSpec = Exceptions.handleInterruptedCall(() -> dockerClient.inspectService(serviceId).spec().endpointSpec());
Service service = Exceptions.handleInterruptedCall(() -> dockerClient.inspectService(serviceId));
Exceptions.handleInterrupted(() -> dockerClient.updateService(serviceId, service.version().index(), ServiceSpec.builder().endpointSpec(endpointSpec).mode(ServiceMode.withReplicas(instanceCount)).taskTemplate(taskSpec).name(serviceName).networks(service.spec().networks()).build()));
return Exceptions.handleInterruptedCall(() -> waitUntilServiceRunning());
} catch (DockerException e) {
throw new TestFrameworkException(TestFrameworkException.Type.RequestFailed, "Test failure: Unable to scale service to given instances=" + instanceCount, e);
}
}
/**
* Retrieve the host ports that were opened at runtime for communicating with the docker container. This method
* is only useful to call after the container is started as the host ports are not known before.
*
* @return Optional {@link Map} of container port keys with a {@link List} of {@link PortBinding}s
*/
public Optional<Map<String, List<PortBinding>>> hostPortBindings() {
// reuse existing containers if they are running
if (nonNull(startedContainer)) {
try {
log.info("Inspecting container '{}' for host ports.", left(startedContainer.id(), SHORT_ID_LENGTH));
return ofNullable(dockerClient.inspectContainer(startedContainer.id()).networkSettings().ports());
}
catch (DockerException | InterruptedException e) {
log.error("Unable to inspect container for host ports '{}'", left(startedContainer.id(), SHORT_ID_LENGTH), e);
}
}
return empty();
}
private static void startHasFailedKillEverything() throws DockerException, InterruptedException {
LOG.error("|");
LOG.error("| ==================== ");
LOG.error("| YOUR TESTS WILL FAIL ");
LOG.error("| ==================== ");
LOG.error("|");
// Kill this container and wipe all connection information
dockerIpAddress = null;
pubsubPort = null;
terminateAndDiscardAnyExistingContainers(false);
}
private static void terminateAndDiscardAnyExistingContainers(boolean warnAboutExisting) throws DockerException, InterruptedException {
ContainerInfo containerInfo;
try {
containerInfo = docker.inspectContainer(CONTAINER_NAME_JUNIT);
// Already have this container running.
assertNotNull("We should either we get containerInfo or we get an exception", containerInfo);
LOG.info("");
LOG.info("/===========================================");
if (warnAboutExisting) {
LOG.warn("| >>> FOUND OLD EMULATOR INSTANCE RUNNING <<< ");
LOG.warn("| Destroying that one to keep tests running smoothly.");
}
LOG.info("| Cleanup of GCloud Emulator");
// We REQUIRE 100% accurate side effect free unit tests
// So we completely discard this one.
String id = containerInfo.id();
// Kill container
if (containerInfo.state().running()) {
docker.killContainer(id);
LOG.info("| - Killed");
}
// Remove container
docker.removeContainer(id);
LOG.info("| - Removed");
LOG.info("\\===========================================");
LOG.info("");
} catch (ContainerNotFoundException cnfe) {
// No such container. Good !
}
}
private static DefaultDockerClient createClient(ArtifactStoreConfig artifactStoreConfig) throws DockerCertificateException, DockerException, InterruptedException {
final RegistryAuthSupplierChain registryAuthSupplier = new RegistryAuthSupplierChain(artifactStoreConfig, new AWSTokenRequestGenerator());
DefaultDockerClient docker = DefaultDockerClient.fromEnv().registryAuthSupplier(registryAuthSupplier).build();
LOG.info(format("Using docker registry server `{0}`.", artifactStoreConfig.getRegistryUrl()));
final String result = docker.ping();
if (!result.equalsIgnoreCase("OK")) {
throw new RuntimeException("Could not ping the docker server.");
}
return docker;
}
private String getNoVncUrl(String selenoidHost, int selenoidPort,
String sessionId, String novncPassword)
throws DockerException, InterruptedException {
DockerContainer novncContainer = startNoVncContainer();
String novncUrl = novncContainer.getContainerUrl();
return format(
"%svnc.html?host=%s&port=%d&path=vnc/%s&resize=scale&autoconnect=true&password=%s",
novncUrl, selenoidHost, selenoidPort, sessionId, novncPassword);
}
public DockerContainer startNoVncContainer()
throws DockerException, InterruptedException {
DockerContainer novncContainer;
String novncImage = getConfig().getNovncImage();
if (containerMap.containsKey(novncImage)) {
log.debug("noVNC container already available");
novncContainer = containerMap.get(novncImage);
} else {
dockerService.pullImage(novncImage);
Map<String, List<PortBinding>> portBindings = new HashMap<>();
String defaultNovncPort = getConfig().getNovncPort();
portBindings.put(defaultNovncPort,
asList(randomPort(ALL_IPV4_ADDRESSES)));
String network = getConfig().getDockerNetwork();
novncContainer = DockerContainer.dockerBuilder(novncImage)
.portBindings(portBindings).network(network).build();
String containerId = dockerService.startContainer(novncContainer);
String novncHost = dockerService.getHost(containerId, network);
String novncPort = dockerService.getBindPort(containerId,
defaultNovncPort + "/tcp");
String novncUrl = format("http://%s:%s/", novncHost, novncPort);
novncContainer.setContainerId(containerId);
novncContainer.setContainerUrl(novncUrl);
containerMap.put(novncImage, novncContainer);
}
return novncContainer;
}
public String getHost(String containerId, String network)
throws DockerException, InterruptedException {
String dockerHost = getConfig().getDockerHost();
if( !dockerHost.isEmpty() ) {
return dockerHost;
}
return IS_OS_LINUX
? dockerClient.inspectContainer(containerId).networkSettings()
.networks().get(network).gateway()
: dockerClient.getHost();
}
public String getBindPort(String containerId, String exposed)
throws DockerException, InterruptedException {
ImmutableMap<String, List<PortBinding>> ports = dockerClient
.inspectContainer(containerId).networkSettings().ports();
List<PortBinding> exposedPort = ports.get(exposed);
log.trace("Port list {} -- Exposed port {} = {}", ports, exposed,
exposedPort);
if (ports.isEmpty() || exposedPort.isEmpty()) {
String dockerImage = dockerClient.inspectContainer(containerId)
.config().image();
throw new SeleniumJupiterException("Port " + exposed
+ " is not bindable in container " + dockerImage);
}
return exposedPort.get(0).hostPort();
}
private void startRedisIfNecessary() throws DockerException {
try {
if (container == null) {
DockerClient docker = DefaultDockerClient.fromEnv().build();
container = new RedisContainer(docker, host);
}
} catch (DockerCertificateException | InterruptedException e) {
throw new RuntimeException(e);
}
}