From ae9884004ebdfab33a109c364a2caca96dec994e Mon Sep 17 00:00:00 2001 From: Matt Thalman Date: Mon, 24 Jun 2019 15:37:20 -0500 Subject: [PATCH] Fix RebuildStaleImages command to generate dependency graph (#217) Ensures that the set of paths produced by the RebuildStaleImages command consists of the image whose base image had changed as well as its dependent images. --- .gitignore | 3 ++- .../src/Commands/RebuildStaleImagesCommand.cs | 16 ++++++++++++++-- .../src/ViewModel/ManifestInfo.cs | 10 +++++++--- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 03231b5135..21052fcfec 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,6 @@ .vscode/ .vs -# Visual Studio debug profile +# Visual Studio user-specific files **/launchSettings.json +**/*.user diff --git a/Microsoft.DotNet.ImageBuilder/src/Commands/RebuildStaleImagesCommand.cs b/Microsoft.DotNet.ImageBuilder/src/Commands/RebuildStaleImagesCommand.cs index 9453591ab6..e23c5840c0 100644 --- a/Microsoft.DotNet.ImageBuilder/src/Commands/RebuildStaleImagesCommand.cs +++ b/Microsoft.DotNet.ImageBuilder/src/Commands/RebuildStaleImagesCommand.cs @@ -119,6 +119,8 @@ private async Task> GetPathsToRebuildAsync(Subscription subs List pathsToRebuild = new List(); + IEnumerable allPlatforms = manifest.GetAllPlatforms().ToList(); + foreach (RepoInfo repo in manifest.FilteredRepos) { IEnumerable platforms = repo.FilteredImages @@ -127,6 +129,7 @@ private async Task> GetPathsToRebuildAsync(Subscription subs RepoData repoData = repos .FirstOrDefault(s => s.Repo == repo.Model.Name); + HashSet processedImages = new HashSet(); foreach (var platform in platforms) { if (repoData != null && @@ -134,12 +137,20 @@ private async Task> GetPathsToRebuildAsync(Subscription subs repoData.Images.TryGetValue(platform.BuildContextPath, out ImageData imageData)) { bool hasDigestChanged = false; + foreach (string fromImage in platform.ExternalFromImages) { + if (processedImages.Contains(fromImage)) + { + continue; + } + DockerHelper.PullImage(fromImage, Options.IsDryRun); string currentDigest = DockerHelper.GetImageDigest(fromImage, Options.IsDryRun); string lastDigest = imageData.BaseImages?[fromImage]; + processedImages.Add(fromImage); + if (lastDigest != currentDigest) { hasDigestChanged = true; @@ -149,7 +160,8 @@ private async Task> GetPathsToRebuildAsync(Subscription subs if (hasDigestChanged) { - pathsToRebuild.Add(platform.BuildContextPath); + IEnumerable dependentPlatforms = platform.GetDependencyGraph(allPlatforms); + pathsToRebuild.AddRange(dependentPlatforms.Select(p => p.BuildContextPath)); } } else @@ -160,7 +172,7 @@ private async Task> GetPathsToRebuildAsync(Subscription subs } } - return pathsToRebuild; + return pathsToRebuild.Distinct().ToList(); } private async Task GetGitRepoPath(Subscription sub) diff --git a/Microsoft.DotNet.ImageBuilder/src/ViewModel/ManifestInfo.cs b/Microsoft.DotNet.ImageBuilder/src/ViewModel/ManifestInfo.cs index beda1d9f45..c794db6b3c 100644 --- a/Microsoft.DotNet.ImageBuilder/src/ViewModel/ManifestInfo.cs +++ b/Microsoft.DotNet.ImageBuilder/src/ViewModel/ManifestInfo.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; @@ -71,7 +72,7 @@ private static ManifestInfo Create(string manifestPath, ManifestFilter manifestF .ToArray(); IEnumerable repoNames = manifestInfo.AllRepos.Select(repo => repo.Name).ToArray(); - foreach (PlatformInfo platform in manifestInfo.AllRepos.SelectMany(repo => repo.AllImages).SelectMany(image => image.AllPlatforms)) + foreach (PlatformInfo platform in manifestInfo.GetAllPlatforms()) { platform.Initialize(repoNames, manifestInfo.Registry); } @@ -84,10 +85,13 @@ private static ManifestInfo Create(string manifestPath, ManifestFilter manifestF return manifestInfo; } + public IEnumerable GetAllImages() => AllRepos.SelectMany(repo => repo.AllImages); + + public IEnumerable GetAllPlatforms() => GetAllImages().SelectMany(image => image.AllPlatforms); + private IEnumerable GetAllTags() { - IEnumerable images = AllRepos - .SelectMany(repo => repo.AllImages) + IEnumerable images = GetAllImages() .ToArray(); IEnumerable sharedTags = images .SelectMany(image => image.SharedTags);