public async Task <DescriptorDigest> HandleSuccessResponseAsync(HttpResponseMessage response) { // Checks if the image digest is as expected. DescriptorDigest expectedDigest = await Digests.ComputeJsonDigestAsync(manifestTemplate).ConfigureAwait(false); if (response.Headers.TryGetValues(RESPONSE_DIGEST_HEADER, out var receivedDigestEnum)) { var receivedDigests = receivedDigestEnum.ToList(); if (receivedDigests.Count == 1) { try { if (expectedDigest.Equals(DescriptorDigest.FromDigest(receivedDigests[0]))) { return(expectedDigest); } } catch (DigestException) { // Invalid digest. } } eventHandlers.Dispatch( LogEvent.Warn(MakeUnexpectedImageDigestWarning(expectedDigest, receivedDigests))); return(expectedDigest); } eventHandlers.Dispatch( LogEvent.Warn(MakeUnexpectedImageDigestWarning(expectedDigest, Array.Empty <string>()))); // The received digest is not as expected. Warns about this. return(expectedDigest); }
public async Task <BuildResult> CallAsync() { IReadOnlyList <BlobDescriptor> baseImageDescriptors = await pushBaseImageLayersStep.GetFuture().ConfigureAwait(false); IReadOnlyList <BlobDescriptor> appLayerDescriptors = await pushApplicationLayersStep.GetFuture().ConfigureAwait(false); BlobDescriptor containerConfigurationBlobDescriptor = await pushContainerConfigurationStep.GetFuture().ConfigureAwait(false); ImmutableHashSet <string> targetImageTags = buildConfiguration.GetAllTargetImageTags(); using (var progressEventDispatcher = progressEventDispatcherFactory.Create("pushing image manifest", this.Index)) using (var factory = progressEventDispatcher.NewChildProducer()("[child progress]pushing image manifest", targetImageTags.Count)) using (TimerEventDispatcher ignored = new TimerEventDispatcher(buildConfiguration.GetEventHandlers(), DESCRIPTION)) { RegistryClient registryClient = buildConfiguration .NewTargetImageRegistryClientFactory() .SetAuthorization(await authenticatePushStep.GetFuture().ConfigureAwait(false)) .NewRegistryClient(); // Constructs the image. ImageToJsonTranslator imageToJsonTranslator = new ImageToJsonTranslator(await buildImageStep.GetFuture().ConfigureAwait(false)); // Gets the image manifest to push. IBuildableManifestTemplate manifestTemplate = imageToJsonTranslator.GetManifestTemplate( buildConfiguration.GetTargetFormat(), containerConfigurationBlobDescriptor); // Pushes to all target image tags. IList <Task <DescriptorDigest> > pushAllTagsFutures = new List <Task <DescriptorDigest> >(); var idx = 0; ProgressEventDispatcher.Factory progressEventDispatcherFactory = factory.NewChildProducer(); foreach (string tag in targetImageTags) { idx++; using (progressEventDispatcherFactory.Create("tagging with " + tag, idx)) { buildConfiguration.GetEventHandlers().Dispatch(LogEvent.Info("Tagging with " + tag + "...")); pushAllTagsFutures.Add(registryClient.PushManifestAsync(manifestTemplate, tag)); } } DescriptorDigest imageDigest = await Digests.ComputeJsonDigestAsync(manifestTemplate).ConfigureAwait(false); DescriptorDigest imageId = containerConfigurationBlobDescriptor.GetDigest(); BuildResult result = new BuildResult(imageDigest, imageId); await Task.WhenAll(pushAllTagsFutures).ConfigureAwait(false); return(result); } }
public async Task TestGenerateSelectorAsync() { DescriptorDigest expectedSelector = await Digests.ComputeJsonDigestAsync(ToLayerEntryTemplates(inOrderLayerEntries)).ConfigureAwait(false); Assert.AreEqual( expectedSelector, await GenerateSelectorAsync(outOfOrderLayerEntries).ConfigureAwait(false)); }
public async Task TestGenerateSelector_emptyAsync() { DescriptorDigest expectedSelector = await Digests.ComputeJsonDigestAsync(ImmutableArray.Create <object>()).ConfigureAwait(false); Assert.AreEqual( expectedSelector, await GenerateSelectorAsync(ImmutableArray.Create <LayerEntry>()).ConfigureAwait(false)); }
public async Task TestPushAsync() { localRegistry.PullAndPushToLocal("busybox", "busybox"); IBlob testLayerBlob = Blobs.From("crepecake"); // Known digest for 'crepecake' DescriptorDigest testLayerBlobDigest = DescriptorDigest.FromHash( "52a9e4d4ba4333ce593707f98564fee1e6d898db0d3602408c0b2a6a424d357c"); IBlob testContainerConfigurationBlob = Blobs.From("12345"); DescriptorDigest testContainerConfigurationBlobDigest = DescriptorDigest.FromHash( "5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5"); // Creates a valid image manifest. V22ManifestTemplate expectedManifestTemplate = new V22ManifestTemplate(); expectedManifestTemplate.AddLayer(9, testLayerBlobDigest); expectedManifestTemplate.SetContainerConfiguration(5, testContainerConfigurationBlobDigest); // Pushes the BLOBs. RegistryClient registryClient = RegistryClient.CreateFactory(EVENT_HANDLERS, "localhost:5000", "testimage") .SetAllowInsecureRegistries(true) .NewRegistryClient(); Assert.IsFalse( await registryClient.PushBlobAsync(testLayerBlobDigest, testLayerBlob, null, _ => { }).ConfigureAwait(false)); Assert.IsFalse( await registryClient.PushBlobAsync( testContainerConfigurationBlobDigest, testContainerConfigurationBlob, null, _ => { }).ConfigureAwait(false)); // Pushes the manifest. DescriptorDigest imageDigest = await registryClient.PushManifestAsync(expectedManifestTemplate, "latest").ConfigureAwait(false); // Pulls the manifest. V22ManifestTemplate manifestTemplate = await registryClient.PullManifestAsync <V22ManifestTemplate>("latest").ConfigureAwait(false); Assert.AreEqual(1, manifestTemplate.Layers.Count); Assert.AreEqual(testLayerBlobDigest, manifestTemplate.Layers[0].Digest); Assert.IsNotNull(manifestTemplate.GetContainerConfiguration()); Assert.AreEqual( testContainerConfigurationBlobDigest, manifestTemplate.GetContainerConfiguration().Digest); // Pulls the manifest by digest. V22ManifestTemplate manifestTemplateByDigest = await registryClient.PullManifestAsync <V22ManifestTemplate>(imageDigest.ToString()).ConfigureAwait(false); Assert.AreEqual( await Digests.ComputeJsonDigestAsync(manifestTemplate).ConfigureAwait(false), await Digests.ComputeJsonDigestAsync(manifestTemplateByDigest).ConfigureAwait(false)); }
public async Task TestHandleResponse_noDigestAsync() { DescriptorDigest expectedDigest = await Digests.ComputeJsonDigestAsync(fakeManifestTemplate).ConfigureAwait(false); using (HttpResponseMessage mockResponse = new HttpResponseMessage { Headers = { { "Docker-Content-Digest", new List <string>() } } }) { Assert.AreEqual(expectedDigest, await testManifestPusher.HandleResponseAsync(mockResponse).ConfigureAwait(false)); Mock.Get(mockEventHandlers).Verify(m => m.Dispatch(LogEvent.Warn("Expected image digest " + expectedDigest + ", but received none"))); } }
public async Task TestHandleResponse_validAsync() { DescriptorDigest expectedDigest = await Digests.ComputeJsonDigestAsync(fakeManifestTemplate).ConfigureAwait(false); using (HttpResponseMessage mockResponse = new HttpResponseMessage { Headers = { { "Docker-Content-Digest", new List <string> { expectedDigest.ToString() } } } }) { Assert.AreEqual(expectedDigest, await testManifestPusher.HandleResponseAsync(mockResponse).ConfigureAwait(false)); } }
/** * Gets a {@link BuildResult} from an {@link Image}. * * @param image the image * @param targetFormat the target format of the image * @return a new {@link BuildResult} with the image's digest and id * @throws IOException if writing the digest or container configuration fails */ public static async Task <BuildResult> FromImageAsync(Image image, ManifestFormat targetFormat) { ImageToJsonTranslator imageToJsonTranslator = new ImageToJsonTranslator(image); ContainerConfigurationTemplate configurationTemplate = imageToJsonTranslator.GetContainerConfiguration(); BlobDescriptor containerConfigurationBlobDescriptor = await Digests.ComputeJsonDescriptorAsync(configurationTemplate).ConfigureAwait(false); IBuildableManifestTemplate manifestTemplate = imageToJsonTranslator.GetManifestTemplate( targetFormat, containerConfigurationBlobDescriptor); DescriptorDigest imageDigest = await Digests.ComputeJsonDigestAsync(manifestTemplate).ConfigureAwait(false); DescriptorDigest imageId = containerConfigurationBlobDescriptor.GetDigest(); return(new BuildResult(imageDigest, imageId)); }
/** * Generates a selector for the list of {@link LayerEntry}s. The selector is unique to each unique * set of layer entries, regardless of order. TODO: Should we care about order? * * @param layerEntries the layer entries * @return the selector * @throws IOException if an I/O exception occurs */ public static async Task <DescriptorDigest> GenerateSelectorAsync(ImmutableArray <LayerEntry> layerEntries) { return(await Digests.ComputeJsonDigestAsync(ToSortedJsonTemplates(layerEntries)).ConfigureAwait(false)); }