Commit 9ceafa7d authored by Joerg Domaschka's avatar Joerg Domaschka

intermediate state to adding support for docker private registries

parent e08d7f7e
package de.uniulm.omi.cloudiator.lance.lca.containers.docker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
enum DockerConfiguration {
INSTANCE{
},
;
private final String hostname;
private final int port;
private final boolean useRegistry;
DockerConfiguration(){
useRegistry = DockerConfigurationFields.isEnabled();
hostname = DockerConfigurationFields.getHostname();
port = DockerConfigurationFields.getPort();
if(shouldBeUsedButCant()) {
DockerConfigurationFields.LOGGER.error("cannot make use of registry@ " + hostname + ":" + port);
}
}
private boolean shouldBeUsedButCant() {
if(!useRegistry) return false;
if(hostname == null || hostname.isEmpty() || port < 0 || port > 65555) // whatever the right number is
return true;
return false;
}
static class DockerConfigurationFields {
private static final Logger LOGGER = LoggerFactory.getLogger(DockerConfigurationFields.class);
public static final String DOCKER_REGISTRY_USE_KEY = "host.docker.registry.use";
public static final String DOCKER_REGISTRY_HOST_KEY = "host.docker.registry.host";
public static final String DOCKER_REGISTRY_PORT_KEY = "host.docker.registry.port";
public static final Boolean DOCKER_REGISTRY_USE_DEFAULT = Boolean.FALSE;
public static final String DOCKER_REGISTRY_HOST_DEFAULT = null;
public static final int DOCKER_REGISTRY_PORT_DEFAULT = 5000;
static boolean isEnabled() {
System.out.println(System.getProperties());
String s = System.getProperty(DockerConfigurationFields.DOCKER_REGISTRY_USE_KEY, DockerConfigurationFields.DOCKER_REGISTRY_USE_DEFAULT.toString());
if("true".equals(s)) {
LOGGER.debug("use of docker registry enabled.");
return true;
}
LOGGER.debug("use of docker registry disabled.");
return false;
}
static String getHostname() {
return System.getProperty(DockerConfigurationFields.DOCKER_REGISTRY_HOST_KEY, DockerConfigurationFields.DOCKER_REGISTRY_HOST_DEFAULT);
}
static int getPort() {
String s = System.getProperty(DockerConfigurationFields.DOCKER_REGISTRY_PORT_KEY, Integer.toString(DockerConfigurationFields.DOCKER_REGISTRY_PORT_DEFAULT));
try {
return Integer.parseInt(s);
} catch(NumberFormatException ex) {
if(s != null && !s.isEmpty())
LOGGER.warn("cannot set port nunmber");
return -1;
}
}
}
public boolean registryCanBeUsed() {
return registryEnabled() && !shouldBeUsedButCant();
}
public boolean registryEnabled() {
return useRegistry;
}
public String prependRegistry(String pre) {
if(useRegistry && !shouldBeUsedButCant()) {
return hostname + ":" + port + "/" + pre;
}
return pre;
}
}
......@@ -61,20 +61,21 @@ public class DockerContainerLogic implements ContainerLogic, LifecycleActionInte
DockerContainerLogic(ComponentInstanceId id, DockerConnector client, DeployableComponent comp,
DeploymentContext ctx, OperatingSystem os, NetworkHandler network,
DockerShellFactory shellFactoryParam) {
this(id, client, os, ctx, comp, network, shellFactoryParam);
DockerShellFactory shellFactoryParam, DockerConfiguration dockerConfig) {
this(id, client, os, ctx, comp, network, shellFactoryParam, dockerConfig);
}
private DockerContainerLogic(ComponentInstanceId id, DockerConnector clientParam, OperatingSystem osParam,
DeploymentContext ctx, DeployableComponent componentParam,
NetworkHandler networkParam, DockerShellFactory shellFactoryParam) {
NetworkHandler networkParam, DockerShellFactory shellFactoryParam,
DockerConfiguration dockerConfigParam) {
if(osParam == null)
throw new NullPointerException("operating system has to be set.");
myId = id;
client = clientParam;
imageHandler = new DockerImageHandler(osParam, new DockerOperatingSystemTranslator(), clientParam, componentParam);
imageHandler = new DockerImageHandler(osParam, new DockerOperatingSystemTranslator(), clientParam, componentParam, dockerConfigParam);
deploymentContext = ctx;
shellFactory = shellFactoryParam;
myComponent = componentParam;
......@@ -111,7 +112,7 @@ public class DockerContainerLogic implements ContainerLogic, LifecycleActionInte
@Override
public void doDestroy(boolean force) throws ContainerException {
/* docker ignores the flag */
/* currently docker ignores the flag */
try {
client.stopContainer(myId);
} catch(DockerException de) {
......
......@@ -52,6 +52,7 @@ public class DockerContainerManager implements ContainerManager {
private final String hostname;
private final DockerConnector client;
private final ContainerRegistry registry = new ContainerRegistry();
private final DockerConfiguration dockerConfig = DockerConfiguration.INSTANCE;
public DockerContainerManager(HostContext vmId) {
this(vmId, LcaConstants.LOCALHOST_IP, false);
......@@ -89,7 +90,7 @@ public class DockerContainerManager implements ContainerManager {
GlobalRegistryAccessor accessor = new GlobalRegistryAccessor(ctx, comp, id);
NetworkHandler networkHandler = new NetworkHandler(accessor, comp, hostContext);
DockerContainerLogic logic = new DockerContainerLogic(id, client, comp, ctx, os, networkHandler, shellFactory);
DockerContainerLogic logic = new DockerContainerLogic(id, client, comp, ctx, os, networkHandler, shellFactory, dockerConfig);
// DockerLifecycleInterceptor interceptor = new DockerLifecycleInterceptor(accessor, id, networkHandler, comp, shellFactory);
ExecutionContext ec = new ExecutionContext(os, shellFactory);
LifecycleController controller = new LifecycleController(comp.getLifecycleStore(), logic, accessor, ec);
......
......@@ -35,14 +35,16 @@ final class DockerImageHandler {
private final OperatingSystem os;
private final DockerConnector client;
private final DeployableComponent myComponent;
private final DockerConfiguration dockerConfig;
private volatile ImageCreationType initSource;
DockerImageHandler(OperatingSystem osParam, DockerOperatingSystemTranslator translatorParam,
DockerConnector clientParam, DeployableComponent componentParam) {
DockerConnector clientParam, DeployableComponent componentParam, DockerConfiguration dockerConfigParam) {
if(osParam == null)
throw new NullPointerException("operating system has to be set.");
dockerConfig = dockerConfigParam;
os = osParam;
translator = translatorParam;
client = clientParam;
......@@ -83,16 +85,19 @@ final class DockerImageHandler {
}
private String doGetSingleImage(String key) throws DockerException {
// TODO: remove this as soon as access to a private registry is set
if(client.findImage(key) != null) {
return key;
}
if(!dockerConfig.registryCanBeUsed())
return key;
try {
client.pullImage(key);
return key;
String pre = dockerConfig.prependRegistry(key);
client.pullImage(pre);
return pre;
} catch(DockerException de) {
LOGGER.debug("could not pull image.", de);
LOGGER.debug("could not pull image. creating one.");
return null;
}
}
......@@ -101,23 +106,36 @@ final class DockerImageHandler {
String componentInstallId = createComponentInstallId();
// first step: try to find matching image for configured component
// currently not implemented; TODO: implement
searchImageInLocalCache();
// second step: try to find matching image for prepared component
// in case a custom docker registry is configured
getImageFromPrivateRepository();
// third step: fall back to the operating system //
getImageFromDefaultLocation(myId);
initSource = ImageCreationType.OPERATING_SYSTEM;
return target;
}
private void searchImageInLocalCache() {
}
private void getImageFromPrivateRepository() {
String target = buildImageTagName(ImageCreationType.COMPONENT, componentInstallId);
String result = doGetSingleImage(target);
if(result != null) {
initSource = ImageCreationType.COMPONENT;
return result; //FIXME: set in component lifecycle stage
}
// third step
target = buildImageTagName(ImageCreationType.OPERATING_SYSTEM, null);
result = doGetSingleImage(target);
}
private void getImageFromDefaultLocation(ComponentInstanceId myId) throws DockerException {
String target = buildImageTagName(ImageCreationType.OPERATING_SYSTEM, null);
String result = doGetSingleImage(target);
if(result == null) {
throw new DockerException("cannot pull image: " + myId + " for key " + target);
}
initSource = ImageCreationType.OPERATING_SYSTEM;
return target;
}
/** here, we may want to run a snapshotting action
......
package de.uniulm.omi.cloudiator.lance.lca.containers.docker;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import de.uniulm.omi.cloudiator.lance.application.DeploymentContext;
import de.uniulm.omi.cloudiator.lance.application.component.DeployableComponent;
import de.uniulm.omi.cloudiator.lance.container.spec.os.OperatingSystem;
import de.uniulm.omi.cloudiator.lance.lca.HostContext;
import de.uniulm.omi.cloudiator.lance.lca.container.ComponentInstanceId;
import de.uniulm.omi.cloudiator.lance.lca.container.ContainerException;
import de.uniulm.omi.cloudiator.lance.lca.container.port.NetworkHandler;
import de.uniulm.omi.cloudiator.lance.lca.containers.docker.connector.ConnectorFactory;
import de.uniulm.omi.cloudiator.lance.lca.containers.docker.connector.DockerConnector;
import de.uniulm.omi.cloudiator.lance.lca.containers.dummy.DummyInterceptor;
import de.uniulm.omi.cloudiator.lance.lca.registry.RegistrationException;
import de.uniulm.omi.cloudiator.lance.lifecycle.ExecutionContext;
import de.uniulm.omi.cloudiator.lance.lifecycle.HandlerType;
import de.uniulm.omi.cloudiator.lance.lifecycle.LifecycleController;
import de.uniulm.omi.cloudiator.lance.lifecycle.LifecycleException;
import de.uniulm.omi.cloudiator.lance.lifecycle.LifecycleHandlerType;
import de.uniulm.omi.cloudiator.lance.lifecycle.detector.DetectorType;
import de.uniulm.omi.cloudiator.lance.lifecycles.CoreElements;
import de.uniulm.omi.cloudiator.lance.lifecycles.LifecycleStoreCreator;
public class DockerSnapshottingTest {
public volatile DummyInterceptor interceptor;
public volatile LifecycleController lcc;
public volatile CoreElements core;
public volatile LifecycleStoreCreator creator;
private volatile ExecutionContext ctx;
private volatile Map<ComponentInstanceId, Map<String, String>> dumb;
private volatile DockerContainerManager manager;
static class FakeHostContext implements HostContext {
@Override
public String getPublicIp() {
throw new UnsupportedOperationException();
}
@Override
public String getInternalIp() {
throw new UnsupportedOperationException();
}
@Override
public String getCloudIdentifier() {
throw new UnsupportedOperationException();
}
@Override
public void close() throws InterruptedException {
throw new UnsupportedOperationException();
}
@Override
public void run(Runnable runner) {
throw new UnsupportedOperationException();
}
@Override
public ScheduledFuture<?> scheduleAction(Runnable runner) {
throw new UnsupportedOperationException();
}
}
static String hostname = "localhost";
@BeforeClass
public static void configureHostContext() {
CoreElements.initStatic();
}
@Before
public void init() {
System.setProperty("host.docker.registry.port", Integer.toString(5000));
System.setProperty("host.docker.registry.host", "134.60.64.242");
System.setProperty("host.docker.registry.use", Boolean.toString(true));
core = new CoreElements(false);
manager = new DockerContainerManager(new FakeHostContext());
}
@Test
public void testCreation() throws ContainerException {
DockerConfiguration dockerConfig = DockerConfiguration.INSTANCE;
DockerConnector client = ConnectorFactory.INSTANCE.createConnector(hostname);
DockerShellFactory shellFactory = new DockerShellFactory();
DockerContainerLogic logic = new DockerContainerLogic(core.componentInstanceId,
client, core.comp, core.ctx, OperatingSystem.UBUNTU_14_04,
core.networkHandler, shellFactory, dockerConfig);
logic.doCreate();
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment