use of com.google.cloud.tools.jib.builder.TimerEventDispatcher in project jib by GoogleContainerTools.
the class PullBaseImageStep method tryMirrors.
@VisibleForTesting
Optional<ImagesAndRegistryClient> tryMirrors(BuildContext buildContext, ProgressEventDispatcher.Factory progressDispatcherFactory) throws LayerCountMismatchException, BadContainerConfigurationFormatException {
EventHandlers eventHandlers = buildContext.getEventHandlers();
Collection<Map.Entry<String, String>> mirrorEntries = buildContext.getRegistryMirrors().entries();
try (ProgressEventDispatcher progressDispatcher1 = progressDispatcherFactory.create("trying mirrors", mirrorEntries.size());
TimerEventDispatcher ignored1 = new TimerEventDispatcher(eventHandlers, "trying mirrors")) {
for (Map.Entry<String, String> entry : mirrorEntries) {
String registry = entry.getKey();
String mirror = entry.getValue();
eventHandlers.dispatch(LogEvent.debug("mirror config: " + registry + " --> " + mirror));
if (!buildContext.getBaseImageConfiguration().getImageRegistry().equals(registry)) {
progressDispatcher1.dispatchProgress(1);
continue;
}
eventHandlers.dispatch(LogEvent.info("trying mirror " + mirror + " for the base image"));
try (ProgressEventDispatcher progressDispatcher2 = progressDispatcher1.newChildProducer().create("trying mirror " + mirror, 2)) {
RegistryClient registryClient = buildContext.newBaseImageRegistryClientFactory(mirror).newRegistryClient();
List<Image> images = pullPublicImages(registryClient, progressDispatcher2);
eventHandlers.dispatch(LogEvent.info("pulled manifest from mirror " + mirror));
return Optional.of(new ImagesAndRegistryClient(images, registryClient));
} catch (IOException | RegistryException ex) {
// Ignore errors from this mirror and continue.
eventHandlers.dispatch(LogEvent.debug("failed to get manifest from mirror " + mirror + ": " + ex.getMessage()));
}
}
return Optional.empty();
}
}
use of com.google.cloud.tools.jib.builder.TimerEventDispatcher in project jib by GoogleContainerTools.
the class PullBaseImageStep method call.
@Override
public ImagesAndRegistryClient call() throws IOException, RegistryException, LayerPropertyNotFoundException, LayerCountMismatchException, BadContainerConfigurationFormatException, CacheCorruptedException, CredentialRetrievalException {
EventHandlers eventHandlers = buildContext.getEventHandlers();
try (ProgressEventDispatcher progressDispatcher = progressDispatcherFactory.create("pulling base image manifest", 4);
TimerEventDispatcher ignored1 = new TimerEventDispatcher(eventHandlers, DESCRIPTION)) {
// Skip this step if this is a scratch image
ImageReference imageReference = buildContext.getBaseImageConfiguration().getImage();
if (imageReference.isScratch()) {
Set<Platform> platforms = buildContext.getContainerConfiguration().getPlatforms();
Verify.verify(!platforms.isEmpty());
eventHandlers.dispatch(LogEvent.progress("Getting scratch base image..."));
ImmutableList.Builder<Image> images = ImmutableList.builder();
for (Platform platform : platforms) {
Image.Builder imageBuilder = Image.builder(buildContext.getTargetFormat());
imageBuilder.setArchitecture(platform.getArchitecture()).setOs(platform.getOs());
images.add(imageBuilder.build());
}
return new ImagesAndRegistryClient(images.build(), null);
}
eventHandlers.dispatch(LogEvent.progress("Getting manifest for base image " + imageReference + "..."));
if (buildContext.isOffline()) {
List<Image> images = getCachedBaseImages();
if (!images.isEmpty()) {
return new ImagesAndRegistryClient(images, null);
}
throw new IOException("Cannot run Jib in offline mode; " + imageReference + " not found in local Jib cache");
} else if (imageReference.getDigest().isPresent()) {
List<Image> images = getCachedBaseImages();
if (!images.isEmpty()) {
RegistryClient noAuthRegistryClient = buildContext.newBaseImageRegistryClientFactory().newRegistryClient();
// https://github.com/GoogleContainerTools/jib/issues/2220
return new ImagesAndRegistryClient(images, noAuthRegistryClient);
}
}
Optional<ImagesAndRegistryClient> mirrorPull = tryMirrors(buildContext, progressDispatcher.newChildProducer());
if (mirrorPull.isPresent()) {
return mirrorPull.get();
}
try {
// First, try with no credentials. This works with public GCR images (but not Docker Hub).
// TODO: investigate if we should just pass credentials up front. However, this involves
// some risk. https://github.com/GoogleContainerTools/jib/pull/2200#discussion_r359069026
// contains some related discussions.
RegistryClient noAuthRegistryClient = buildContext.newBaseImageRegistryClientFactory().newRegistryClient();
return new ImagesAndRegistryClient(pullBaseImages(noAuthRegistryClient, progressDispatcher.newChildProducer()), noAuthRegistryClient);
} catch (RegistryUnauthorizedException ex) {
eventHandlers.dispatch(LogEvent.lifecycle("The base image requires auth. Trying again for " + imageReference + "..."));
Credential credential = RegistryCredentialRetriever.getBaseImageCredential(buildContext).orElse(null);
RegistryClient registryClient = buildContext.newBaseImageRegistryClientFactory().setCredential(credential).newRegistryClient();
String wwwAuthenticate = ex.getHttpResponseException().getHeaders().getAuthenticate();
if (wwwAuthenticate != null) {
eventHandlers.dispatch(LogEvent.debug("WWW-Authenticate for " + imageReference + ": " + wwwAuthenticate));
registryClient.authPullByWwwAuthenticate(wwwAuthenticate);
return new ImagesAndRegistryClient(pullBaseImages(registryClient, progressDispatcher.newChildProducer()), registryClient);
} else {
// TODO: consider removing this fallback branch.
if (credential != null && !credential.isOAuth2RefreshToken()) {
eventHandlers.dispatch(LogEvent.debug("Trying basic auth as fallback for " + imageReference + "..."));
registryClient.configureBasicAuth();
try {
return new ImagesAndRegistryClient(pullBaseImages(registryClient, progressDispatcher.newChildProducer()), registryClient);
} catch (RegistryUnauthorizedException ignored) {
// Fall back to try bearer auth.
}
}
eventHandlers.dispatch(LogEvent.debug("Trying bearer auth as fallback for " + imageReference + "..."));
registryClient.doPullBearerAuth();
return new ImagesAndRegistryClient(pullBaseImages(registryClient, progressDispatcher.newChildProducer()), registryClient);
}
}
}
}
use of com.google.cloud.tools.jib.builder.TimerEventDispatcher in project jib by GoogleContainerTools.
the class PushBlobStep method call.
@Override
public BlobDescriptor call() throws IOException, RegistryException {
EventHandlers eventHandlers = buildContext.getEventHandlers();
DescriptorDigest blobDigest = blobDescriptor.getDigest();
try (ProgressEventDispatcher progressEventDispatcher = progressEventDispatcherFactory.create("pushing blob " + blobDigest, blobDescriptor.getSize());
TimerEventDispatcher ignored = new TimerEventDispatcher(eventHandlers, DESCRIPTION + blobDescriptor);
ThrottledAccumulatingConsumer throttledProgressReporter = new ThrottledAccumulatingConsumer(progressEventDispatcher::dispatchProgress)) {
// check if the BLOB is available
if (!forcePush && registryClient.checkBlob(blobDigest).isPresent()) {
eventHandlers.dispatch(LogEvent.info("Skipping push; BLOB already exists on target registry : " + blobDescriptor));
return blobDescriptor;
}
// If base and target images are in the same registry, then use mount/from to try mounting the
// BLOB from the base image repository to the target image repository and possibly avoid
// having to push the BLOB. See
// https://docs.docker.com/registry/spec/api/#cross-repository-blob-mount for details.
String baseRegistry = buildContext.getBaseImageConfiguration().getImageRegistry();
String baseRepository = buildContext.getBaseImageConfiguration().getImageRepository();
String targetRegistry = buildContext.getTargetImageConfiguration().getImageRegistry();
String sourceRepository = targetRegistry.equals(baseRegistry) ? baseRepository : null;
registryClient.pushBlob(blobDigest, blob, sourceRepository, throttledProgressReporter);
return blobDescriptor;
}
}
use of com.google.cloud.tools.jib.builder.TimerEventDispatcher in project jib by GoogleContainerTools.
the class PushImageStep method makeListForManifestList.
static ImmutableList<PushImageStep> makeListForManifestList(BuildContext buildContext, ProgressEventDispatcher.Factory progressEventDispatcherFactory, RegistryClient registryClient, ManifestTemplate manifestList, boolean manifestListAlreadyExists) throws IOException {
Set<String> tags = buildContext.getAllTargetImageTags();
EventHandlers eventHandlers = buildContext.getEventHandlers();
try (TimerEventDispatcher ignored = new TimerEventDispatcher(eventHandlers, "Preparing manifest list pushers");
ProgressEventDispatcher progressEventDispatcher = progressEventDispatcherFactory.create("launching manifest list pushers", tags.size())) {
boolean singlePlatform = buildContext.getContainerConfiguration().getPlatforms().size() == 1;
if (singlePlatform) {
// single image; no need to push a manifest list
return ImmutableList.of();
}
if (JibSystemProperties.skipExistingImages() && manifestListAlreadyExists) {
eventHandlers.dispatch(LogEvent.info("Skipping pushing manifest list; already exists."));
return ImmutableList.of();
}
DescriptorDigest manifestListDigest = Digests.computeJsonDigest(manifestList);
return tags.stream().map(tag -> new PushImageStep(buildContext, progressEventDispatcher.newChildProducer(), registryClient, manifestList, tag, manifestListDigest, // return value and type.
manifestListDigest)).collect(ImmutableList.toImmutableList());
}
}
use of com.google.cloud.tools.jib.builder.TimerEventDispatcher in project jib by GoogleContainerTools.
the class PushImageStep method makeList.
static ImmutableList<PushImageStep> makeList(BuildContext buildContext, ProgressEventDispatcher.Factory progressEventDispatcherFactory, RegistryClient registryClient, BlobDescriptor containerConfigurationDigestAndSize, Image builtImage, boolean manifestAlreadyExists) throws IOException {
// Gets the image manifest to push.
BuildableManifestTemplate manifestTemplate = new ImageToJsonTranslator(builtImage).getManifestTemplate(buildContext.getTargetFormat(), containerConfigurationDigestAndSize);
DescriptorDigest manifestDigest = Digests.computeJsonDigest(manifestTemplate);
Set<String> imageQualifiers = getImageQualifiers(buildContext, builtImage, manifestDigest);
EventHandlers eventHandlers = buildContext.getEventHandlers();
try (TimerEventDispatcher ignored = new TimerEventDispatcher(eventHandlers, "Preparing manifest pushers");
ProgressEventDispatcher progressDispatcher = progressEventDispatcherFactory.create("launching manifest pushers", imageQualifiers.size())) {
if (JibSystemProperties.skipExistingImages() && manifestAlreadyExists) {
eventHandlers.dispatch(LogEvent.info("Skipping pushing manifest; already exists."));
return ImmutableList.of();
}
return imageQualifiers.stream().map(qualifier -> new PushImageStep(buildContext, progressDispatcher.newChildProducer(), registryClient, manifestTemplate, qualifier, manifestDigest, containerConfigurationDigestAndSize.getDigest())).collect(ImmutableList.toImmutableList());
}
}
Aggregations