use of com.google.cloud.tools.jib.builder.TimerEventDispatcher in project jib by google.
the class RegistryClient method pushBlob.
/**
* Pushes the BLOB. If the {@code sourceRepository} is provided then the remote registry may skip
* if the BLOB already exists on the registry.
*
* @param blobDigest the digest of the BLOB, used for existence-check
* @param blob the BLOB to push
* @param sourceRepository if pushing to the same registry then the source image, or {@code null}
* otherwise; used to optimize the BLOB push
* @param writtenByteCountListener listens on byte count written to the registry during the push
* @return {@code true} if the BLOB already exists on the registry and pushing was skipped; false
* if the BLOB was pushed
* @throws IOException if communicating with the endpoint fails
* @throws RegistryException if communicating with the endpoint fails
*/
public boolean pushBlob(DescriptorDigest blobDigest, Blob blob, @Nullable String sourceRepository, Consumer<Long> writtenByteCountListener) throws IOException, RegistryException {
if (isBearerAuth(authorization.get()) && readOnlyBearerAuth) {
throw new IllegalStateException("push may fail with pull-only bearer auth token");
}
if (sourceRepository != null && !(JibSystemProperties.useCrossRepositoryBlobMounts() && canAttemptBlobMount(authorization.get(), sourceRepository))) {
// don't bother requesting a cross-repository blob-mount if we don't have access
sourceRepository = null;
}
BlobPusher blobPusher = new BlobPusher(registryEndpointRequestProperties, blobDigest, blob, sourceRepository);
try (TimerEventDispatcher timerEventDispatcher = new TimerEventDispatcher(eventHandlers, "pushBlob")) {
try (TimerEventDispatcher timerEventDispatcher2 = timerEventDispatcher.subTimer("pushBlob POST " + blobDigest)) {
// POST /v2/<name>/blobs/uploads/?mount={blob.digest}&from={sourceRepository}
// POST /v2/<name>/blobs/uploads/
Optional<URL> patchLocation = callRegistryEndpoint(blobPusher.initializer());
if (!patchLocation.isPresent()) {
// The BLOB exists already.
return true;
}
timerEventDispatcher2.lap("pushBlob PATCH " + blobDigest);
// PATCH <Location> with BLOB
URL putLocation = callRegistryEndpoint(blobPusher.writer(patchLocation.get(), writtenByteCountListener));
timerEventDispatcher2.lap("pushBlob PUT " + blobDigest);
// PUT <Location>?digest={blob.digest}
callRegistryEndpoint(blobPusher.committer(putLocation));
return false;
}
}
}
use of com.google.cloud.tools.jib.builder.TimerEventDispatcher in project jib by google.
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 google.
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 google.
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());
}
}
use of com.google.cloud.tools.jib.builder.TimerEventDispatcher in project jib by google.
the class BuildManifestListOrSingleManifestStep method call.
@Override
public ManifestTemplate call() throws IOException {
Preconditions.checkState(!builtImages.isEmpty(), "no images given");
EventHandlers eventHandlers = buildContext.getEventHandlers();
try (TimerEventDispatcher ignored = new TimerEventDispatcher(eventHandlers, DESCRIPTION);
ProgressEventDispatcher ignored2 = progressEventDispatcherFactory.create("building a manifest list or a single manifest", 1)) {
if (builtImages.size() == 1) {
eventHandlers.dispatch(LogEvent.info("Building a single manifest"));
ImageToJsonTranslator imageTranslator = new ImageToJsonTranslator(builtImages.get(0));
BlobDescriptor configDescriptor = Digests.computeDigest(imageTranslator.getContainerConfiguration());
return imageTranslator.getManifestTemplate(buildContext.getTargetFormat(), configDescriptor);
}
eventHandlers.dispatch(LogEvent.info("Building a manifest list"));
return new ManifestListGenerator(builtImages).getManifestListTemplate(buildContext.getTargetFormat());
}
}
Aggregations