Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allows use of Maven settings for defining registry credentials. #81

Merged
merged 29 commits into from
Feb 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
cb61b1f
Uses credential helper for pulling base image as well.
coollog Feb 7, 2018
a452c91
Changes credential helpers to be a list.
coollog Feb 7, 2018
bb65b01
Changes to multiple credential helpers for jib-maven-plugin.
coollog Feb 7, 2018
88de538
Adds image reference to RegistryUnauthorizedException.
coollog Feb 7, 2018
9ac2c1a
Fixes build steps.
coollog Feb 7, 2018
122549b
Fixes nullpointerexception.
coollog Feb 7, 2018
c622a8a
Merge branch 'master' into multiple-credhelpers
coollog Feb 7, 2018
b7fd773
Updates README and CHANGELOG.
coollog Feb 7, 2018
08066d1
Updates README and CHANGELOG.
coollog Feb 7, 2018
3d2592c
Merge branch 'master' into multiple-credhelpers
coollog Feb 7, 2018
ac990d0
Merge branch 'master' into multiple-credhelpers
coollog Feb 8, 2018
e6d4134
Pulls registry credentials from Maven settings.
coollog Feb 8, 2018
4595dc5
Fixes spacing.
coollog Feb 8, 2018
6bbb7d3
Merge branch 'multiple-credhelpers' of github.com:google/jib into mul…
coollog Feb 8, 2018
ba44f51
Merge branch 'master' into multiple-credhelpers
coollog Feb 8, 2018
422c159
Changes credentialHelperNames to credHelpers.
coollog Feb 8, 2018
1fcee9d
Merge branch 'master' into multiple-credhelpers
coollog Feb 8, 2018
1a94f75
Merge branch 'master' into multiple-credhelpers
coollog Feb 8, 2018
7b0e1f5
Merge branch 'multiple-credhelpers' into maven-settings-server
coollog Feb 8, 2018
1119c6e
Removes NoRegistryCredentialsException.
coollog Feb 8, 2018
d6c994d
Merge branch 'master' into multiple-credhelpers
coollog Feb 8, 2018
7c0b533
Merge branch 'multiple-credhelpers' into maven-settings-server
coollog Feb 9, 2018
5734f05
Merge branch 'master' into maven-settings-server
coollog Feb 9, 2018
5ce6c0c
Uses Maven server settings as known credentials for registry.
coollog Feb 9, 2018
4c3bd30
Updates CHANGELOG.
coollog Feb 9, 2018
4b15908
Changes suggestion messages.
coollog Feb 9, 2018
da50314
Merge branch 'master' into maven-settings-server
coollog Feb 9, 2018
52d0221
Fixes comment.
coollog Feb 12, 2018
767a038
Fixes push to ECR.
coollog Feb 12, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ All notable changes to this project will be documented in this file.
- Simple example `helloworld` project under `examples/` ([#62](https://github.com/google/jib/pull/62))
- Better error messages when pushing an image manifest ([#63](https://github.com/google/jib/pull/63))
- Validates target image configuration ([#63](https://github.com/google/jib/pull/63))
- Configure multiple credential helpers with `credHelpers` ([#68](https://github.com/google/jib/pull/68))
- Configure registry credentials with Maven settings ([#81](https://github.com/google/jib/pull/81))

### Changed
- Configure multiple credential helpers with `credHelpers` ([#68](https://github.com/google/jib/pull/68))
- Removed configuration `credentialHelperName` ([#68](https://github.com/google/jib/pull/68))

### Fixed
- Build failure on Windows ([#74](https://github.com/google/jib/issues/74))
- Infers common credential helper names (for GCR and ECR) ([#64](https://github.com/google/jib/pull/64))
- Cannot use private base image ([#68](https://github.com/google/jib/pull/68))
- Building applications with no resources ([#73](https://github.com/google/jib/pull/73))
- Pushing to registries like Docker Hub and ACR ([#75](https://github.com/google/jib/issues/75))
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ public void testSteps() throws Exception {
SourceFilesConfiguration sourceFilesConfiguration = new TestSourceFilesConfiguration();
BuildConfiguration buildConfiguration =
BuildConfiguration.builder()
.setBaseImageServerUrl("gcr.io")
.setBaseImageName("distroless/java")
.setBaseImageRegistry("gcr.io")
.setBaseImageRepository("distroless/java")
.setBaseImageTag("latest")
.setTargetServerUrl("localhost:5000")
.setTargetImageName("testimage")
.setTargetRegistry("localhost:5000")
.setTargetRepository("testimage")
.setTargetTag("testtag")
.setMainClass("HelloWorld")
.setBuildLogger(new TestBuildLogger())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public void testGetRegistryAuthenticator()
RegistryClient registryClient =
new RegistryClient(null, "registry.hub.docker.com", "library/busybox");
RegistryAuthenticator registryAuthenticator = registryClient.getRegistryAuthenticator();
Authorization authorization = registryAuthenticator.authenticate();
Authorization authorization = registryAuthenticator.authenticatePull();

RegistryClient authorizedRegistryClient =
new RegistryClient(authorization, "registry.hub.docker.com", "library/busybox");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class RegistryAuthenticatorIntegrationTest {
public void testAuthenticate() throws RegistryAuthenticationFailedException {
RegistryAuthenticator registryAuthenticator =
RegistryAuthenticators.forDockerHub("library/busybox");
Authorization authorization = registryAuthenticator.authenticate();
Authorization authorization = registryAuthenticator.authenticatePull();

// Checks that some token was received.
Assert.assertTrue(0 < authorization.getToken().length());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,67 +19,52 @@
import com.google.cloud.tools.jib.Timer;
import com.google.cloud.tools.jib.http.Authorization;
import com.google.cloud.tools.jib.registry.RegistryAuthenticationFailedException;
import com.google.cloud.tools.jib.registry.RegistryAuthenticator;
import com.google.cloud.tools.jib.registry.RegistryAuthenticators;
import com.google.cloud.tools.jib.registry.RegistryException;
import com.google.cloud.tools.jib.registry.credentials.RegistryCredentials;
import com.google.common.util.concurrent.ListenableFuture;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import javax.annotation.Nullable;

/** Retrieves credentials to pull from the base image registry. */
/**
* Authenticates pull from the base image registry using Docker Token Authentication.
*
* @see <a
* href="https://docs.docker.com/registry/spec/auth/token/">https://docs.docker.com/registry/spec/auth/token/</a>
*/
class AuthenticatePullStep implements Callable<Authorization> {

private static final String DESCRIPTION = "Authenticating with base image registry";
private static final String DESCRIPTION = "Authenticating pull from %s";

private final BuildConfiguration buildConfiguration;
private final ListenableFuture<RegistryCredentials> registryCredentialsFuture;
private final ListenableFuture<Authorization> registryCredentialsFuture;

AuthenticatePullStep(
BuildConfiguration buildConfiguration,
ListenableFuture<RegistryCredentials> registryCredentialsFuture) {
ListenableFuture<Authorization> registryCredentialsFuture) {
this.buildConfiguration = buildConfiguration;
this.registryCredentialsFuture = registryCredentialsFuture;
}

/** Depends on nothing. */
/** Depends on {@link RetrieveRegistryCredentialsStep}. */
@Override
public Authorization call()
throws RegistryAuthenticationFailedException, IOException, RegistryException,
ExecutionException, InterruptedException {
try (Timer ignored = new Timer(buildConfiguration.getBuildLogger(), DESCRIPTION)) {
return RegistryAuthenticators.forOther(
buildConfiguration.getBaseImageServerUrl(), buildConfiguration.getBaseImageName())
.setAuthorization(getBaseImageAuthorization())
.authenticate();
try (Timer ignored =
new Timer(
buildConfiguration.getBuildLogger(),
String.format(DESCRIPTION, buildConfiguration.getBaseImageRegistry()))) {
Authorization registryCredentials = NonBlockingFutures.get(registryCredentialsFuture);
RegistryAuthenticator registryAuthenticator =
RegistryAuthenticators.forOther(
buildConfiguration.getBaseImageRegistry(),
buildConfiguration.getBaseImageRepository());
if (registryAuthenticator == null) {
return registryCredentials;
}
return registryAuthenticator.setAuthorization(registryCredentials).authenticatePull();
}
}

/** Attempts to retrieve authorization for pulling the base image. */
@Nullable
private Authorization getBaseImageAuthorization()
throws ExecutionException, InterruptedException {
RegistryCredentials registryCredentials = NonBlockingFutures.get(registryCredentialsFuture);
String registry = buildConfiguration.getBaseImageServerUrl();

String credentialHelperSuffix = registryCredentials.getCredentialHelperUsed(registry);
Authorization authorization = registryCredentials.getAuthorization(registry);
if (credentialHelperSuffix == null || authorization == null) {
/*
* If no credentials found, give an info (not warning because in most cases, the base image is
* public and does not need extra credentials) and return null.
*/
buildConfiguration
.getBuildLogger()
.info("No credentials could be retrieved for registry " + registry);
return null;
}

buildConfiguration
.getBuildLogger()
.info(
"Using docker-credential-" + credentialHelperSuffix + " for pulling from " + registry);
return authorization;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,52 +18,56 @@

import com.google.cloud.tools.jib.Timer;
import com.google.cloud.tools.jib.http.Authorization;
import com.google.cloud.tools.jib.registry.credentials.RegistryCredentials;
import com.google.cloud.tools.jib.registry.RegistryAuthenticationFailedException;
import com.google.cloud.tools.jib.registry.RegistryAuthenticator;
import com.google.cloud.tools.jib.registry.RegistryAuthenticators;
import com.google.cloud.tools.jib.registry.RegistryException;
import com.google.common.util.concurrent.ListenableFuture;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import javax.annotation.Nullable;

/** Retrieves credentials to push to a target registry. */
/**
* Authenticates push to a target registry using Docker Token Authentication.
*
* @see <a
* href="https://docs.docker.com/registry/spec/auth/token/">https://docs.docker.com/registry/spec/auth/token/</a>
*/
class AuthenticatePushStep implements Callable<Authorization> {

private static final String DESCRIPTION = "Authenticating with push to %s";

private final BuildConfiguration buildConfiguration;
private final ListenableFuture<RegistryCredentials> registryCredentialsFuture;
private final ListenableFuture<Authorization> registryCredentialsFuture;

AuthenticatePushStep(
BuildConfiguration buildConfiguration,
ListenableFuture<RegistryCredentials> registryCredentialsFuture) {
ListenableFuture<Authorization> registryCredentialsFuture) {
this.buildConfiguration = buildConfiguration;
this.registryCredentialsFuture = registryCredentialsFuture;
}

/** Depends on nothing. */
/** Depends on {@link RetrieveRegistryCredentialsStep}. */
@Override
@Nullable
public Authorization call() throws ExecutionException, InterruptedException {
public Authorization call()
throws ExecutionException, InterruptedException, RegistryAuthenticationFailedException,
IOException, RegistryException {
try (Timer ignored =
new Timer(
buildConfiguration.getBuildLogger(),
String.format(DESCRIPTION, buildConfiguration.getTargetServerUrl()))) {
RegistryCredentials registryCredentials = NonBlockingFutures.get(registryCredentialsFuture);
String registry = buildConfiguration.getTargetServerUrl();

String credentialHelperSuffix = registryCredentials.getCredentialHelperUsed(registry);
Authorization authorization = registryCredentials.getAuthorization(registry);
if (credentialHelperSuffix == null || authorization == null) {
// If no credentials found, give a warning and return null.
buildConfiguration
.getBuildLogger()
.warn("No credentials could be retrieved for registry " + registry);
return null;
String.format(DESCRIPTION, buildConfiguration.getTargetRegistry()))) {
Authorization registryCredentials = NonBlockingFutures.get(registryCredentialsFuture);
RegistryAuthenticator registryAuthenticator =
RegistryAuthenticators.forOther(
buildConfiguration.getTargetRegistry(), buildConfiguration.getTargetRepository());
if (registryAuthenticator == null) {
return registryCredentials;
}
buildConfiguration
.getBuildLogger()
.info(
"Using docker-credential-" + credentialHelperSuffix + " for pushing to " + registry);
return authorization;
return registryAuthenticator
.setAuthorization(NonBlockingFutures.get(registryCredentialsFuture))
.authenticatePush();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ private BlobDescriptor afterBaseImageLayerFuturesFuture()
RegistryClient registryClient =
new RegistryClient(
NonBlockingFutures.get(pushAuthorizationFuture),
buildConfiguration.getTargetServerUrl(),
buildConfiguration.getTargetImageName())
buildConfiguration.getTargetRegistry(),
buildConfiguration.getTargetRepository())
.setTimer(timer);

// Constructs the image.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,23 @@ public class BuildConfiguration {
@VisibleForTesting
enum Fields {
/** The server URL of the registry to pull the base image from. */
BASE_IMAGE_SERVER_URL(true),
BASE_IMAGE_REGISTRY(true),
/** The image name/repository of the base image (also known as the registry namespace). */
BASE_IMAGE_NAME(true),
BASE_IMAGE_REPOSITORY(true),
/** The base image tag. */
BASE_IMAGE_TAG(true),

/** The server URL of the registry to push the built image to. */
TARGET_SERVER_URL(true),
TARGET_REGISTRY(true),
/** The image name/repository of the built image (also known as the registry namespace). */
TARGET_IMAGE_NAME(true),
TARGET_REPOSITORY(true),
/** The image tag of the built image (the part after the colon). */
TARGET_TAG(true),

/** The credential helper names used by {@link RegistryCredentials}. */
CREDENTIAL_HELPER_NAMES(false),
/** Known registry credentials to fallback on. */
KNOWN_REGISTRY_CREDENTIALS(false),

/** The main class to use when running the application. */
MAIN_CLASS(true),
Expand Down Expand Up @@ -74,11 +76,11 @@ public static class Builder {
static final Map<Fields, String> FIELD_DESCRIPTIONS =
new EnumMap<Fields, String>(Fields.class) {
{
put(Fields.BASE_IMAGE_SERVER_URL, "base image registry server URL");
put(Fields.BASE_IMAGE_NAME, "base image name");
put(Fields.BASE_IMAGE_REGISTRY, "base image registry server URL");
put(Fields.BASE_IMAGE_REPOSITORY, "base image name");
put(Fields.BASE_IMAGE_TAG, "base image tag");
put(Fields.TARGET_SERVER_URL, "target registry server URL");
put(Fields.TARGET_IMAGE_NAME, "target image name");
put(Fields.TARGET_REGISTRY, "target registry server URL");
put(Fields.TARGET_REPOSITORY, "target image name");
put(Fields.TARGET_TAG, "target image tag");
put(Fields.CREDENTIAL_HELPER_NAMES, "credential helper names");
put(Fields.MAIN_CLASS, "main class");
Expand All @@ -96,6 +98,7 @@ public static class Builder {
private Builder() {
// Sets default empty values.
values.put(Fields.CREDENTIAL_HELPER_NAMES, Collections.emptyList());
values.put(Fields.KNOWN_REGISTRY_CREDENTIALS, RegistryCredentials.none());
values.put(Fields.JVM_FLAGS, Collections.emptyList());
values.put(Fields.ENVIRONMENT, Collections.emptyMap());
}
Expand All @@ -105,13 +108,13 @@ public Builder setBuildLogger(BuildLogger buildLogger) {
return this;
}

public Builder setBaseImageServerUrl(String baseImageServerUrl) {
values.put(Fields.BASE_IMAGE_SERVER_URL, baseImageServerUrl);
public Builder setBaseImageRegistry(String baseImageServerUrl) {
values.put(Fields.BASE_IMAGE_REGISTRY, baseImageServerUrl);
return this;
}

public Builder setBaseImageName(String baseImageName) {
values.put(Fields.BASE_IMAGE_NAME, baseImageName);
public Builder setBaseImageRepository(String baseImageName) {
values.put(Fields.BASE_IMAGE_REPOSITORY, baseImageName);
return this;
}

Expand All @@ -120,13 +123,13 @@ public Builder setBaseImageTag(String baseImageTag) {
return this;
}

public Builder setTargetServerUrl(String targetServerUrl) {
values.put(Fields.TARGET_SERVER_URL, targetServerUrl);
public Builder setTargetRegistry(String targetServerUrl) {
values.put(Fields.TARGET_REGISTRY, targetServerUrl);
return this;
}

public Builder setTargetImageName(String targetImageName) {
values.put(Fields.TARGET_IMAGE_NAME, targetImageName);
public Builder setTargetRepository(String targetImageName) {
values.put(Fields.TARGET_REPOSITORY, targetImageName);
return this;
}

Expand All @@ -142,6 +145,13 @@ public Builder setCredentialHelperNames(List<String> credentialHelperNames) {
return this;
}

public Builder setKnownRegistryCredentials(RegistryCredentials knownRegistryCredentials) {
if (knownRegistryCredentials != null) {
values.put(Fields.KNOWN_REGISTRY_CREDENTIALS, knownRegistryCredentials);
}
return this;
}

public Builder setMainClass(String mainClass) {
values.put(Fields.MAIN_CLASS, mainClass);
return this;
Expand Down Expand Up @@ -220,30 +230,34 @@ public BuildLogger getBuildLogger() {
return buildLogger;
}

public String getBaseImageServerUrl() {
return getFieldValue(Fields.BASE_IMAGE_SERVER_URL);
public String getBaseImageRegistry() {
return getFieldValue(Fields.BASE_IMAGE_REGISTRY);
}

public String getBaseImageName() {
return getFieldValue(Fields.BASE_IMAGE_NAME);
public String getBaseImageRepository() {
return getFieldValue(Fields.BASE_IMAGE_REPOSITORY);
}

public String getBaseImageTag() {
return getFieldValue(Fields.BASE_IMAGE_TAG);
}

public String getTargetServerUrl() {
return getFieldValue(Fields.TARGET_SERVER_URL);
public String getTargetRegistry() {
return getFieldValue(Fields.TARGET_REGISTRY);
}

public String getTargetImageName() {
return getFieldValue(Fields.TARGET_IMAGE_NAME);
public String getTargetRepository() {
return getFieldValue(Fields.TARGET_REPOSITORY);
}

public String getTargetTag() {
return getFieldValue(Fields.TARGET_TAG);
}

public RegistryCredentials getKnownRegistryCredentials() {
return getFieldValue(Fields.KNOWN_REGISTRY_CREDENTIALS);
}

public List<String> getCredentialHelperNames() {
return getFieldValue(Fields.CREDENTIAL_HELPER_NAMES);
}
Expand Down
Loading