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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        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());
        }