From 2b4ca239d7033d20fd1516184f1fe31bdd902d9d Mon Sep 17 00:00:00 2001 From: Nigel Magnay Date: Fri, 6 Feb 2015 14:30:22 +0000 Subject: [PATCH 1/2] Add some utility classes for splitting up "tag parameters" passed at various points (e.g: 10.0.0.1:8000/mybuild:1234) Signed-off-by: Nigel Magnay --- .../dockerjava/api/model/Identifier.java | 59 +++++++++++++++++++ .../dockerjava/api/model/Repository.java | 46 +++++++++++++++ .../dockerjava/api/model/IdentifierTest.java | 39 ++++++++++++ .../dockerjava/api/model/RepositoryTest.java | 18 ++++++ 4 files changed, 162 insertions(+) create mode 100644 src/main/java/com/github/dockerjava/api/model/Identifier.java create mode 100644 src/main/java/com/github/dockerjava/api/model/Repository.java create mode 100644 src/test/java/com/github/dockerjava/api/model/IdentifierTest.java create mode 100644 src/test/java/com/github/dockerjava/api/model/RepositoryTest.java diff --git a/src/main/java/com/github/dockerjava/api/model/Identifier.java b/src/main/java/com/github/dockerjava/api/model/Identifier.java new file mode 100644 index 000000000..498104e29 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Identifier.java @@ -0,0 +1,59 @@ +package com.github.dockerjava.api.model; + + +import com.google.common.base.Objects; +import com.google.common.base.Optional; + +/** + * Created by magnayn on 22/07/2014. + */ +public class Identifier { + public final Repository repository; + public final Optional tag; + + public Identifier(Repository repository, String tag) { + this.repository = repository; + + if( tag == null ) + this.tag = Optional.absent(); + else + this.tag = Optional.of(tag); + } + + + /** + * Return an identifier that correctly splits up the repository and tag. + * There can be > 1 ":" + * fred/jim --> fred/jim, [] + * fred/jim:123 --> fred/jim, 123 + * fred:123/jim:123 --> fred:123/jim, 123 + * + * + * @param identifier as a string + * @return parsed identifier. + */ + public static Identifier fromCompoundString(String identifier) { + String[] parts = identifier.split("/"); + if( parts.length != 2 ) { + String[] rhs = identifier.split(":"); + if( rhs.length != 2 ) + return new Identifier( new Repository(identifier), null); + else + return new Identifier( new Repository(rhs[0]), rhs[1]); + } + + String[] rhs = parts[1].split(":"); + if( rhs.length != 2 ) + return new Identifier( new Repository(identifier), null); + + return new Identifier( new Repository(parts[0] + "/" + rhs[0]), rhs[1]); + } + + @Override + public String toString() { + return Objects.toStringHelper(this) + .add("repository", repository) + .add("tag", tag) + .toString(); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/Repository.java b/src/main/java/com/github/dockerjava/api/model/Repository.java new file mode 100644 index 000000000..673eabee2 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Repository.java @@ -0,0 +1,46 @@ +package com.github.dockerjava.api.model; + +import com.google.common.base.Objects; + +import java.net.MalformedURLException; +import java.net.URL; + +/** + * A repository or image name. + */ +public class Repository { + public final String name; + + /** + * Name may be eg. 'busybox' or '10.0.0.1:5000/fred' + * @param name Repository name + */ + public Repository(String name) { + this.name = name; + } + + /** + * Return the URL portion (repository). + * Note that this might not actually BE a repository location. + * @return + * @throws java.net.MalformedURLException + */ + public URL getURL() throws MalformedURLException { + return new URL("http://" + name); + } + + @Override + public String toString() { + return Objects.toStringHelper(this) + .add("name", name) + .toString(); + } + + + public String getPath() { + if( !name.contains("/") ) + return name; + + return name.substring(name.indexOf("/") + 1 ); + } +} diff --git a/src/test/java/com/github/dockerjava/api/model/IdentifierTest.java b/src/test/java/com/github/dockerjava/api/model/IdentifierTest.java new file mode 100644 index 000000000..d57c0b572 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/IdentifierTest.java @@ -0,0 +1,39 @@ +package com.github.dockerjava.api.model; + +import junit.framework.TestCase; + + +public class IdentifierTest extends TestCase { + + public void testFromCompoundString() throws Exception { + + Identifier i1 = Identifier.fromCompoundString("10.0.0.1/jim"); + Identifier i2 = Identifier.fromCompoundString("10.0.0.1/jim:123"); + Identifier i3 = Identifier.fromCompoundString("10.0.0.1:123/jim:124"); + Identifier i3A = Identifier.fromCompoundString("10.0.0.1:123/jim:latest"); + + assertTrue(!i1.tag.isPresent()); + assertEquals(i1.repository.name, "10.0.0.1/jim"); + + assertTrue(i2.tag.isPresent()); + assertEquals(i2.tag.get(), "123"); + assertEquals(i2.repository.name, "10.0.0.1/jim"); + + assertTrue(i3.tag.isPresent()); + assertEquals(i3.tag.get(), "124"); + assertEquals(i3.repository.name, "10.0.0.1:123/jim"); + assertEquals(i3.repository.getURL().getPort(), 123); + assertEquals(i3A.tag.get(), "latest"); + + + Identifier i4 = Identifier.fromCompoundString("centos:latest"); + assertTrue(i4.tag.isPresent()); + assertEquals(i4.tag.get(), "latest"); + + Identifier i5 = Identifier.fromCompoundString("busybox"); + assertTrue(!i5.tag.isPresent()); + + Identifier i6 = Identifier.fromCompoundString("10.0.0.1:5000/my-test-image:1234"); + assertEquals(i6.repository.getPath(), "my-test-image"); + } +} \ No newline at end of file diff --git a/src/test/java/com/github/dockerjava/api/model/RepositoryTest.java b/src/test/java/com/github/dockerjava/api/model/RepositoryTest.java new file mode 100644 index 000000000..8a40de28b --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/RepositoryTest.java @@ -0,0 +1,18 @@ +package com.github.dockerjava.api.model; + +import junit.framework.TestCase; + +public class RepositoryTest extends TestCase { + public void testRepository() throws Exception { + + Repository repo = new Repository("10.0.0.1/jim"); + Repository repo1 = new Repository("10.0.0.1:1234/jim"); + Repository repo2 = new Repository("busybox"); + + assertEquals("jim", repo.getPath()); + assertEquals("jim", repo1.getPath()); + assertEquals("busybox", repo2.getPath()); + + assertEquals(1234, repo1.getURL().getPort()); + } +} \ No newline at end of file From 81b30b2625b87b7cd46ed8a78b47bcf11fba24a9 Mon Sep 17 00:00:00 2001 From: Nigel Magnay Date: Mon, 23 Feb 2015 16:55:46 +0000 Subject: [PATCH 2/2] Convenience function for pushing by full tag. Signed-off-by: Nigel Magnay --- .../github/dockerjava/api/DockerClient.java | 3 +++ .../dockerjava/core/DockerClientImpl.java | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/DockerClient.java b/src/main/java/com/github/dockerjava/api/DockerClient.java index d905ef105..1a3a285fa 100644 --- a/src/main/java/com/github/dockerjava/api/DockerClient.java +++ b/src/main/java/com/github/dockerjava/api/DockerClient.java @@ -4,6 +4,7 @@ import com.github.dockerjava.api.command.*; import com.github.dockerjava.api.model.AuthConfig; +import com.github.dockerjava.api.model.Identifier; // https://godoc.org/github.com/fsouza/go-dockerclient public interface DockerClient extends Closeable { @@ -29,6 +30,8 @@ public interface DockerClient extends Closeable { public PushImageCmd pushImageCmd(String name); + public PushImageCmd pushImageCmd(Identifier identifier); + public CreateImageCmd createImageCmd(String repository, InputStream imageStream); diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java index dd9e566da..06009d875 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java @@ -10,6 +10,7 @@ import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.command.*; import com.github.dockerjava.api.model.AuthConfig; +import com.github.dockerjava.api.model.Identifier; import com.github.dockerjava.core.command.*; /** @@ -129,8 +130,21 @@ public PushImageCmd pushImageCmd(String name) { return new PushImageCmdImpl(getDockerCmdExecFactory() .createPushImageCmdExec(), name).withAuthConfig(dockerClientConfig.effectiveAuthConfig(name)); } - - @Override + + @Override + public PushImageCmd pushImageCmd(Identifier identifier) { + PushImageCmd cmd = pushImageCmd(identifier.repository.name); + if( identifier.tag.isPresent() ) + cmd.withTag(identifier.tag.get()); + + AuthConfig cfg = dockerClientConfig.effectiveAuthConfig(identifier.repository.name); + if( cfg != null ) + cmd.withAuthConfig(cfg); + + return cmd; + } + + @Override public SaveImageCmd saveImageCmd(String name) { return new SaveImageCmdImpl(getDockerCmdExecFactory() .createSaveImageCmdExec(), name).withAuthConfig(dockerClientConfig.effectiveAuthConfig(name));