예제 #1
0
        private async Task SaveTagInfoToImageInfoFileAsync(DateTime createdDate, ImageArtifactDetails imageArtifactDetails)
        {
            _loggerService.WriteSubheading("SETTING TAG INFO");

            IEnumerable <ImageData> images = imageArtifactDetails.Repos
                                             .SelectMany(repo => repo.Images)
                                             .Where(image => image.Manifest != null);

            await Parallel.ForEachAsync(images, async (image, cancellationToken) =>
            {
                image.Manifest.Created = createdDate;

                TagInfo sharedTag = image.ManifestImage.SharedTags.First();

                image.Manifest.Digest = DockerHelper.GetDigestString(
                    image.ManifestRepo.FullModelName,
                    await _manifestToolService.GetManifestDigestShaAsync(
                        sharedTag.FullyQualifiedName, Options.CredentialsOptions, Options.IsDryRun));

                IEnumerable <(string Repo, string Tag)> syndicatedRepresentativeSharedTags = image.ManifestImage.SharedTags
                                                                                             .Where(tag => tag.SyndicatedRepo is not null)
                                                                                             .GroupBy(tag => tag.SyndicatedRepo)
                                                                                             .Select(group => (group.Key, group.First().SyndicatedDestinationTags.First()))
                                                                                             .Cast <(string Repo, string Tag)>()
                                                                                             .OrderBy(obj => obj.Repo)
                                                                                             .ThenBy(obj => obj.Tag);

                foreach ((string Repo, string Tag)syndicatedSharedTag in syndicatedRepresentativeSharedTags)
                {
                    string digest = DockerHelper.GetDigestString(
                        DockerHelper.GetImageName(Manifest.Model.Registry, syndicatedSharedTag.Repo),
                        await _manifestToolService.GetManifestDigestShaAsync(
                            DockerHelper.GetImageName(Manifest.Registry, Options.RepoPrefix + syndicatedSharedTag.Repo, syndicatedSharedTag.Tag),
                            Options.CredentialsOptions,
                            Options.IsDryRun));
                    image.Manifest.SyndicatedDigests.Add(digest);
                }
            });

            string imageInfoString = JsonHelper.SerializeObject(imageArtifactDetails);

            File.WriteAllText(Options.ImageInfoPath, imageInfoString);
        }
예제 #2
0
        private void SetPlatformDataDigest(PlatformData platform, string tag)
        {
            // The digest of an image that is pushed to ACR is guaranteed to be the same when transferred to MCR.
            string digest = _imageDigestCache.GetImageDigest(tag, Options.IsDryRun);

            if (digest != null)
            {
                digest = DockerHelper.GetDigestString(platform.PlatformInfo.FullRepoModelName, DockerHelper.GetDigestSha(digest));
            }

            if (platform.Digest != null && platform.Digest != digest)
            {
                // Pushing the same image with different tags should result in the same digest being output
                throw new InvalidOperationException(
                          $"Tag '{tag}' was pushed with a resulting digest value that differs from the corresponding image's digest value." +
                          Environment.NewLine +
                          $"\tDigest value from image info: {platform.Digest}{Environment.NewLine}" +
                          $"\tDigest value retrieved from query: {digest}");
            }

            platform.Digest = digest;
        }
예제 #3
0
        private void SaveTagInfoToImageInfoFile(DateTime createdDate, ImageArtifactDetails imageArtifactDetails)
        {
            _loggerService.WriteSubheading("SETTING TAG INFO");

            IEnumerable <ImageData> images = imageArtifactDetails.Repos
                                             .SelectMany(repo => repo.Images)
                                             .Where(image => image.Manifest != null);

            Parallel.ForEach(images, image =>
            {
                image.Manifest.Created = createdDate;

                TagInfo sharedTag     = image.ManifestImage.SharedTags.First();
                image.Manifest.Digest = DockerHelper.GetDigestString(
                    image.ManifestRepo.FullModelName,
                    _manifestToolService.GetManifestDigestSha(
                        ManifestMediaType.ManifestList, sharedTag.FullyQualifiedName, Options.IsDryRun));
            });

            string imageInfoString = JsonHelper.SerializeObject(imageArtifactDetails);

            File.WriteAllText(Options.ImageInfoPath, imageInfoString);
        }
예제 #4
0
        private List <string> GetPathsToRebuild(
            IEnumerable <PlatformInfo> allPlatforms, PlatformInfo platform, RepoData repoData)
        {
            bool foundImageInfo = false;

            List <string> pathsToRebuild = new List <string>();

            void processPlatformWithMissingImageInfo(PlatformInfo platform)
            {
                _loggerService.WriteMessage(
                    $"WARNING: Image info not found for '{platform.DockerfilePath}'. Adding path to build to be queued anyway.");
                IEnumerable <PlatformInfo> dependentPlatforms = platform.GetDependencyGraph(allPlatforms);

                pathsToRebuild.AddRange(dependentPlatforms.Select(p => p.Model.Dockerfile));
            }

            if (repoData == null || repoData.Images == null)
            {
                processPlatformWithMissingImageInfo(platform);
                return(pathsToRebuild);
            }

            foreach (ImageData imageData in repoData.Images)
            {
                PlatformData platformData = imageData.Platforms
                                            .FirstOrDefault(platformData => platformData.PlatformInfo == platform);
                if (platformData != null)
                {
                    foundImageInfo = true;
                    string fromImage = platform.FinalStageFromImage;
                    string currentDigest;

                    currentDigest = LockHelper.DoubleCheckedLockLookup(_imageDigestsLock, _imageDigests, fromImage,
                                                                       () =>
                    {
                        string digest = _manifestToolService.GetManifestDigestSha(ManifestMediaType.Any, fromImage, Options.IsDryRun);
                        return(DockerHelper.GetDigestString(DockerHelper.GetRepo(fromImage), digest));
                    });

                    bool rebuildImage = platformData.BaseImageDigest != currentDigest;

                    _loggerService.WriteMessage(
                        $"Checking base image '{fromImage}' from '{platform.DockerfilePath}'{Environment.NewLine}"
                        + $"\tLast build digest:    {platformData.BaseImageDigest}{Environment.NewLine}"
                        + $"\tCurrent digest:       {currentDigest}{Environment.NewLine}"
                        + $"\tImage is up-to-date:  {!rebuildImage}{Environment.NewLine}");

                    if (rebuildImage)
                    {
                        IEnumerable <PlatformInfo> dependentPlatforms = platform.GetDependencyGraph(allPlatforms);
                        pathsToRebuild.AddRange(dependentPlatforms.Select(p => p.Model.Dockerfile));
                    }

                    break;
                }
            }

            if (!foundImageInfo)
            {
                processPlatformWithMissingImageInfo(platform);
            }

            return(pathsToRebuild);
        }