public static async Task GenerateTemplateImageAsync(ImageInfo imageInfo, string accessToken, string templateFilePath) { AzureContainerRegistryClient acrClient = new AzureContainerRegistryClient(imageInfo.Registry, new AcrBasicToken(accessToken)); int schemaV2 = 2; string mediatypeV2Manifest = "application/vnd.docker.distribution.manifest.v2+json"; string mediatypeV1Manifest = "application/vnd.oci.image.config.v1+json"; string emptyConfigStr = "{}"; // Upload config blob byte[] originalConfigBytes = Encoding.UTF8.GetBytes(emptyConfigStr); using var originalConfigStream = new MemoryStream(originalConfigBytes); string originalConfigDigest = ComputeDigest(originalConfigStream); await UploadBlob(acrClient, originalConfigStream, imageInfo.ImageName, originalConfigDigest); // Upload memory blob List <Descriptor> layers = new List <Descriptor>(); using FileStream fileStream = File.OpenRead(templateFilePath); using MemoryStream byteStream = new MemoryStream(); fileStream.CopyTo(byteStream); var blobLength = byteStream.Length; string blobDigest = ComputeDigest(byteStream); await UploadBlob(acrClient, byteStream, imageInfo.ImageName, blobDigest); layers.Add(new Descriptor("application/vnd.oci.image.layer.v1.tar", blobLength, blobDigest)); // Push manifest var v2Manifest = new V2Manifest(schemaV2, mediatypeV2Manifest, new Descriptor(mediatypeV1Manifest, originalConfigBytes.Length, originalConfigDigest), layers); await acrClient.Manifests.CreateAsync(imageInfo.ImageName, imageInfo.Tag, v2Manifest); }
private async Task PushTemplateSet(ContainerRegistryInfo registry, string repository, string tag) { AzureContainerRegistryClient acrClient = new AzureContainerRegistryClient(registry.Server, new AcrBasicToken(registry)); int schemaV2 = 2; string mediatypeV2Manifest = "application/vnd.docker.distribution.manifest.v2+json"; string mediatypeV1Manifest = "application/vnd.oci.image.config.v1+json"; string emptyConfigStr = "{}"; // Upload config blob byte[] originalConfigBytes = Encoding.UTF8.GetBytes(emptyConfigStr); using var originalConfigStream = new MemoryStream(originalConfigBytes); string originalConfigDigest = ComputeDigest(originalConfigStream); await UploadBlob(acrClient, originalConfigStream, repository, originalConfigDigest); // Upload memory blob using Stream byteStream = Samples.GetDefaultConversionTemplates(); var blobLength = byteStream.Length; string blobDigest = ComputeDigest(byteStream); await UploadBlob(acrClient, byteStream, repository, blobDigest); // Push manifest List <Descriptor> layers = new List <Descriptor> { new Descriptor("application/vnd.oci.image.layer.v1.tar", blobLength, blobDigest), }; var v2Manifest = new V2Manifest(schemaV2, mediatypeV2Manifest, new Descriptor(mediatypeV1Manifest, originalConfigBytes.Length, originalConfigDigest), layers); await acrClient.Manifests.CreateAsync(repository, tag, v2Manifest); }
/// <summary> /// Uploads a specified image layer by layer from another local repository (Within the specific registry) /// </summary> private static async Task BuildImageInRepoAfterDownload(string origin, string output, string outputTag, AzureContainerRegistryClient client, CancellationToken ct) { V2Manifest manifest = (V2Manifest)await client.GetManifestAsync(origin, outputTag, "application/vnd.docker.distribution.manifest.v2+json", ct); var listOfActions = new List <Action>(); // Acquire and upload all layers for (int i = 0; i < manifest.Layers.Count; i++) { var cur = i; listOfActions.Add(() => { var progress = new ProgressBar(3); progress.Refresh(0, "Starting"); var layer = client.GetBlobAsync(origin, manifest.Layers[cur].Digest).GetAwaiter().GetResult(); progress.Next("Downloading " + manifest.Layers[cur].Digest + " layer from " + origin); string digestLayer = UploadLayer(layer, output, client).GetAwaiter().GetResult(); progress.Next("Uploading " + manifest.Layers[cur].Digest + " layer to " + output); manifest.Layers[cur].Digest = digestLayer; progress.Next("Uploaded " + manifest.Layers[cur].Digest + " layer to " + output); }); } // Acquire config Blob listOfActions.Add(() => { var progress = new ProgressBar(3); progress.Next("Downloading config blob from " + origin); var configBlob = client.GetBlobAsync(origin, manifest.Config.Digest).GetAwaiter().GetResult(); progress.Next("Uploading config blob to " + output); string digestConfig = UploadLayer(configBlob, output, client).GetAwaiter().GetResult(); progress.Next("Uploaded config blob to " + output); manifest.Config.Digest = digestConfig; }); var options = new ParallelOptions { MaxDegreeOfParallelism = MaxParallel }; Parallel.Invoke(options, listOfActions.ToArray()); Console.WriteLine("Pushing new manifest to " + output + ":" + outputTag); await client.CreateManifestAsync(output, outputTag, manifest, ct); Console.WriteLine("Successfully created " + output + ":" + outputTag); }
private static async Task CopyBaseImageLayers(ImageRef origin, ImageRef output, bool includeConfig) { AzureContainerRegistryClient originClient; if (!string.IsNullOrEmpty(origin.Username)) { var originCredentials = new AcrClientCredentials(AcrClientCredentials.LoginMode.Basic, origin.Registry, origin.Username, origin.Password); originClient = new AzureContainerRegistryClient(originCredentials) { LoginUri = origin.Registry }; } else { originClient = new AzureContainerRegistryClient(new TokenCredentials()) { LoginUri = "https://" + origin.Registry }; } var outputCredentials = new AcrClientCredentials(AcrClientCredentials.LoginMode.Basic, output.Registry, output.Username, output.Password); var outputClient = new AzureContainerRegistryClient(outputCredentials) { LoginUri = "https://" + output.Registry }; V2Manifest manifest = (V2Manifest)await originClient.GetManifestAsync(origin.Repository, origin.Tag, "application/vnd.docker.distribution.manifest.v2+json"); var listOfActions = new List <Action>(); // Acquire and upload all layers for (int i = 0; i < manifest.Layers.Count; i++) { var cur = i; listOfActions.Add(() => { var progress = new ProgressBar(3); progress.Refresh(0, "Starting"); var layer = originClient.GetBlobAsync(origin.Repository, manifest.Layers[cur].Digest).GetAwaiter().GetResult(); progress.Next("Downloading " + manifest.Layers[cur].Digest + " layer from " + origin); string digestLayer = UploadLayer(layer, output.Repository, outputClient).GetAwaiter().GetResult(); progress.Next("Uploading " + manifest.Layers[cur].Digest + " layer to " + output.Repository); progress.Next("Uploaded " + manifest.Layers[cur].Digest + " layer to " + output.Repository); }); } if (includeConfig) { // Acquire config Blob listOfActions.Add(() => { var progress = new ProgressBar(3); progress.Next("Downloading config blob from " + origin.Repository); var configBlob = originClient.GetBlobAsync(origin.Repository, manifest.Config.Digest).GetAwaiter().GetResult(); progress.Next("Uploading config blob to " + output.Repository); string digestConfig = UploadLayer(configBlob, output.Repository, outputClient).GetAwaiter().GetResult(); progress.Next("Uploaded config blob to " + output); }); } var options = new ParallelOptions { MaxDegreeOfParallelism = MaxParallel }; Parallel.Invoke(options, listOfActions.ToArray()); }