Skip to content

Commit

Permalink
Fix broken links section in docker-compose recipe (#2850)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mykola Morhun authored Oct 31, 2016
1 parent 329bd6a commit d74b24f
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,28 @@
*******************************************************************************/
package org.eclipse.che.plugin.docker.client.json;

import com.google.gson.annotations.SerializedName;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** @author andrew00x */
public class NetworkSettings {
@SerializedName("IPAddress")
private String ipAddress;
private int iPPrefixLen;
@SerializedName("IPPrefixLen")
private int ipPrefixLen;
private String gateway;
private String bridge;
private String[] portMapping;
private String macAddress;
private int linkLocalIPv6PrefixLen;
private String globalIPv6Address;
private int globalIPv6PrefixLen;
private String iPv6Gateway;
@SerializedName("IPv6Gateway")
private String ipV6Gateway;
private String linkLocalIPv6Address;

private Map<String, List<PortBinding>> ports = new HashMap<>();
Expand All @@ -40,11 +45,11 @@ public void setIpAddress(String ipAddress) {
}

public int getIpPrefixLen() {
return iPPrefixLen;
return ipPrefixLen;
}

public void setIpPrefixLen(int iPPrefixLen) {
this.iPPrefixLen = iPPrefixLen;
this.ipPrefixLen = iPPrefixLen;
}

public String getGateway() {
Expand Down Expand Up @@ -111,12 +116,12 @@ public void setGlobalIPv6PrefixLen(int globalIPv6PrefixLen) {
this.globalIPv6PrefixLen = globalIPv6PrefixLen;
}

public String getiPv6Gateway() {
return iPv6Gateway;
public String getIpV6Gateway() {
return ipV6Gateway;
}

public void setiPv6Gateway(String iPv6Gateway) {
this.iPv6Gateway = iPv6Gateway;
public void setIpV6Gateway(String ipV6Gateway) {
this.ipV6Gateway = ipV6Gateway;
}

public String getLinkLocalIPv6Address() {
Expand All @@ -131,15 +136,15 @@ public void setLinkLocalIPv6Address(String linkLocalIPv6Address) {
public String toString() {
return "NetworkSettings{" +
"ipAddress='" + ipAddress + '\'' +
", iPPrefixLen=" + iPPrefixLen +
", ipPrefixLen=" + ipPrefixLen +
", gateway='" + gateway + '\'' +
", bridge='" + bridge + '\'' +
", portMapping=" + Arrays.toString(portMapping) +
", macAddress='" + macAddress + '\'' +
", linkLocalIPv6PrefixLen=" + linkLocalIPv6PrefixLen +
", globalIPv6Address='" + globalIPv6Address + '\'' +
", globalIPv6PrefixLen=" + globalIPv6PrefixLen +
", iPv6Gateway='" + iPv6Gateway + '\'' +
", ipV6Gateway='" + ipV6Gateway + '\'' +
", linkLocalIPv6Address='" + linkLocalIPv6Address + '\'' +
", ports=" + ports +
'}';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public Map<String, String> getProperties() {
md.put("network.linkLocalIPv6PrefixLen", String.valueOf(networkSettings.getLinkLocalIPv6PrefixLen()));
md.put("network.globalIPv6Address", networkSettings.getGlobalIPv6Address());
md.put("network.globalIPv6PrefixLen", String.valueOf(networkSettings.getGlobalIPv6PrefixLen()));
md.put("network.iPv6Gateway", networkSettings.getiPv6Gateway());
md.put("network.iPv6Gateway", networkSettings.getIpV6Gateway());
md.put("network.linkLocalIPv6Address", networkSettings.getLinkLocalIPv6Address());
}
HostConfig hostConfig = info.getHostConfig();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public DockerMachineSource(MachineSource machineSource) throws MachineException
}


/**
/**
* Build image source based on given arguments
* @param repository as for example codenvy/ubuntu_jdk8
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,8 @@ private String createContainer(String workspaceId,
isDev,
service);

EndpointConfig endpointConfig = new EndpointConfig().withAliases(machineName);
EndpointConfig endpointConfig = new EndpointConfig().withAliases(machineName)
.withLinks(toArrayIfNotNull(service.getLinks()));
NetworkingConfig networkingConfig = new NetworkingConfig().withEndpointsConfig(singletonMap(networkName,
endpointConfig));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.eclipse.che.plugin.docker.client.DockerConnectorConfiguration;
import org.eclipse.che.plugin.docker.client.ProgressMonitor;
import org.eclipse.che.plugin.docker.client.UserSpecificDockerRegistryCredentialsProvider;
import org.eclipse.che.plugin.docker.client.json.ContainerConfig;
import org.eclipse.che.plugin.docker.client.json.ContainerCreated;
import org.eclipse.che.plugin.docker.client.json.ContainerInfo;
import org.eclipse.che.plugin.docker.client.json.ContainerState;
Expand Down Expand Up @@ -1086,6 +1087,26 @@ public void shouldAddEnvVarsFromMachineConfigToContainerOnDevInstanceCreationFro
.collect(Collectors.toList())));
}

@Test
public void shouldAddLinksToContainerOnCreation() throws Exception {
// given
String links[] = new String[] {"container1", "container2:alias"};
String networkName = "network";

CheServiceImpl service = createService();
service.setLinks(asList(links));

// when
createInstanceFromRecipe(service, true);

// then
ArgumentCaptor<CreateContainerParams> argumentCaptor = ArgumentCaptor.forClass(CreateContainerParams.class);
verify(dockerConnector).createContainer(argumentCaptor.capture());
ContainerConfig containerConfig = argumentCaptor.getValue().getContainerConfig();
assertEquals(containerConfig.getHostConfig().getLinks(), links);
assertEquals(containerConfig.getNetworkingConfig().getEndpointsConfig().get(NETWORK_NAME).getLinks(), links);
}

private CheServiceImpl createInstanceFromRecipe() throws Exception {
CheServiceImpl service = createService();
createInstanceFromRecipe(service);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,24 +360,24 @@ public Instance startMachine(String workspaceId,
machine.setId(service.getId());

machineStarter = (machineLogger, machineSource) -> {
CheServiceImpl serviceWithCorrectSource = getServiceWithCorrectSource(service, machineSource);
CheServiceImpl serviceWithNormalizedSource = normalizeServiceSource(service, machineSource);

normalize(namespace,
workspaceId,
machineConfig.getName(),
serviceWithCorrectSource);
serviceWithNormalizedSource);

ExtendedMachineImpl extendedMachine = new ExtendedMachineImpl();
extendedMachine.setAgents(agents);
applyAgents(extendedMachine, serviceWithCorrectSource);
applyAgents(extendedMachine, serviceWithNormalizedSource);

return machineProvider.startService(namespace,
workspaceId,
environmentHolder.name,
machineConfig.getName(),
machineConfig.isDev(),
environmentHolder.networkId,
serviceWithCorrectSource,
serviceWithNormalizedSource,
machineLogger);
};
} else {
Expand All @@ -387,8 +387,8 @@ public Instance startMachine(String workspaceId,
addAgentsProvidedServers(machine, agents);

machineStarter = (machineLogger, machineSource) -> {
Machine machineWithCorrectSource = getMachineWithCorrectSource(machine, machineSource);
return provider.createInstance(machineWithCorrectSource, machineLogger);
Machine machineWithNormalizedSource = normalizeMachineSource(machine, machineSource);
return provider.createInstance(machineWithNormalizedSource, machineLogger);
};
} catch (NotFoundException e) {
throw new NotFoundException(format("Provider of machine type '%s' not found", machineConfig.getType()));
Expand Down Expand Up @@ -543,7 +543,7 @@ private void initializeEnvironment(String namespace,

List<String> servicesOrder = startStrategy.order(environment);

normilizeVolumesFrom(environment);
normalizeNames(environment);

EnvironmentHolder environmentHolder = new EnvironmentHolder(servicesOrder,
environment,
Expand Down Expand Up @@ -614,20 +614,69 @@ private void normalize(String namespace,
}
}

private void normilizeVolumesFrom(CheServicesEnvironmentImpl environment) {
/**
* Sets specific names for this environment instance where it is required.
*
* @param environment
* environment in which names will be normalized
*/
private void normalizeNames(CheServicesEnvironmentImpl environment) {
Map<String, CheServiceImpl> services = environment.getServices();
// replace machines names in volumes_from with containers IDs
for (Map.Entry<String, CheServiceImpl> serviceEntry : services.entrySet()) {
CheServiceImpl service = serviceEntry.getValue();
if (service.getVolumesFrom() != null) {
service.setVolumesFrom(service.getVolumesFrom()
.stream()
.map(serviceName -> services.get(serviceName).getContainerName())
.collect(toList()));
}
normalizeVolumesFrom(service, services);
normalizeLinks(service, services);
}
}

// replace machines names in volumes_from with containers IDs
private void normalizeVolumesFrom(CheServiceImpl service, Map<String, CheServiceImpl> services) {
if (service.getVolumesFrom() != null) {
service.setVolumesFrom(service.getVolumesFrom()
.stream()
.map(serviceName -> services.get(serviceName).getContainerName())
.collect(toList()));
}
}

/**
* Replaces linked to this service's name with container name which represents the service in links section.
* The problem is that a user writes names of other services in links section in compose file.
* But actually links are constraints and their values should be names of containers (not services) to be linked.
* <br/>
* For example: serviceDB:serviceDbAlias -> container_1234:serviceDbAlias <br/>
* If alias is omitted then service name will be used.
*
* @param serviceToNormalizeLinks
* service which links will be normalized
* @param services
* all services in environment
*/
@VisibleForTesting
void normalizeLinks(CheServiceImpl serviceToNormalizeLinks, Map<String, CheServiceImpl> services) {
serviceToNormalizeLinks.setLinks(
serviceToNormalizeLinks.getLinks()
.stream()
.map(link -> {
// a link has format: 'name:alias' or 'name'
String serviceNameAndAliasToLink[] = link.split(":", 2);
String serviceName = serviceNameAndAliasToLink[0];
String serviceAlias = (serviceNameAndAliasToLink.length > 1) ?
serviceNameAndAliasToLink[1] : null;
CheServiceImpl serviceLinkTo = services.get(serviceName);
if (serviceLinkTo != null) {
String containerNameLinkTo = serviceLinkTo.getContainerName();
return (serviceAlias == null) ?
containerNameLinkTo :
containerNameLinkTo + ':' + serviceAlias;
} else {
// should never happens. Errors like this should be filtered by CheEnvironmentValidator
throw new IllegalArgumentException("Attempt to link non existing service " + serviceName +
" to " + serviceToNormalizeLinks + " service.");
}
}).collect(toList()));
}

private void normalize(String namespace,
String workspaceId,
String machineName,
Expand Down Expand Up @@ -725,14 +774,14 @@ private void startEnvironmentQueue(String namespace,
// needed to reuse startInstance method and
// create machine instances by different implementation-specific providers
MachineStarter machineStarter = (machineLogger, machineSource) -> {
CheServiceImpl serviceWithCorrectSource = getServiceWithCorrectSource(service, machineSource);
CheServiceImpl serviceWithNormalizedSource = normalizeServiceSource(service, machineSource);
return machineProvider.startService(namespace,
workspaceId,
envName,
finalMachineName,
isDev,
networkId,
serviceWithCorrectSource,
serviceWithNormalizedSource,
machineLogger);
};

Expand Down Expand Up @@ -918,47 +967,47 @@ Instance startMachine(LineConsumer machineLogger,
NotFoundException;
}

private CheServiceImpl getServiceWithCorrectSource(CheServiceImpl service,
MachineSource machineSource)
private CheServiceImpl normalizeServiceSource(CheServiceImpl service,
MachineSource machineSource)
throws ServerException {
CheServiceImpl serviceWithCorrectSource = service;
CheServiceImpl serviceWithNormalizedSource = service;
if (machineSource != null) {
serviceWithCorrectSource = new CheServiceImpl(service);
serviceWithNormalizedSource = new CheServiceImpl(service);
if ("image".equals(machineSource.getType())) {
serviceWithCorrectSource.setBuild(null);
serviceWithCorrectSource.setImage(machineSource.getLocation());
serviceWithNormalizedSource.setBuild(null);
serviceWithNormalizedSource.setImage(machineSource.getLocation());
} else {
// dockerfile
serviceWithCorrectSource.setImage(null);
serviceWithNormalizedSource.setImage(null);
if (machineSource.getContent() != null) {
serviceWithCorrectSource.setBuild(new CheServiceBuildContextImpl(null,
null,
machineSource.getContent(),
null));
serviceWithNormalizedSource.setBuild(new CheServiceBuildContextImpl(null,
null,
machineSource.getContent(),
null));
} else {
serviceWithCorrectSource.setBuild(new CheServiceBuildContextImpl(machineSource.getLocation(),
null,
null,
null));
serviceWithNormalizedSource.setBuild(new CheServiceBuildContextImpl(machineSource.getLocation(),
null,
null,
null));
}
}
}
return serviceWithCorrectSource;
return serviceWithNormalizedSource;
}

private Machine getMachineWithCorrectSource(MachineImpl machine, MachineSource machineSource) {
Machine machineWithCorrectSource = machine;
private Machine normalizeMachineSource(MachineImpl machine, MachineSource machineSource) {
Machine machineWithNormalizedSource = machine;
if (machineSource != null) {
machineWithCorrectSource = MachineImpl.builder()
.fromMachine(machine)
.setConfig(MachineConfigImpl.builder()
.fromConfig(machine.getConfig())
.setSource(machineSource)
.build())
.build();
machineWithNormalizedSource = MachineImpl.builder()
.fromMachine(machine)
.setConfig(MachineConfigImpl.builder()
.fromConfig(machine.getConfig())
.setSource(machineSource)
.build())
.build();

}
return machineWithCorrectSource;
return machineWithNormalizedSource;
}

private void addMachine(MachineImpl machine) throws ServerException {
Expand Down
Loading

0 comments on commit d74b24f

Please sign in to comment.