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);
        }
 public ContainerRegistryDataPlaneClient(IAzureContext context)
 {
     _clientCredential = AzureSession.Instance.AuthenticationFactory.GetServiceClientCredentials(context, AzureEnvironment.Endpoint.ResourceManager);
     _accessToken      = AzureSession.Instance.AuthenticationFactory.Authenticate(context.Account, context.Environment, context.Tenant.Id, null, ShowDialog.Never, null, context.Environment.GetTokenAudience(AzureEnvironment.Endpoint.ResourceManager));
     _suffix           = context.Environment.ContainerRegistryEndpointSuffix;
     _client           = AzureSession.Instance.ClientFactory.CreateCustomArmClient <AzureContainerRegistryClient>(_clientCredential);
 }
        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);
        }
Ejemplo n.º 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="loginServer"></param>
        /// <returns></returns>
        public static async ValueTask <AcrRepository[]> LoadAsync(string userName, string password, string loginServer)
        {
            //--- create client
            var credentials = new BasicAuthenticationCredentials
            {
                UserName = userName.Trim(),
                Password = password.Trim(),
            };
            var client = new AzureContainerRegistryClient(credentials)
            {
                BaseUri = new Uri($"https://{loginServer.Trim()}"),
            };

            //--- load reposigories
            var names = (await client.GetRepositoriesAsync().ConfigureAwait(false)).Names;

            return((await names
                    .Select(async x =>
            {
                var manifests
                    = (await client.GetAcrManifestsAsync(x).ConfigureAwait(false))
                      .Manifests
                      .OrderByDescending(y => y.CreatedTime)
                      .Select(y => new AcrManifest(y))
                      .ToArray();
                return new AcrRepository(x, manifests);
            })
                    .WhenAll()
                    .ConfigureAwait(false))
                   .OrderBy(x => x.Name)
                   .ToArray());
        }
Ejemplo n.º 5
0
        private static AzureContainerRegistryClient LoginBasic(CancellationToken ct, string username, string password, string loginUrl)
        {
            AcrClientCredentials         credentials = new AcrClientCredentials(AcrClientCredentials.LoginMode.Basic, loginUrl, username, password, ct);
            AzureContainerRegistryClient client      = new AzureContainerRegistryClient(credentials);

            client.LoginUri = "https://" + loginUrl;
            return(client);
        }
Ejemplo n.º 6
0
        static void Main()
        {
            int timeoutInMilliseconds           = 1500000;
            CancellationToken            ct     = new CancellationTokenSource(timeoutInMilliseconds).Token;
            AzureContainerRegistryClient client = LoginBasic(ct);

            BuildImageInRepoAfterDownload(RepoOrigin, RepoOutput, OutputTag, client, ct).GetAwaiter().GetResult();
        }
Ejemplo n.º 7
0
        public ContainerRegistryDataPlaneClient(IAzureContext context, string acrTokenCacheKey)
        {
            _context = context;
            _suffix  = _context.Environment.ContainerRegistryEndpointSuffix;
            ServiceClientCredentials clientCredential = AzureSession.Instance.AuthenticationFactory.GetServiceClientCredentials(_accessToken, () => _accessToken);

            _client           = AzureSession.Instance.ClientFactory.CreateCustomArmClient <AzureContainerRegistryClient>(clientCredential);
            _acrTokenCacheKey = acrTokenCacheKey;
        }
        private static async Task UploadBlob(AzureContainerRegistryClient acrClient, Stream stream, string repository, string digest)
        {
            stream.Position = 0;
            var uploadInfo = await acrClient.Blob.StartUploadAsync(repository);

            var uploadedLayer = await acrClient.Blob.UploadAsync(stream, uploadInfo.Location);

            await acrClient.Blob.EndUploadAsync(digest, uploadedLayer.Location);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Example Credentials provisioning (Using Basic Authentication)
        /// </summary>
        private static AzureContainerRegistryClient LoginBasic(CancellationToken ct)
        {
            AcrClientCredentials         credentials = new AcrClientCredentials(AcrClientCredentials.LoginMode.Basic, Registry, Username, Password, ct);
            AzureContainerRegistryClient client      = new AzureContainerRegistryClient(credentials)
            {
                LoginUri = "https://csharpsdkblobtest.azurecr.io"
            };

            return(client);
        }
Ejemplo n.º 10
0
        public async Task GetAcrAccessTokenFromLogin()
        {
            using (var context = MockContext.Start(GetType(), nameof(GetAcrAccessTokenFromLogin)))
            {
                AzureContainerRegistryClient client = await ACRTestUtil.GetACRClientAsync(context, ACRTestUtil.ManagedTestRegistry);

                var accessToken = await client.AccessTokens.GetFromLoginAsync(ACRTestUtil.ManagedTestRegistryFullName, ACRTestUtil.Scope);

                ValidateAccessToken(accessToken.AccessTokenProperty);
            }
        }
Ejemplo n.º 11
0
        public async Task GetAcrRefreshTokenFromExchange()
        {
            using (var context = MockContext.Start(GetType(), nameof(GetAcrRefreshTokenFromExchange)))
            {
                AzureContainerRegistryClient client = await ACRTestUtil.GetACRClientAsync(context, ACRTestUtil.ManagedTestRegistry);

                var refreshToken = await client.RefreshTokens.GetFromExchangeAsync("access_token", ACRTestUtil.ManagedTestRegistryFullName, null, null, await ACRTestUtil.GetAADAccessToken());

                ValidateRefreshToken(refreshToken.RefreshTokenProperty);
            }
        }
Ejemplo n.º 12
0
        public async Task CancelBlobUpload()
        {
            using (var context = MockContext.Start(GetType(), nameof(CancelBlobUpload)))
            {
                AzureContainerRegistryClient client = await ACRTestUtil.GetACRClientAsync(context, ACRTestUtil.ManagedTestRegistryForChanges);

                var uploadInfo = await client.Blob.StartUploadAsync(ACRTestUtil.changeableRepository);

                await client.Blob.CancelUploadAsync(uploadInfo.Location);
            }
        }
Ejemplo n.º 13
0
        public async Task CheckBlob()
        {
            using (var context = MockContext.Start(GetType(), nameof(CheckBlob)))
            {
                AzureContainerRegistryClient client = await ACRTestUtil.GetACRClientAsync(context, ACRTestUtil.ManagedTestRegistry);

                var blob = await client.Blob.CheckAsync(ACRTestUtil.ProdRepository, ProdConfigBlobDigest);

                Assert.Equal(blob.DockerContentDigest, ProdConfigBlobDigest);
                Assert.Equal(5635, blob.ContentLength);
            }
        }
Ejemplo n.º 14
0
        public async Task CheckBlobChunk()
        {
            using (var context = MockContext.Start(GetType(), nameof(CheckBlobChunk)))
            {
                AzureContainerRegistryClient client = await ACRTestUtil.GetACRClientAsync(context, ACRTestUtil.ManagedTestRegistry);

                var blobData = await client.Blob.CheckChunkAsync(ACRTestUtil.ProdRepository, ProdConfigBlobDigest, "bytes=0-300");

                //Range is actually ignored in this request. Ends up working quite similarly to CheckBlob
                Assert.Equal(5635, blobData.ContentLength);
            }
        }
Ejemplo n.º 15
0
        private static async System.Threading.Tasks.Task DeleteImageAsync(
            ContainerRegistryImageDeletedEventData deleteEvent,
            AppConfiguration configuration,
            ILogger log)
        {
            // Create the resourceId from the target ACR resourceId string
            var targetACRResourceId = ResourceId.FromString(configuration.TargetACRResourceId);

            // Create Azure credentials to talk to target Cloud using the Active directory application
            var credential = new AzureCredentials(
                new ServicePrincipalLoginInformation
            {
                ClientId     = configuration.TargetAzureServicePrincipalClientId,
                ClientSecret = configuration.TargetAzureServicePrincipalClientKey
            },
                configuration.TargetAzureServicePrincipalTenantId,
                AzureEnvironment.FromName(configuration.TargetAzureEnvironmentName))
                             .WithDefaultSubscription(targetACRResourceId.SubscriptionId);

            var builder = RestClient
                          .Configure()
                          .WithEnvironment(AzureEnvironment.FromName(configuration.TargetAzureEnvironmentName))
                          .WithCredentials(credential)
                          .Build();

            // Create ACR management client using the Azure credentials
            var _registryClient = new ContainerRegistryManagementClient(builder);

            _registryClient.SubscriptionId = targetACRResourceId.SubscriptionId;

            // Fetch the target ACR properties to identify its login server.
            var targetRegistry = await _registryClient.Registries.GetAsync(
                resourceGroupName : targetACRResourceId.ResourceGroupName,
                registryName : targetACRResourceId.Name) ??
                                 throw new InvalidOperationException($"'{configuration.TargetACRResourceId}' is not found");

            // Create ACR data plane client using the Azure credentials
            var registryCredentials = new ContainerRegistryCredentials(
                ContainerRegistryCredentials.LoginMode.TokenAuth,
                targetRegistry.LoginServer,
                configuration.TargetAzureServicePrincipalClientId,
                configuration.TargetAzureServicePrincipalClientKey);

            var client = new AzureContainerRegistryClient(registryCredentials);

            // Invoke Delete of the image that is part of the delete event on the target ACR.
            await client.Manifests.DeleteAsync(
                name : deleteEvent.Target.Repository,
                reference : deleteEvent.Target.Digest);

            log.LogInformation($"Image '{deleteEvent.Target.Repository}:@{deleteEvent.Target.Digest}' deleted from registry '{configuration.TargetACRResourceId}'");
        }
Ejemplo n.º 16
0
        public async Task GetBlob()
        {
            using (var context = MockContext.Start(GetType(), nameof(GetBlob)))
            {
                AzureContainerRegistryClient client = await ACRTestUtil.GetACRClientAsync(context, ACRTestUtil.ManagedTestRegistry);

                Stream blob = await client.Blob.GetAsync(ACRTestUtil.ProdRepository, ProdConfigBlobDigest);

                StreamReader reader       = new StreamReader(blob, Encoding.UTF8);
                string       originalBlob = reader.ReadToEnd();
                Assert.Equal(ProdConfigBlob, originalBlob);
            }
        }
Ejemplo n.º 17
0
        public async Task GetBlobOAuth()
        {
            using (var context = MockContext.Start(GetType(), nameof(GetBlobOAuth)))
            {
                LoginMode loginMode = LoginMode.TokenAuth; // use oauth - exchange username and password for a refreshtoken
                AzureContainerRegistryClient client = await ACRTestUtil.GetACRClientAsync(context, ACRTestUtil.ManagedTestRegistry, loginMode);

                Stream blob = await client.Blob.GetAsync(ACRTestUtil.ProdRepository, ProdConfigBlobDigest);

                StreamReader reader       = new StreamReader(blob, Encoding.UTF8);
                string       originalBlob = reader.ReadToEnd();
                Assert.Equal(ProdConfigBlob, originalBlob);
            }
        }
Ejemplo n.º 18
0
        public async Task DeleteBlob()
        {
            using (var context = MockContext.Start(GetType(), nameof(DeleteBlob)))
            {
                AzureContainerRegistryClient client = await ACRTestUtil.GetACRClientAsync(context, ACRTestUtil.ManagedTestRegistryForChanges);

                string digest = await UploadLayer(GenerateStreamFromString("Testdata"), client, ACRTestUtil.BlobTestRepository);

                await client.Blob.DeleteAsync(ACRTestUtil.BlobTestRepository, digest);

                // Should not find layer
                Assert.Throws <AcrErrorsException>(() => { client.Blob.CheckAsync(ACRTestUtil.BlobTestRepository, digest).GetAwaiter().GetResult(); }); // Should error
            }
        }
Ejemplo n.º 19
0
        public async Task UploadLayerNext()
        {
            using (var context = MockContext.Start(GetType(), nameof(UploadLayerNext)))
            {
                AzureContainerRegistryClient client = await ACRTestUtil.GetACRClientAsync(context, ACRTestUtil.ManagedTestRegistry);

                string digest = await UploadLayer(GenerateStreamFromString("SomethingElse"), client, ACRTestUtil.BlobTestRepository);

                var blob = await client.Blob.GetAsync(ACRTestUtil.BlobTestRepository, digest);

                StreamReader reader = new StreamReader(blob, Encoding.UTF8);
                Assert.Equal("SomethingElse", reader.ReadToEnd());
            }
        }
Ejemplo n.º 20
0
        public async Task GetBlobStatus()
        {
            using (var context = MockContext.Start(GetType(), nameof(GetBlobStatus)))
            {
                AzureContainerRegistryClient client = await ACRTestUtil.GetACRClientAsync(context, ACRTestUtil.ManagedTestRegistry);

                var uploadInfo = await client.Blob.StartUploadAsync(ACRTestUtil.BlobTestRepository);

                var status = await client.Blob.GetStatusAsync(uploadInfo.Location.Substring(1));

                Assert.Equal(uploadInfo.DockerUploadUUID, status.DockerUploadUUID);
                Assert.Equal("0-0", status.Range);
                await client.Blob.CancelUploadAsync(uploadInfo.Location);
            }
        }
Ejemplo n.º 21
0
        public async Task MountBlob()
        {
            using (var context = MockContext.Start(GetType(), nameof(MountBlob)))
            {
                AzureContainerRegistryClient client = await ACRTestUtil.GetACRClientAsync(context, ACRTestUtil.ManagedTestRegistryForChanges);

                var res = await client.Blob.MountAsync("somethingnew", "doundo/bash", "sha256:16463e0c481e161aabb735437d30b3c9c7391c2747cc564bb927e843b73dcb39");

                Stream blob = await client.Blob.GetAsync("somethingnew", "sha256:16463e0c481e161aabb735437d30b3c9c7391c2747cc564bb927e843b73dcb39");

                StreamReader reader       = new StreamReader(blob, Encoding.UTF8);
                string       originalBlob = reader.ReadToEnd();
                Assert.Equal(ProdConfigBlob, originalBlob);
            }
        }
Ejemplo n.º 22
0
        private async Task <string> UploadLayer(Stream blob, AzureContainerRegistryClient client, string repository)
        {
            // Make copy to obtain the ability to rewind the stream
            Stream cpy = new MemoryStream();

            blob.CopyTo(cpy);
            cpy.Position = 0;

            string digest = ComputeDigest(cpy);

            cpy.Position = 0;

            var uploadInfo = await client.Blob.StartUploadAsync(repository);

            var uploadedLayer = await client.Blob.UploadAsync(cpy, uploadInfo.Location);

            var uploadedLayerEnd = await client.Blob.EndUploadAsync(digest, uploadedLayer.Location);

            return(uploadedLayerEnd.DockerContentDigest);
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Upload a layer using the nextLink properties internally. Very clean and simple to use overall.
        /// </summary>
        private static async Task <string> UploadLayer(Stream blob, string repo, AzureContainerRegistryClient client)
        {
            // Make copy to obtain the ability to rewind the stream
            Stream cpy = new MemoryStream();

            blob.CopyTo(cpy);
            cpy.Position = 0;

            string digest = ComputeDigest(cpy);

            cpy.Position = 0;

            var uploadInfo = await client.StartEmptyResumableBlobUploadAsync(repo);

            var uploadedLayer = await client.UploadBlobContentFromNextAsync(cpy, uploadInfo.Location.Substring(1));

            var uploadedLayerEnd = await client.EndBlobUploadFromNextAsync(digest, uploadedLayer.Location.Substring(1));

            return(digest);
        }
Ejemplo n.º 24
0
        static void Main(string[] args)
        {
            string               username = "******";
            string               password = "";
            string               loginUrl = "acryihchentest0611.azurecr.io";
            int                  timeoutInMilliseconds = 15000;
            CancellationToken    ct = new CancellationTokenSource(timeoutInMilliseconds).Token;
            AcrClientCredentials clientCredential = new AcrClientCredentials(true,
                                                                             loginUrl,
                                                                             username,
                                                                             password,
                                                                             ct);
            AzureContainerRegistryClient client = new AzureContainerRegistryClient(clientCredential);

            client.LoginUri = "https://acryihchentest0611.azurecr.io";
            try
            {
                /*
                 * {
                 *  // ######################## Acr V1 Get Repositories ########################
                 *  Repositories repositories = client.GetAcrRepositoriesAsync(null,
                 *      "",
                 *      ct).GetAwaiter().GetResult();
                 *  Console.WriteLine("GET /acr/v1/_catalog result");
                 *  Console.WriteLine(SafeJsonConvert.SerializeObject(repositories, client.SerializationSettings));
                 *  foreach (string repository in repositories.Names) {
                 *      // ######################## Acr V1 Get Repositorie Attributes ########################
                 *      RepositoryAttributes repositoryAttributes = client.GetAcrRepositoryAttributesAsync(repository,
                 *          ct).GetAwaiter().GetResult();
                 *      Console.WriteLine("GET /acr/v1/{0} result", repository);
                 *      Console.WriteLine(SafeJsonConvert.SerializeObject(repositoryAttributes, client.SerializationSettings));
                 *
                 *      // ######################## Acr V1 Get Repositorie Tags ########################
                 *      AcrRepositoryTags tags = client.GetAcrTagsAsync(repository,
                 *          null,
                 *          null,
                 *          null,
                 *          null,
                 *          ct).GetAwaiter().GetResult();
                 *      Console.WriteLine("GET /acr/v1/{0}/_tags result", repository);
                 *      Console.WriteLine(SafeJsonConvert.SerializeObject(tags, client.SerializationSettings));
                 *      foreach (AcrTagAttributesBase tag in tags.TagsAttributes) {
                 *          // ######################## Acr V1 Get Tag Attributes ########################
                 *          AcrTagAttributes tagAttribute = client.GetAcrTagAttributesAsync(repository,
                 *              tag.Name,
                 *              ct).GetAwaiter().GetResult();
                 *          Console.WriteLine("GET /acr/v1/{0}/_tags/{1} result", repository, tag.Name);
                 *          Console.WriteLine(SafeJsonConvert.SerializeObject(tagAttribute, client.SerializationSettings));
                 *      }
                 *
                 *      // ######################## Acr V1 Get Repositorie Manifests ########################
                 *      AcrManifests manifests = client.GetAcrManifestsAsync(repository,
                 *          null,
                 *          null,
                 *          null,
                 *          ct).GetAwaiter().GetResult();
                 *      Console.WriteLine("GET /acr/v1/{0}/_manifests result", repository);
                 *      Console.WriteLine(SafeJsonConvert.SerializeObject(manifests, client.SerializationSettings));
                 *      foreach (AcrManifestAttributesBase manifest in manifests.ManifestsAttributes) {
                 *          // ######################## Acr V1 Get Manifest Attributes ########################
                 *          AcrManifestAttributes manifestAttribute = client.GetAcrManifestAttributesAsync(repository,
                 *              manifest.Digest,
                 *              ct).GetAwaiter().GetResult();
                 *          Console.WriteLine("GET /acr/v1/{0}/_manifests/{1} result", repository, manifest.Digest);
                 *          Console.WriteLine(SafeJsonConvert.SerializeObject(manifestAttribute, client.SerializationSettings));
                 *      }
                 *  }
                 * }*/

                {
                    // ######################## Docker V2 Get Repositories ########################
                    Repositories repositories = client.GetRepositoriesAsync(null,
                                                                            null,
                                                                            ct).GetAwaiter().GetResult();
                    Console.WriteLine("GET /v2/_catalog result");
                    Console.WriteLine(SafeJsonConvert.SerializeObject(repositories, client.SerializationSettings));
                    foreach (string repository in repositories.Names)
                    {
                        // ######################## Docker V2 Get Tags ########################
                        RepositoryTags repositoryTags = client.GetTagListAsync(repository,
                                                                               ct).GetAwaiter().GetResult();
                        Console.WriteLine("GET /v2/{0}/tags/list result", repository);
                        Console.WriteLine(SafeJsonConvert.SerializeObject(repositoryTags, client.SerializationSettings));

                        foreach (string tag in repositoryTags.Tags)
                        {
                            // ######################## Docker V2 Get Manifest ########################
                            Manifest manifest = client.GetManifestAsync(repository,
                                                                        tag,
                                                                        "application/vnd.docker.distribution.manifest.v2+json", // most of docker images are v2 docker images now. The accept header should include "application/vnd.docker.distribution.manifest.v2+json"
                                                                        ct).GetAwaiter().GetResult();
                            Console.WriteLine("GET /v2/{0}/manifests/{1} result", repository, tag);
                            Console.WriteLine(SafeJsonConvert.SerializeObject(manifest, client.SerializationSettings));

                            // ######################## Docker V2 Update Manifest ########################
                            // Use the same manifest to update the manifest
                            // Keep in mind, you need to wait at least 5 seconds to let this change be committed in server.
                            // Getting manifest again right after updating will actually getting old manifest.
                            if (!string.Equals(tag, "3.7"))
                            {
                                continue;
                            }

                            // 1. Reference by tag
                            client.PutManifestAsync(repository,
                                                    tag, // Reference by tag
                                                    manifest,
                                                    ct).GetAwaiter().GetResult();
                            Console.WriteLine("PUT /v2/{0}/manifests/{1} result. reference by tag", repository, tag);
                            Console.WriteLine(SafeJsonConvert.SerializeObject(manifest, client.SerializationSettings));

                            // 2. Reference by digest
                            string manifestString = SafeJsonConvert.SerializeObject(manifest, client.SerializationSettings);
                            string digest         = computeDigest(manifestString);
                            client.PutManifestAsync(repository,
                                                    digest, // Reference by digest
                                                    manifest,
                                                    ct).GetAwaiter().GetResult();
                            Console.WriteLine("PUT /v2/{0}/manifests/{1} result. reference by digest", repository, digest);
                            Console.WriteLine(SafeJsonConvert.SerializeObject(manifest, client.SerializationSettings));
                        }
                    }
                }
            } catch (Exception e) {
                Console.WriteLine("Exception caught: " + e.Message);
            }
        }
Ejemplo n.º 25
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());
        }
Ejemplo n.º 26
0
        private static async Task BuildDotNetImage(string fileOrigin, ImageRef outputRepo)
        {
            // 1. Upload the .Net files to the specified repository
            var oras = new OrasPush()
            {
                OrasExe    = "C:/ProgramData/Fish/Barrel/oras/0.6.0/oras.exe",
                Registry   = outputRepo.Registry,
                Tag        = outputRepo.Tag,
                Repository = outputRepo.Repository,
                PublishDir = fileOrigin,
                Username   = outputRepo.Username,
                Password   = outputRepo.Password
            };

            if (!oras.Execute())
            {
                throw new Exception("Could not upload " + fileOrigin);
            }

            var clientCredentials = new AcrClientCredentials(AcrClientCredentials.LoginMode.Basic, outputRepo.Registry, outputRepo.Username, outputRepo.Password);
            var client            = new AzureContainerRegistryClient(clientCredentials)
            {
                LoginUri = "https://" + outputRepo.Registry
            };

            // 2. Acquire the resulting OCI manifest
            string          orasDigest = oras.digest;
            ManifestWrapper manifest   = await client.GetManifestAsync(outputRepo.Repository, orasDigest, "application/vnd.oci.image.manifest.v1+json");

            long   app_size   = (long)manifest.Layers[0].Size;
            string appDiffId  = (string)manifest.Layers[0].Annotations.AdditionalProperties["io.deis.oras.content.digest"];
            string app_digest = manifest.Layers[0].Digest;

            // 3. Acquire base for .Net image

            var baseLayers = new ImageRef()
            {
                Registry = "mcr.microsoft.com"
            };

            var dotnetVersion = "2.2";

            switch (dotnetVersion)
            {
            case "2.1":
                baseLayers.Repository = "dotnet/core/runtime";
                baseLayers.Tag        = "2.1";
                break;

            case "2.2":
                baseLayers.Repository = "dotnet/core/runtime";
                baseLayers.Tag        = "2.2";
                break;

            case "3.0":
                baseLayers.Repository = "dotnet/core-nightly/runtime";
                baseLayers.Tag        = "3.0";
                break;

            default:
                baseLayers.Repository = "dotnet/core-nightly/runtime-deps";
                baseLayers.Tag        = "latest";
                break;
            }

            // 4. Move base layers to repo
            await CopyBaseImageLayers(baseLayers, outputRepo, true);

            // 5. Acquire config blob from base
            var baseClient = new AzureContainerRegistryClient(new TokenCredentials())
            {
                LoginUri = "https://" + baseLayers.Registry
            };

            ManifestWrapper baseManifest = await baseClient.GetManifestAsync(baseLayers.Repository, baseLayers.Tag, "application/vnd.docker.distribution.manifest.v2+json");

            var configBlob = await baseClient.GetBlobAsync(baseLayers.Repository, baseManifest.Config.Digest);

            long   appConfigSize;
            string appConfigDigest;

            // 6. Add layer to config blob
            using (StreamReader reader = new StreamReader(configBlob, Encoding.UTF8))
            {
                string originalBlob = reader.ReadToEnd();
                var    nah          = System.Text.Encoding.UTF8.GetByteCount(originalBlob);

                var config = JsonConvert.DeserializeObject <ConfigBlob>(originalBlob);
                config.Rootfs.DiffIds.Add(appDiffId);
                string serialized = JsonConvert.SerializeObject(config, Formatting.None);
                appConfigSize   = Encoding.UTF8.GetByteCount(serialized);
                appConfigDigest = ComputeDigest(serialized);
                await UploadLayer(GenerateStreamFromString(serialized), outputRepo.Repository, client);

                // Upload config blob
            }

            // 7. Modify manifest file for the new layer
            var newManifest = baseManifest;

            newManifest.Config.Size   = appConfigSize;
            newManifest.Config.Digest = appConfigDigest;
            var newLayer = new Descriptor()
            {
                MediaType = "application/vnd.docker.image.rootfs.diff.tar.gzip",
                Size      = app_size,
                Digest    = app_digest
            };

            newManifest.Layers.Add(newLayer);

            await client.CreateManifestAsync(outputRepo.Repository, outputRepo.Tag, newManifest);

            // 8. Upload config blob

            // 9. Push new manifest

            // Image can now be run!
        }
Ejemplo n.º 27
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);
        }