private string GetVariableValue(string variableType, string variableName)
        {
            string variableValue = null;

            if (string.Equals(variableType, VariableHelper.McrTagsYmlRepoTypeId, StringComparison.Ordinal))
            {
                RepoInfo repo = _manifest.GetFilteredRepoById(variableName);
                variableValue = GetRepoYaml(repo);
            }
            else if (string.Equals(variableType, VariableHelper.McrTagsYmlTagGroupTypeId, StringComparison.Ordinal))
            {
                ImageDocumentationInfo info = _imageDocInfos
                                              .FirstOrDefault(idi => idi.DocumentedTags.Any(tag => tag.Name == variableName));
                if (info != null)
                {
                    // Find all other doc infos that match this one. This accounts for scenarios where a platform is
                    // duplicated in another image in order to associate it within a distinct set of shared tags.
                    IEnumerable <ImageDocumentationInfo> matchingDocInfos = _imageDocInfos
                                                                            .Where(docInfo => docInfo.Platform != info.Platform &&
                                                                                   PlatformInfo.AreMatchingPlatforms(docInfo.Image, docInfo.Platform, info.Image, info.Platform))
                                                                            .Prepend(info)
                                                                            .ToArray();

                    foreach (ImageDocumentationInfo docInfo in matchingDocInfos)
                    {
                        _imageDocInfos.Remove(docInfo);
                    }

                    variableValue = GetTagGroupYaml(matchingDocInfos);
                }
            }

            return(variableValue);
        }
Exemplo n.º 2
0
        private void PublishImageInfo()
        {
            if (string.IsNullOrEmpty(Options.ImageInfoOutputPath))
            {
                return;
            }

            if (string.IsNullOrEmpty(Options.SourceRepoUrl))
            {
                throw new InvalidOperationException("Source repo URL must be provided when outputting to an image info file.");
            }

            Dictionary <string, PlatformData> platformDataByTag = new Dictionary <string, PlatformData>();

            foreach (PlatformData platformData in GetBuiltPlatforms())
            {
                foreach (TagInfo tag in platformData.PlatformInfo.Tags)
                {
                    platformDataByTag.Add(tag.FullyQualifiedName, platformData);
                }
            }

            IEnumerable <PlatformData> builtPlatforms          = GetBuiltPlatforms();
            List <PlatformData>        platformsWithNoPushTags = new List <PlatformData>();

            foreach (PlatformData platform in builtPlatforms)
            {
                IEnumerable <TagInfo> pushTags = GetPushTags(platform.PlatformInfo.Tags);

                foreach (TagInfo tag in pushTags)
                {
                    if (Options.IsPushEnabled)
                    {
                        SetPlatformDataDigest(platform, tag.FullyQualifiedName);
                        SetPlatformDataBaseDigest(platform, platformDataByTag);
                    }

                    SetPlatformDataCreatedDate(platform, tag.FullyQualifiedName);
                }

                if (!pushTags.Any())
                {
                    platformsWithNoPushTags.Add(platform);
                }

                platform.CommitUrl = _gitService.GetDockerfileCommitUrl(platform.PlatformInfo, Options.SourceRepoUrl);
            }

            // Some platforms do not have concrete tags. In such cases, they must be duplicates of a platform in a different
            // image which does have a concrete tag. For these platforms that do not have concrete tags, we are unable to
            // lookup digest/created info based on their tag. Instead, we find the matching platform which does have that info
            // set (as a result of having a concrete tag) and copy its values.
            foreach (PlatformData platform in platformsWithNoPushTags)
            {
                PlatformData matchingBuiltPlatform = builtPlatforms.First(builtPlatform =>
                                                                          GetPushTags(builtPlatform.PlatformInfo.Tags).Any() &&
                                                                          PlatformInfo.AreMatchingPlatforms(platform.ImageInfo, platform.PlatformInfo, builtPlatform.ImageInfo, builtPlatform.PlatformInfo));

                platform.Digest  = matchingBuiltPlatform.Digest;
                platform.Created = matchingBuiltPlatform.Created;
            }

            string imageInfoString = JsonHelper.SerializeObject(_imageArtifactDetails);

            File.WriteAllText(Options.ImageInfoOutputPath, imageInfoString);
        }
Exemplo n.º 3
0
        private string GenerateManifest(RepoInfo repo, ImageInfo image, IEnumerable <string> tags, Func <string, string> getImageName,
                                        Func <PlatformInfo, TagInfo?> getTagRepresentative)
        {
            string        imageName   = getImageName(tags.First());
            StringBuilder manifestYml = new();

            manifestYml.AppendLine($"image: {imageName}");
            _publishedManifestTags.Add(imageName);

            string repoName = DockerHelper.GetRepo(imageName);

            IEnumerable <string> additionalTags = tags.Skip(1);

            if (additionalTags.Any())
            {
                manifestYml.AppendLine($"tags: [{string.Join(",", additionalTags)}]");
            }

            _publishedManifestTags.AddRange(additionalTags.Select(tag => $"{repoName}:{tag}"));

            manifestYml.AppendLine("manifests:");
            foreach (PlatformInfo platform in image.AllPlatforms)
            {
                TagInfo?imageTag;
                if (platform.Tags.Any())
                {
                    imageTag = getTagRepresentative(platform);
                }
                else
                {
                    (ImageInfo Image, PlatformInfo Platform)matchingImagePlatform = repo.AllImages
                                                                                    .SelectMany(image =>
                                                                                                image.AllPlatforms
                                                                                                .Select(p => (Image: image, Platform: p))
                                                                                                .Where(imagePlatform => platform != imagePlatform.Platform &&
                                                                                                       PlatformInfo.AreMatchingPlatforms(image, platform, imagePlatform.Image, imagePlatform.Platform) &&
                                                                                                       imagePlatform.Platform.Tags.Any()))
                                                                                    .FirstOrDefault();

                    if (matchingImagePlatform.Platform is null)
                    {
                        throw new InvalidOperationException(
                                  $"Could not find a platform with concrete tags for '{platform.DockerfilePathRelativeToManifest}'.");
                    }

                    imageTag = getTagRepresentative(matchingImagePlatform.Platform);
                }

                if (imageTag is not null)
                {
                    manifestYml.AppendLine($"- image: {getImageName(imageTag.Name)}");
                    manifestYml.AppendLine($"  platform:");
                    manifestYml.AppendLine($"    architecture: {platform.Model.Architecture.GetDockerName()}");
                    manifestYml.AppendLine($"    os: {platform.Model.OS.GetDockerName()}");
                    if (platform.Model.Variant != null)
                    {
                        manifestYml.AppendLine($"    variant: {platform.Model.Variant}");
                    }
                }
            }

            return(manifestYml.ToString());
        }