Ejemplo n.º 1
0
        private async Task ProcessManifestsAsync(
            IAcrClient acrClient, List <string> deletedImages, List <string> deletedRepos, Repository repository,
            Func <ManifestAttributes, bool> canDeleteManifest)
        {
            _loggerService.WriteMessage($"Querying manifests for repo '{repository.Name}'");
            RepositoryManifests repoManifests = await acrClient.GetRepositoryManifestsAsync(repository.Name);

            _loggerService.WriteMessage($"Finished querying manifests for repo '{repository.Name}'. Manifest count: {repoManifests.Manifests.Count}");

            if (!repoManifests.Manifests.Any())
            {
                await DeleteRepositoryAsync(acrClient, deletedRepos, repository);

                return;
            }

            ManifestAttributes[] expiredTestImages = repoManifests.Manifests
                                                     .Where(manifest => canDeleteManifest(manifest))
                                                     .ToArray();

            // If all the images in the repo are expired, delete the whole repo instead of
            // deleting each individual image.
            if (expiredTestImages.Length == repoManifests.Manifests.Count)
            {
                await DeleteRepositoryAsync(acrClient, deletedRepos, repository);

                return;
            }

            await DeleteManifestsAsync(acrClient, deletedImages, repository, expiredTestImages);
        }
Ejemplo n.º 2
0
        public async Task <RepositoryManifests> GetRepositoryManifestsAsync(string repositoryName)
        {
            RepositoryManifests result = null;

            await GetPagedResponseAsync <RepositoryManifests>(
                $"{_acrV1BaseUrl}/{repositoryName}/_manifests?n={MaxPagedResults}",
                pagedRepoManifests =>
            {
                if (result is null)
                {
                    result = pagedRepoManifests;
                }
                else
                {
                    result.Manifests.AddRange(pagedRepoManifests.Manifests);
                }
            });

            return(result);
        }
        public async Task StagingRepos()
        {
            const string acrName       = "myacr.azurecr.io";
            const string tenant        = "mytenant";
            const string username      = "******";
            const string password      = "******";
            const string subscription  = "my sub";
            const string resourceGroup = "group";

            const string stagingRepo1Name = "build-staging/repo1";
            const string stagingRepo2Name = "build-staging/repo2";

            Catalog catalog = new Catalog
            {
                RepositoryNames = new List <string>
                {
                    stagingRepo1Name,
                    stagingRepo2Name
                }
            };

            Repository nonPublicRepo1 = new Repository
            {
                LastUpdateTime = DateTime.Now.Subtract(TimeSpan.FromDays(14)),
                Name           = stagingRepo1Name
            };

            Repository nonPublicRepo2 = new Repository
            {
                LastUpdateTime = DateTime.Now.Subtract(TimeSpan.FromDays(16)),
                Name           = stagingRepo2Name
            };

            const string repo1Digest1 = "sha256:repo1digest1";

            RepositoryManifests repo1Manifests = new RepositoryManifests
            {
                RepositoryName = stagingRepo1Name,
                Manifests      = new List <ManifestAttributes>
                {
                    new ManifestAttributes
                    {
                        Digest = repo1Digest1
                    }
                }
            };

            const string repo2Digest1 = "sha256:repo2digest1";

            RepositoryManifests repo2Manifests = new RepositoryManifests
            {
                RepositoryName = stagingRepo2Name,
                Manifests      = new List <ManifestAttributes>
                {
                    new ManifestAttributes
                    {
                        Digest = repo2Digest1
                    }
                }
            };

            Mock <IAcrClient> acrClientMock = new Mock <IAcrClient>();

            acrClientMock
            .Setup(o => o.GetCatalogAsync())
            .ReturnsAsync(catalog);
            acrClientMock
            .Setup(o => o.GetRepositoryManifestsAsync(stagingRepo1Name))
            .ReturnsAsync(repo1Manifests);
            acrClientMock
            .Setup(o => o.GetRepositoryManifestsAsync(stagingRepo2Name))
            .ReturnsAsync(repo2Manifests);
            acrClientMock
            .Setup(o => o.GetRepositoryAsync(stagingRepo1Name))
            .ReturnsAsync(nonPublicRepo1);
            acrClientMock
            .Setup(o => o.GetRepositoryAsync(stagingRepo2Name))
            .ReturnsAsync(nonPublicRepo2);
            acrClientMock
            .Setup(o => o.DeleteRepositoryAsync(stagingRepo2Name))
            .ReturnsAsync(new DeleteRepositoryResponse());

            Mock <IAcrClientFactory> acrClientFactoryMock = new Mock <IAcrClientFactory>();

            acrClientFactoryMock
            .Setup(o => o.CreateAsync(acrName, tenant, username, password))
            .ReturnsAsync(acrClientMock.Object);

            CleanAcrImagesCommand command = new CleanAcrImagesCommand(
                acrClientFactoryMock.Object, Mock.Of <ILoggerService>());

            command.Options.Subscription              = subscription;
            command.Options.ServicePrincipal.Secret   = password;
            command.Options.ServicePrincipal.ClientId = username;
            command.Options.ServicePrincipal.Tenant   = tenant;
            command.Options.ResourceGroup             = resourceGroup;
            command.Options.RegistryName              = acrName;
            command.Options.RepoName = "build-staging/*";
            command.Options.Action   = CleanAcrImagesAction.Delete;
            command.Options.Age      = 15;

            await command.ExecuteAsync();

            acrClientMock.Verify(o => o.DeleteRepositoryAsync(stagingRepo1Name), Times.Never);
            acrClientMock.Verify(o => o.DeleteRepositoryAsync(stagingRepo2Name));
        }
        public async Task TestRepos()
        {
            const string acrName       = "myacr.azurecr.io";
            const string tenant        = "mytenant";
            const string username      = "******";
            const string password      = "******";
            const string subscription  = "my sub";
            const string resourceGroup = "group";

            const string repo1Name = "test/repo1";
            const string repo2Name = "test/repo2";

            Catalog catalog = new Catalog
            {
                RepositoryNames = new List <string>
                {
                    repo1Name,
                    repo2Name
                }
            };

            const string repo1Digest1 = "sha256:repo1digest1";
            const string repo1Digest2 = "sha256:repo1digest2";

            RepositoryManifests repo1Manifests = new RepositoryManifests
            {
                RepositoryName = repo1Name,
                Manifests      = new List <ManifestAttributes>
                {
                    new ManifestAttributes
                    {
                        Digest         = repo1Digest1,
                        LastUpdateTime = DateTime.Now.Subtract(TimeSpan.FromDays(8))
                    },
                    new ManifestAttributes
                    {
                        Digest         = repo1Digest2,
                        LastUpdateTime = DateTime.Now.Subtract(TimeSpan.FromDays(6))
                    }
                }
            };

            const string repo2Digest1 = "sha256:repo2digest1";
            const string repo2Digest2 = "sha256:repo2digest2";

            RepositoryManifests repo2Manifests = new RepositoryManifests
            {
                RepositoryName = repo2Name,
                Manifests      = new List <ManifestAttributes>
                {
                    new ManifestAttributes
                    {
                        Digest         = repo2Digest1,
                        LastUpdateTime = DateTime.Now.Subtract(TimeSpan.FromDays(1))
                    },
                    new ManifestAttributes
                    {
                        Digest         = repo2Digest2,
                        LastUpdateTime = DateTime.Now.Subtract(TimeSpan.FromDays(31))
                    }
                }
            };

            Mock <IAcrClient> acrClientMock = new Mock <IAcrClient>();

            acrClientMock
            .Setup(o => o.GetCatalogAsync())
            .ReturnsAsync(catalog);
            foreach (string repoName in catalog.RepositoryNames)
            {
                acrClientMock
                .Setup(o => o.GetRepositoryAsync(repoName))
                .ReturnsAsync(new Repository {
                    Name = repoName
                });
            }
            acrClientMock
            .Setup(o => o.GetRepositoryManifestsAsync(repo1Name))
            .ReturnsAsync(repo1Manifests);
            acrClientMock
            .Setup(o => o.GetRepositoryManifestsAsync(repo2Name))
            .ReturnsAsync(repo2Manifests);

            Mock <IAcrClientFactory> acrClientFactoryMock = new Mock <IAcrClientFactory>();

            acrClientFactoryMock
            .Setup(o => o.CreateAsync(acrName, tenant, username, password))
            .ReturnsAsync(acrClientMock.Object);

            CleanAcrImagesCommand command = new CleanAcrImagesCommand(
                acrClientFactoryMock.Object, Mock.Of <ILoggerService>());

            command.Options.Subscription              = subscription;
            command.Options.ServicePrincipal.Secret   = password;
            command.Options.ServicePrincipal.ClientId = username;
            command.Options.ServicePrincipal.Tenant   = tenant;
            command.Options.ResourceGroup             = resourceGroup;
            command.Options.RegistryName              = acrName;
            command.Options.RepoName = "test/*";
            command.Options.Action   = CleanAcrImagesAction.PruneAll;
            command.Options.Age      = 7;

            await command.ExecuteAsync();

            acrClientMock.Verify(o => o.DeleteManifestAsync(repo1Name, repo1Digest1));
            acrClientMock.Verify(o => o.DeleteManifestAsync(repo1Name, repo1Digest2), Times.Never);
            acrClientMock.Verify(o => o.DeleteManifestAsync(repo2Name, repo2Digest1), Times.Never);
            acrClientMock.Verify(o => o.DeleteManifestAsync(repo2Name, repo2Digest2));
        }
        public async Task PublicNightlyRepos()
        {
            const string acrName       = "myacr.azurecr.io";
            const string tenant        = "mytenant";
            const string username      = "******";
            const string password      = "******";
            const string subscription  = "my sub";
            const string resourceGroup = "group";

            const string publicRepo1Name = "public/dotnet/core-nightly/repo1";
            const string publicRepo2Name = "public/dotnet/core/repo2";
            const string publicRepo3Name = "public/dotnet/core-nightly/repo3";
            const string publicRepo4Name = "public/dotnet/nightly/repo4";

            Catalog catalog = new Catalog
            {
                RepositoryNames = new List <string>
                {
                    publicRepo1Name,
                    publicRepo2Name,
                    publicRepo3Name,
                    publicRepo4Name
                }
            };

            const string repo1Digest1 = "sha256:repo1digest1";
            const string repo1Digest2 = "sha256:repo1digest2";

            RepositoryManifests repo1Manifests = new RepositoryManifests
            {
                RepositoryName = publicRepo1Name,
                Manifests      = new List <ManifestAttributes>
                {
                    new ManifestAttributes
                    {
                        Digest         = repo1Digest1,
                        LastUpdateTime = DateTime.Now.Subtract(TimeSpan.FromDays(1)),
                        Tags           = new string[0]
                    },
                    new ManifestAttributes
                    {
                        Digest         = repo1Digest2,
                        LastUpdateTime = DateTime.Now.Subtract(TimeSpan.FromDays(31)),
                        Tags           = new string[]
                        {
                            "tag"
                        }
                    }
                }
            };

            const string repo3Digest1 = "sha256:repo3digest1";
            const string repo3Digest2 = "sha256:repo3digest2";

            RepositoryManifests repo3Manifests = new RepositoryManifests
            {
                RepositoryName = publicRepo3Name,
                Manifests      = new List <ManifestAttributes>
                {
                    new ManifestAttributes
                    {
                        Digest         = repo3Digest1,
                        LastUpdateTime = DateTime.Now.Subtract(TimeSpan.FromDays(29)),
                        Tags           = new string[0]
                    },
                    new ManifestAttributes
                    {
                        Digest         = repo3Digest2,
                        LastUpdateTime = DateTime.Now.Subtract(TimeSpan.FromDays(31)),
                        Tags           = new string[0]
                    }
                }
            };

            const string repo4Digest1 = "sha256:repo4digest1";

            RepositoryManifests repo4Manifests = new RepositoryManifests
            {
                RepositoryName = publicRepo4Name,
                Manifests      = new List <ManifestAttributes>
                {
                    new ManifestAttributes
                    {
                        Digest         = repo4Digest1,
                        LastUpdateTime = DateTime.Now.Subtract(TimeSpan.FromDays(60)),
                        Tags           = new string[0]
                    }
                }
            };

            Mock <IAcrClient> acrClientMock = new Mock <IAcrClient>();

            acrClientMock
            .Setup(o => o.GetCatalogAsync())
            .ReturnsAsync(catalog);
            foreach (string repoName in catalog.RepositoryNames)
            {
                acrClientMock
                .Setup(o => o.GetRepositoryAsync(repoName))
                .ReturnsAsync(new Repository {
                    Name = repoName
                });
            }
            acrClientMock
            .Setup(o => o.GetRepositoryManifestsAsync(publicRepo1Name))
            .ReturnsAsync(repo1Manifests);
            acrClientMock
            .Setup(o => o.GetRepositoryManifestsAsync(publicRepo3Name))
            .ReturnsAsync(repo3Manifests);
            acrClientMock
            .Setup(o => o.GetRepositoryManifestsAsync(publicRepo4Name))
            .ReturnsAsync(repo4Manifests);
            acrClientMock
            .Setup(o => o.DeleteRepositoryAsync(publicRepo4Name))
            .ReturnsAsync(new DeleteRepositoryResponse());

            Mock <IAcrClientFactory> acrClientFactoryMock = new Mock <IAcrClientFactory>();

            acrClientFactoryMock
            .Setup(o => o.CreateAsync(acrName, tenant, username, password))
            .ReturnsAsync(acrClientMock.Object);

            CleanAcrImagesCommand command = new CleanAcrImagesCommand(
                acrClientFactoryMock.Object, Mock.Of <ILoggerService>());

            command.Options.Subscription              = subscription;
            command.Options.ServicePrincipal.Secret   = password;
            command.Options.ServicePrincipal.ClientId = username;
            command.Options.ServicePrincipal.Tenant   = tenant;
            command.Options.ResourceGroup             = resourceGroup;
            command.Options.RegistryName              = acrName;
            command.Options.RepoName = "public/dotnet/*nightly/*";
            command.Options.Action   = CleanAcrImagesAction.PruneDangling;
            command.Options.Age      = 30;

            await command.ExecuteAsync();

            acrClientMock.Verify(o => o.DeleteManifestAsync(publicRepo1Name, repo1Digest1), Times.Never);
            acrClientMock.Verify(o => o.DeleteManifestAsync(publicRepo1Name, repo1Digest2), Times.Never);
            acrClientMock.Verify(o => o.DeleteManifestAsync(publicRepo2Name, It.IsAny <string>()), Times.Never);
            acrClientMock.Verify(o => o.DeleteManifestAsync(publicRepo3Name, repo3Digest1), Times.Never);
            acrClientMock.Verify(o => o.DeleteManifestAsync(publicRepo3Name, repo3Digest2));
            acrClientMock.Verify(o => o.DeleteRepositoryAsync(publicRepo4Name));
        }