Use container host ip not manager ip

When providing node ip in metadata jclouds was using the
ip of the docker manager which was fine for docker machine
but fails when using a swarm cluster.  This uses the ip returned
from docker.
This commit is contained in:
Duncan Grant 2016-05-26 10:34:13 +01:00 committed by Andrea Turli
parent c0469cc9b7
commit ebc8f7568f
5 changed files with 94 additions and 15 deletions

View File

@ -36,6 +36,7 @@ import org.jclouds.domain.Location;
import org.jclouds.providers.ProviderMetadata;
import com.google.common.base.Function;
import com.google.common.base.Strings;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@ -61,9 +62,9 @@ public class ContainerToNodeMetadata implements Function<Container, NodeMetadata
@Inject
ContainerToNodeMetadata(ProviderMetadata providerMetadata,
Function<State, NodeMetadata.Status> toPortableStatus, GroupNamingConvention.Factory namingConvention,
Supplier<Map<String, ? extends Image>> images, @Memoized Supplier<Set<? extends Location>> locations,
LoginPortForContainer loginPortForContainer) {
Function<State, NodeMetadata.Status> toPortableStatus, GroupNamingConvention.Factory namingConvention,
Supplier<Map<String, ? extends Image>> images, @Memoized Supplier<Set<? extends Location>> locations,
LoginPortForContainer loginPortForContainer) {
this.providerMetadata = providerMetadata;
this.toPortableStatus = toPortableStatus;
this.nodeNamingConvention = namingConvention.createWithoutPrefix();
@ -81,7 +82,7 @@ public class ContainerToNodeMetadata implements Function<Container, NodeMetadata
.name(name)
.group(group)
.hostname(container.config().hostname())
// TODO Set up hardware
// TODO Set up hardware
.hardware(new HardwareBuilder()
.id("")
.ram(container.config().memory())
@ -89,14 +90,14 @@ public class ContainerToNodeMetadata implements Function<Container, NodeMetadata
.build());
builder.status(toPortableStatus.apply(container.state()));
builder.loginPort(loginPortForContainer.apply(container).or(NO_LOGIN_PORT));
builder.publicAddresses(getPublicIpAddresses());
builder.publicAddresses(getPublicIpAddresses(container));
builder.privateAddresses(getPrivateIpAddresses(container));
builder.location(Iterables.getOnlyElement(locations.get()));
String imageId = container.image();
builder.imageId(imageId);
if (images.get().containsKey(imageId)) {
Image image = images.get().get(imageId);
builder.operatingSystem(image.getOperatingSystem());
Image image = images.get().get(imageId);
builder.operatingSystem(image.getOperatingSystem());
}
return builder.build();
}
@ -110,8 +111,13 @@ public class ContainerToNodeMetadata implements Function<Container, NodeMetadata
return ImmutableList.of(container.networkSettings().ipAddress());
}
private List<String> getPublicIpAddresses() {
String dockerIpAddress = URI.create(providerMetadata.getEndpoint()).getHost();
private List<String> getPublicIpAddresses(Container container) {
String dockerIpAddress;
if (container.node() != null && !Strings.isNullOrEmpty(container.node().ip())) {
dockerIpAddress = container.node().ip();
} else {
dockerIpAddress = URI.create(providerMetadata.getEndpoint()).getHost();
}
return ImmutableList.of(dockerIpAddress);
}

View File

@ -77,6 +77,8 @@ public abstract class Container {
@Nullable public abstract String processLabel();
@Nullable public abstract Node node();
Container() {
}
@ -84,17 +86,17 @@ public abstract class Container {
{
"Id", "Created", "Path", "Name", "Args", "Config", "State", "Image", "NetworkSettings", "SysInitPath",
"ResolvConfPath", "Volumes", "HostConfig", "Driver", "ExecDriver", "VolumesRW", "Command", "Status",
"Ports", "HostnamePath", "HostsPath", "MountLabel", "ProcessLabel"
"Ports", "HostnamePath", "HostsPath", "MountLabel", "ProcessLabel", "Node"
})
public static Container create(String id, Date created, String path, String name, List<String> args, Config config,
State state, String image, NetworkSettings networkSettings, String sysInitPath,
String resolvConfPath, Map<String, String> volumes, HostConfig hostConfig,
String driver, String execDriver, Map<String, Boolean> volumesRW, String command,
String status, List<Port> ports, String hostnamePath, String hostsPath,
String mountLabel, String processLabel) {
String mountLabel, String processLabel, Node node) {
return new AutoValue_Container(id, created, path, name, copyOf(args), config, state, image, networkSettings,
sysInitPath, resolvConfPath, copyOf(volumes), hostConfig, driver, execDriver, copyOf(volumesRW), command,
status, copyOf(ports), hostnamePath, hostsPath, mountLabel, processLabel);
status, copyOf(ports), hostnamePath, hostsPath, mountLabel, processLabel, node);
}
public static Builder builder() {
@ -130,6 +132,7 @@ public abstract class Container {
private String hostsPath;
private String mountLabel;
private String processLabel;
private Node node;
public Builder id(String id) {
this.id = id;
@ -246,10 +249,15 @@ public abstract class Container {
return this;
}
public Builder node(Node node) {
this.node = node;
return this;
}
public Container build() {
return Container.create(id, created, path, name, args, config, state, image, networkSettings,
sysInitPath, resolvConfPath, volumes, hostConfig, driver, execDriver, volumesRW, command, status,
ports, hostnamePath, hostsPath, mountLabel, processLabel);
ports, hostnamePath, hostsPath, mountLabel, processLabel, node);
}
public Builder fromContainer(Container in) {
@ -258,7 +266,7 @@ public abstract class Container {
.sysInitPath(in.sysInitPath()).resolvConfPath(in.resolvConfPath()).driver(in.driver())
.execDriver(in.execDriver()).volumes(in.volumes()).hostConfig(in.hostConfig()).volumesRW(in.volumesRW())
.command(in.command()).status(in.status()).ports(in.ports()).hostnamePath(in.hostnamePath())
.hostsPath(in.hostsPath()).mountLabel(in.mountLabel()).processLabel(in.processLabel());
.hostsPath(in.hostsPath()).mountLabel(in.mountLabel()).processLabel(in.processLabel()).node(in.node());
}
}
}

View File

@ -0,0 +1,63 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.docker.domain;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;
import com.google.auto.value.AutoValue;
@AutoValue
public abstract class Node {
Node() {
}
@SerializedNames({"IP"})
public static Node create(String ip) {
return new AutoValue_Node(ip);
}
public static Builder builder() {
return new Builder();
}
@Nullable
public abstract String ip();
public Builder toBuilder() {
return builder().fromNode(this);
}
public static final class Builder {
private String ip;
public Builder ip(String ip) {
this.ip = ip;
return this;
}
public Node build() {
return Node.create(this.ip);
}
public Builder fromNode(Node in) {
return this.ip(in.ip());
}
}
}

View File

@ -203,6 +203,7 @@ public class ContainerToNodeMetadataTest {
expect(mockContainer.name()).andReturn(container.name());
expect(mockContainer.config()).andReturn(container.config()).anyTimes();
expect(mockContainer.networkSettings()).andReturn(container.networkSettings()).anyTimes();
expect(mockContainer.node()).andReturn(container.node()).anyTimes();
expect(mockContainer.state()).andReturn(container.state());
expect(mockContainer.image()).andReturn(container.image()).anyTimes();
replay(mockContainer);

View File

@ -23,6 +23,7 @@ import java.util.logging.Level;
import org.jclouds.docker.DockerApi;
import org.jclouds.docker.features.ImageApi;
import org.jclouds.docker.options.DeleteImageOptions;
import com.google.common.base.Preconditions;
@ -72,7 +73,7 @@ public class DockerTestUtils {
Preconditions.checkNotNull(imageName, "Docker image name has to be provided");
final ImageApi imageApi = dockerApi.getImageApi();
if (null != imageApi.inspectImage(imageName)) {
consumeStreamSilently(imageApi.deleteImage(imageName));
consumeStreamSilently(imageApi.deleteImage(imageName, DeleteImageOptions.Builder.force(true)));
}
}
}