Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docker container fetch limit is now configurable #513

Merged
merged 1 commit into from
Jul 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions doc/manual/external-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ Example:
</image>
```

Given this example configuration a single image configuration is build
up from the following properties, which correspond to corresponding
Given this example configuration a single image configuration is built
up from the following properties, which correspond to the corresponding
values in the `<build>` and `<run>` sections.

* **docker.alias** Alias name
Expand Down Expand Up @@ -83,6 +83,7 @@ used to create the image. The dockerfile must be name `Dockerfile`
used as environment variables. The environment variables takes precedence over any other environment
variables specified.
* **docker.extraHosts.idx** List of `host:ip` to add to `/etc/hosts`
* **docker.fetchLimit** Number of running and stopped containers to return. A value of 0 returns all running and stopped containers. Default is 100.
* **docker.from** Base image for building an image
* **docker.hostname** Container hostname
* **docker.labels.LABEL** Sets a label which works similarly like setting environment variables.
Expand Down
2 changes: 2 additions & 0 deletions doc/manual/global-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ parentheses.
* **skip** (`docker.skip`)
With this parameter the execution of this plugin can be skipped
completely.
* **fetchLimit** (`docker.fetchLimit`)
Number of running and stopped containers to return. A value of 0 returns all running and stopped containers. Default is 100.
* **skipTags** (`docker.skipTags`)
If set to `true` the plugin won't add any tags to images that have been built.
* **registry** (`docker.registry`)
Expand Down
11 changes: 9 additions & 2 deletions src/main/java/io/fabric8/maven/docker/AbstractDockerMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ public abstract class AbstractDockerMojo extends AbstractMojo implements Context
@Parameter(property = "docker.skip", defaultValue = "false")
private boolean skip;

// Max number of containers to fetch when stopping/removing
@Parameter(property = "docker.fetchLimit", defaultValue = "100")
protected int fetchLimit;

/**
* Whether to restrict operation to a single image. This can be either
* the image or an alias name. It can also be comma separated list.
Expand All @@ -139,7 +143,7 @@ public abstract class AbstractDockerMojo extends AbstractMojo implements Context
// property file to write out with port mappings
@Parameter
protected String portPropertyFile;

// Authentication information
@Parameter
Map authConfig;
Expand Down Expand Up @@ -178,7 +182,9 @@ public void execute() throws MojoExecutionException, MojoFailureException {
DockerAccess access = null;
try {
access = createDockerAccess(minimalApiVersion);
ServiceHub serviceHub = serviceHubFactory.createServiceHub(project, session, access, log, logSpecFactory);
fetchLimit = resolvedImages.get(0).getRunConfiguration().getFetchLimit() != null
Copy link
Collaborator

Choose a reason for hiding this comment

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

It doesnt makes sense to pick up only the first image for extracting the fetchLimit. Currently it only makes sense as a globale parameter (as you already put it in). Since I guess it makes also only sense to put it into the global scope (i.e. valid for all images), I'll move it from ServiceHub to DockerAccess and remove the two variants of listImages() (since the list will automatically truncate).

Copy link
Author

Choose a reason for hiding this comment

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

Well spotted. I meant to ask you about fetching the resolvedImage. I was not happy with the get(0) it's a bit dangerous ..

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, that was a misunderstanding on my side. A global parameter is good enough.

However, our problem indeed is how we can make the lookup of a container by its name and by its image more effective. Because then we could omit the call to list() altogether. And it would be much more effective, too, especially for a large set of running containers. At the time this was implemented, there was no way with the API todo this direct lookup, but it could be that there is now an alternative API call.

I will go hunting a bit ... ;-)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Just saw that there are new filters for the list call:

exited=<int>; -- containers with exit code of <int> ;
status=(created|restarting|running|paused|exited|dead)
label=key or label="key=value" of a container label
isolation=(default|process|hyperv) (Windows daemon only)
ancestor=(<image-name>[:<tag>], <image id> or <image@digest>)
before=(<container id> or <container name>)
since=(<container id> or <container name>)
volume=(<volume name> or <mount point destination>)
network=(<network id> or <network name>)

So maybe since and ancestors could be a match for our use case ....

Copy link
Collaborator

@rhuss rhuss Jul 12, 2016

Choose a reason for hiding this comment

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

E.g.

  • for fetching by name: since=<container name>&limit=1
  • for fetching by images: ancestor=<image name>&limit=1

Hopefully the filter is inclusive. 'will try this out now ...

Copy link
Author

Choose a reason for hiding this comment

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

gah -- we are on 1.11 -- I will upgrade Nucleus's docker tomorrow to 1.24..

Copy link
Collaborator

@rhuss rhuss Jul 12, 2016

Choose a reason for hiding this comment

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

I'm also only on 1.21, however there is since query param (not as part of the filter), but it seems to eclusive, not inclusive (so the entry with the name itself is not included).

For the name lookup I have to check why I haven't use the /containers/<name>/json call. I remember darkly, there was a reason ;-)

'have to run now, see you tomorrow ...

Copy link
Collaborator

Choose a reason for hiding this comment

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

Cool, filtering with 'ancestor=' works. Unfortunately only available since 1.23

But with this two features we should get rid of the local iteration of image names (we leave it in nevertheless so that the plugin will work with older clients, too).

? resolvedImages.get(0).getRunConfiguration().getFetchLimit() : fetchLimit;
ServiceHub serviceHub = serviceHubFactory.createServiceHub(project, session, access, log, logSpecFactory, fetchLimit);
executeInternal(serviceHub);
} catch (DockerAccessException exp) {
log.error("%s", exp.getMessage());
Expand Down Expand Up @@ -225,6 +231,7 @@ public List<ImageConfiguration> resolve(ImageConfiguration image) {

// Customization hook for subclasses to influence the final configuration. This method is called
// before initialization and validation of the configuration.
@Override
public List<ImageConfiguration> customizeConfig(List<ImageConfiguration> imageConfigs) {
return imageConfigs;
}
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/io/fabric8/maven/docker/access/UrlBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public String containerLogs(String containerId, boolean follow) {
.p("follow", follow)
.build();
}

public String createContainer(String name) {
return u("containers/create")
.p("name", name)
Expand All @@ -70,13 +70,19 @@ public String inspectContainer(String containerId) {
return u("containers/%s/json", containerId)
.build();
}

public String listContainers(int limit) {
return u("containers/json")
.p("limit", limit)
.build();
}

public String listAllContainers() {
return u("containers/json")
.p("all", 0)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldnt this be "1" ?

Copy link
Author

Choose a reason for hiding this comment

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

Yep -- misread the documentation.
Will change.

Copy link
Collaborator

Choose a reason for hiding this comment

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

no worries, I already did some refactorings, will push my changes in an own branch soon.

.build();
}

public String pullImage(ImageName name, String registry) {
return u("images/create")
.p("fromImage", name.getNameWithoutTag(registry))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public void stopContainer(String containerId, int killWait) throws DockerAccessE

@Override
public void buildImage(String image, File dockerArchive, String dockerfileName, boolean forceRemove, boolean noCache,
Map<String, String> buildArgs) throws DockerAccessException {
Map<String, String> buildArgs) throws DockerAccessException {
try {
String url = urlBuilder.buildImage(image, dockerfileName, forceRemove, noCache, buildArgs);
delegate.post(url, dockerArchive, createBuildResponseHandler(), HTTP_OK);
Expand All @@ -198,7 +198,7 @@ public void buildImage(String image, File dockerArchive, String dockerfileName,
}

@Override
public void copyArchive(String containerId,File archive, String targetPath)
public void copyArchive(String containerId, File archive, String targetPath)
throws DockerAccessException {
try {
String url = urlBuilder.copyArchive(containerId, targetPath);
Expand Down Expand Up @@ -235,7 +235,7 @@ public Container inspectContainer(String containerId) throws DockerAccessExcepti

@Override
public List<Container> listContainers(int limit) throws DockerAccessException {
String url = urlBuilder.listContainers(limit);
String url = limit == 0 ? urlBuilder.listAllContainers() : urlBuilder.listContainers(limit);

try {
String response = delegate.get(url, HTTP_OK);
Expand Down Expand Up @@ -300,7 +300,7 @@ public void pullImage(String image, AuthConfig authConfig, String registry)

try {
delegate.post(pullUrl, null, createAuthHeader(authConfig),
createPullOrPushResponseHandler(), HTTP_OK);
createPullOrPushResponseHandler(), HTTP_OK);
} catch (IOException e) {
throw new DockerAccessException(e, "Unable to pull '%s'%s", image, (registry != null) ? " from registry '" + registry + "'" : "");
}
Expand All @@ -314,7 +314,7 @@ public void pushImage(String image, AuthConfig authConfig, String registry)
String temporaryImage = tagTemporaryImage(name, registry);
try {
delegate.post(pushUrl, null, createAuthHeader(authConfig),
createPullOrPushResponseHandler(), HTTP_OK);
createPullOrPushResponseHandler(), HTTP_OK);
} catch (IOException e) {
throw new DockerAccessException(e, "Unable to push '%s'%s", image, (registry != null) ? " from registry '" + registry + "'" : "");
} finally {
Expand All @@ -334,7 +334,7 @@ public void tag(String sourceImage, String targetImage, boolean force)
delegate.post(url, HTTP_CREATED);
} catch (IOException e) {
throw new DockerAccessException(e, "Unable to add tag [%s] to image [%s]", targetImage,
sourceImage, e);
sourceImage, e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,18 @@ public class RunImageConfiguration {
@Parameter
private WaitConfiguration wait;

@Parameter
private Integer fetchLimit;

@Parameter
private LogConfiguration log;

@Parameter
private RestartPolicy restartPolicy;

@Parameter
private boolean skip = false;

public RunImageConfiguration() { }

public String initAndValidate() {
Expand Down Expand Up @@ -197,6 +200,10 @@ public WaitConfiguration getWaitConfiguration() {
return wait;
}

public Integer getFetchLimit() {
return fetchLimit;
}

public LogConfiguration getLogConfiguration() {
return log;
}
Expand Down Expand Up @@ -224,7 +231,7 @@ public List<String> getDnsSearch() {
public List<String> getExtraHosts() {
return extraHosts;
}

public VolumeConfiguration getVolumeConfiguration() {
return volumes;
}
Expand All @@ -248,7 +255,7 @@ public enum NamingStrategy {
public NamingStrategy getNamingStrategy() {
return namingStrategy == null ? NamingStrategy.none : namingStrategy;
}

public Boolean getPrivileged() {
return privileged;
}
Expand All @@ -260,7 +267,7 @@ public RestartPolicy getRestartPolicy() {
public boolean skip() {
return skip;
}

// ======================================================================================

public static class Builder {
Expand Down Expand Up @@ -387,12 +394,16 @@ public Builder wait(WaitConfiguration wait) {
return this;
}

public Builder fetchLimit(Integer fetchLimit) {
config.fetchLimit = fetchLimit;
return this;
}

public Builder log(LogConfiguration log) {
config.log = log;
return this;
}


public Builder namingStrategy(String namingStrategy) {
config.namingStrategy = namingStrategy == null ?
NamingStrategy.none :
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package io.fabric8.maven.docker.config.handler.property;/*
*
*
* Copyright 2014 Roland Huss
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -15,8 +15,6 @@
* limitations under the License.
*/

import static io.fabric8.maven.docker.assembly.DockerFileKeyword.WORKDIR;

/**
* Enum holding possible configuration keys
*
Expand Down Expand Up @@ -51,6 +49,7 @@ public enum ConfigKey {
ENV,
ENV_PROPERTY_FILE,
EXTRA_HOSTS,
FETCH_LIMIT,
FROM,
HOSTNAME,
LABELS,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package io.fabric8.maven.docker.config.handler.property;/*
*
*
* Copyright 2014 Roland Huss
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -40,14 +40,14 @@ public String getType() {
@Override
public List<ImageConfiguration> resolve(ImageConfiguration config, Properties properties) throws IllegalArgumentException {
String prefix = getPrefix(config);

RunImageConfiguration run = extractRunConfiguration(prefix,properties);
BuildImageConfiguration build = extractBuildConfiguration(prefix,properties);
WatchImageConfiguration watch = extractWatchConfig(prefix, properties);

String name = extractName(prefix, properties);
String alias = withPrefix(prefix, ALIAS, properties);

return Collections.singletonList(
new ImageConfiguration.Builder()
.name(name)
Expand Down Expand Up @@ -85,7 +85,7 @@ private BuildImageConfiguration extractBuildConfiguration(String prefix, Propert
}

private RunImageConfiguration extractRunConfiguration(String prefix, Properties properties) {

return new RunImageConfiguration.Builder()
.capAdd(listWithPrefix(prefix, CAP_ADD, properties))
.capDrop(listWithPrefix(prefix, CAP_DROP, properties))
Expand Down Expand Up @@ -113,14 +113,15 @@ private RunImageConfiguration extractRunConfiguration(String prefix, Properties
.workingDir(withPrefix(prefix, WORKING_DIR, properties))
.log(extractLogConfig(prefix,properties))
.wait(extractWaitConfig(prefix, properties))
.fetchLimit(intWithPrefix(prefix, FETCH_LIMIT, properties))
.volumes(extractVolumeConfig(prefix, properties))
.skip(withPrefix(prefix, SKIP_RUN, properties))
.build();
}

private AssemblyConfiguration extractAssembly(String prefix, Properties properties) {
return new AssemblyConfiguration.Builder()
.basedir(withPrefix(prefix, ASSEMBLY_BASEDIR, properties))
.basedir(withPrefix(prefix, ASSEMBLY_BASEDIR, properties))
.descriptor(withPrefix(prefix, ASSEMBLY_DESCRIPTOR, properties))
.descriptorRef(withPrefix(prefix, ASSEMBLY_DESCRIPTOR_REF, properties))
.dockerFileDir(withPrefix(prefix, ASSEMBLY_DOCKER_FILE_DIR, properties))
Expand All @@ -130,15 +131,15 @@ private AssemblyConfiguration extractAssembly(String prefix, Properties properti
.mode(withPrefix(prefix, ASSEMBLY_MODE, properties))
.build();
}

private String extractName(String prefix, Properties properties) throws IllegalArgumentException {
String name = withPrefix(prefix, NAME, properties);
if (name == null) {
throw new IllegalArgumentException(String.format("Mandatory property [%s] is not defined", NAME));
}
return name;
}

// Extract only the values of the port mapping
private List<String> extractPortValues(String prefix, Properties properties) {
List<String> ret = new ArrayList<>();
Expand Down Expand Up @@ -204,7 +205,7 @@ private WaitConfiguration extractWaitConfig(String prefix, Properties properties
.tcpPorts(asIntList(listWithPrefix(prefix, WAIT_TCP_PORT, properties)))
.build();
}

private WatchImageConfiguration extractWatchConfig(String prefix, Properties properties) {
return new WatchImageConfiguration.Builder()
.interval(asInt(withPrefix(prefix, WATCH_INTERVAL, properties)))
Expand All @@ -219,7 +220,7 @@ private VolumeConfiguration extractVolumeConfig(String prefix, Properties proper
.from(listWithPrefix(prefix, VOLUMES_FROM, properties))
.build();
}

private int asInt(String s) {
return s != null ? Integer.parseInt(s) : 0;
}
Expand All @@ -241,11 +242,11 @@ private List<Integer> asIntList(List<String> strings) {
private List<String> listWithPrefix(String prefix, ConfigKey key, Properties properties) {
return extractFromPropertiesAsList(key.asPropertyKey(prefix), properties);
}

private Map<String, String> mapWithPrefix(String prefix, ConfigKey key, Properties properties) {
return extractFromPropertiesAsMap(key.asPropertyKey(prefix), properties);
}

private String withPrefix(String prefix, ConfigKey key, Properties properties) {
return properties.getProperty(key.asPropertyKey(prefix));
}
Expand All @@ -255,6 +256,11 @@ private Long longWithPrefix(String prefix, ConfigKey key, Properties properties)
return prop == null ? null : Long.valueOf(prop);
}

private Integer intWithPrefix(String prefix, ConfigKey key, Properties properties) {
String prop = withPrefix(prefix, key, properties);
return prop == null ? null : Integer.valueOf(prop);
}

private Boolean booleanWithPrefix(String prefix, ConfigKey key, Properties properties) {
String prop = withPrefix(prefix,key,properties);
return prop == null ? null : Boolean.valueOf(prop);
Expand Down
Loading