Skip to content
Snippets Groups Projects
Commit 013be64a authored by Amandine  TOURNAY's avatar Amandine TOURNAY
Browse files

Added project

parent a504c052
Branches
No related tags found
No related merge requests found
.idea/
target/
.settings/
*.iml
.project
.classpath
\ No newline at end of file
pom.xml 0 → 100644
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- Inherited Icy Parent POM -->
<parent>
<groupId>org.bioimageanalysis.icy</groupId>
<artifactId>parent-pom-plugin</artifactId>
<version>1.0.3</version>
</parent>
<!-- Project Information -->
<artifactId>docker4icy</artifactId>
<version>3.2.7</version>
<packaging>jar</packaging>
<name>Docker for Icy</name>
<description>Yes, it is finally here. A user-friendly interface to Docker, letting you run containers within your plug-ins in no time.</description>
<url>http://icy.bioimageanalysis.org/plugin/docker-for-icy/</url>
<inceptionYear>2020</inceptionYear>
<organization>
<name>Institut Pasteur</name>
<url>https://pasteur.fr</url>
</organization>
<licenses>
<license>
<name>GNU GPLv3</name>
<url>https://www.gnu.org/licenses/gpl-3.0.en.html</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>sdallongeville</id>
<name>Stéphane Dallongeville</name>
<url>https://research.pasteur.fr/fr/member/stephane-dallongeville/</url>
<roles>
<role>founder</role>
<role>lead</role>
<role>architect</role>
<role>developer</role>
<role>debugger</role>
<role>tester</role>
<role>maintainer</role>
<role>support</role>
</roles>
</developer>
</developers>
<!-- Project properties -->
<properties>
</properties>
<!-- Project build configuration -->
<build>
</build>
<!-- List of project's dependencies -->
<dependencies>
<!-- The core of Icy -->
<dependency>
<groupId>org.bioimageanalysis.icy</groupId>
<artifactId>icy-kernel</artifactId>
</dependency>
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java</artifactId>
<version>3.2.7</version>
</dependency>
</dependencies>
<!-- Icy Maven repository (to find parent POM) -->
<repositories>
<repository>
<id>icy</id>
<name>Icy's Nexus</name>
<url>https://icy-nexus.pasteur.fr/repository/Icy/</url>
</repository>
</repositories>
</project>
package plugins.adufour.docker;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import icy.file.FileUtil;
import icy.plugin.PluginLoader;
import icy.plugin.abstract_.Plugin;
import icy.plugin.classloader.JarClassLoader;
import icy.plugin.interface_.PluginDaemon;
import icy.util.JarUtil;
/**
* Icy interface to <a href="https://www.docker.com/what-docker">Docker</a>. This daemon loads up
* necessary 3rd-party libraries into the class path at startup (and every time the plug-in list is
* reloaded). To interact with Docker, see the {@link DockerUtil} class.
*
* @author Alexandre Dufour
*/
public class Docker4Icy extends Plugin implements PluginDaemon
{
/** The temporary folder where the 3rd party libraries will be extracted */
private static final String libFolder = FileUtil.getTempDirectory() + "/Docker4Icy/";
@Override
public void init()
{
try
{
// 1) Unpack and load 3rd-party JAR libraries via a temporary folder
URL url = DockerUtil.class.getResource("lib");
if (url != null)
{
String[] jarFiles = new File(url.getFile()).list();
for (String jarFile : jarFiles)
{
String fileName = FileUtil.getFileName(jarFile);
extractResource(libFolder + fileName, DockerUtil.class.getResource("lib" + File.separator + fileName));
((JarClassLoader) PluginLoader.getLoader()).add(new URL("file://" + libFolder + fileName));
}
}
else
{
String jarPath = FileUtil.getApplicationDirectory() + "/" + getDescriptor().getJarFilename();
for (String jarFile : JarUtil.getAllFiles(jarPath, false, false))
if (jarFile.endsWith(".jar"))
{
String fileName = FileUtil.getFileName(jarFile);
extractResource(libFolder + fileName, DockerUtil.class.getResource("lib/" + fileName));
((JarClassLoader) PluginLoader.getLoader()).add(libFolder + fileName);
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
@Override
public void run()
{
// Don't run. I'm too fast for you anyway.
}
@Override
public void stop()
{
// Delete the temporary folder:
// 1) for the beauty of saving space until the next run...
// 2) To prevent potential conflicts after upgrades
FileUtil.delete(new File(libFolder), true);
}
}
package plugins.adufour.docker;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateContainerCmd;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.model.AccessMode;
import com.github.dockerjava.api.model.Bind;
import com.github.dockerjava.api.model.Volume;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientBuilder;
import com.github.dockerjava.core.command.ExecStartResultCallback;
import com.github.dockerjava.core.command.PullImageResultCallback;
/**
* Utility class to easily interface with (and run)
* <a href="https://www.docker.com/what-docker">Docker</a> within Icy, using the official
* <a href="https://github.com/docker-java/docker-java">docker-java API</a>.
*
* @author Alexandre Dufour
*/
public class DockerUtil
{
private static DockerClient docker = DockerClientBuilder.getInstance(DefaultDockerClientConfig.createDefaultConfigBuilder().build()).build();
/**
* Starts a container with the specified image
*
* @param image
* the image to run (and download if necessary)
* @return the container ID
* @throws InterruptedException
*/
public static String startContainer(String image) throws InterruptedException
{
return startContainer(image, (List<Bind>) null, null);
}
/**
* Starts a container with the specified image and virtual folder binding(s)
*
* @param image
* the image to run (and download if necessary)
* @param bindings
* Virtual bindings between host and container folders, e.g.
* <code>{"/host/a", "/docker/b"}</code>. NB: by default, these mappings are set to
* "read-write" mode. For further control, use
* {@link #startContainer(String, List, String)}
* @return the container ID
* @throws InterruptedException
*/
public static String startContainer(String image, Map<String, String> bindings) throws InterruptedException
{
return startContainer(image, bindings, null);
}
/**
* Starts a container with the specified image and virtual folder binding(s)
*
* @param image
* the image to run (and download if necessary)
* @param bindings
* Virtual bindings between host and container folders, e.g.
* <code>new Bind("/host/a", "/docker/b", AccessMode.rw)</code>
* @return the container ID
* @throws InterruptedException
*/
public static String startContainer(String image, List<Bind> bindings) throws InterruptedException
{
return startContainer(image, bindings, null);
}
/**
* Starts a container with the specified image and virtual folder binding(s)
*
* @param image
* the image to run (and download if necessary)
* @param bindings
* Virtual bindings between host and container folders, e.g.
* <code>{"/host/a", "/docker/b"}</code>. NB: by default, these mappings are set to
* "read-write" mode. For further control, use
* {@link #startContainer(String, List, String)}
* @param workingDirectory
* the directory where the container should start from (e.g.
* <code>"/docker/b/subdir"</code>). This is equivalent to (but faster than) starting
* the container and then calling <code>"cd /docker/b/subdir"</code>
* @return the container ID
* @throws InterruptedException
*/
public static String startContainer(String image, Map<String, String> bindings, String workingDirectory) throws InterruptedException
{
List<Bind> bindingList = null;
if (bindings != null)
{
// Convert user mappings to Docker bindings
bindingList = new ArrayList<Bind>(bindings.size());
for (Entry<String, String> binding : bindings.entrySet())
bindingList.add(new Bind(binding.getKey(), new Volume(binding.getValue()), AccessMode.rw));
}
return startContainer(image, bindingList, workingDirectory);
}
/**
* Starts a container with the specified image and virtual folder binding(s)
*
* @param image
* the image to run (and download if necessary)
* @param bindings
* Virtual bindings between host and container folders, e.g.
* <code>new Bind("/host/a", "/docker/b", AccessMode.rw)</code>
* @param workingDirectory
* the directory where the container should start from (e.g.
* <code>"/docker/b/subdir"</code>). This is equivalent to (but faster than) starting
* the container and then calling <code>"cd /docker/b/subdir"</code>
* @return the container ID
* @throws InterruptedException
*/
public static String startContainer(String image, List<Bind> bindings, String workingDirectory) throws InterruptedException
{
System.out.println("Fetching image " + image);
docker.pullImageCmd(image).exec(new PullImageResultCallback()).awaitCompletion();
System.out.println("Starting container using " + image);
CreateContainerCmd createCommand = docker.createContainerCmd(image);
if (bindings != null) createCommand = createCommand.withBinds(bindings);
if (workingDirectory != null) createCommand = createCommand.withWorkingDir(workingDirectory);
// Emulate a TTY and attach output and error streams
createCommand = createCommand.withTty(true).withAttachStdout(true).withAttachStderr(true);
// Finally, start the container
CreateContainerResponse container = createCommand.exec();
String containerID = container.getId();
docker.startContainerCmd(containerID).exec();
return containerID;
}
public static void stopContainer(String containerID)
{
docker.stopContainerCmd(containerID).exec();
}
/**
* Runs the specified command in the given container and awaits completion
*
* @param containerID
* the ID of the container where the command should run
* @param command
* the command to run (e.g. <code>"echo hello Icy world!"</code>
* @throws InterruptedException
* if the calling thread was interrupted before completion of the command
*/
public static void runCommand(String containerID, String command) throws InterruptedException
{
String cmd = docker.execCreateCmd(containerID).withAttachStdout(true).withAttachStderr(true).withTty(true).withCmd(command.split(" ")).exec().getId();
docker.execStartCmd(cmd).exec(new ExecStartResultCallback(System.out, System.err)).awaitCompletion();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment