public async Task <Result> Run()
        {
            var templates = _configurationExplorer.Explore(_options.SourcePath, _options.ConfigurationFiles);

            if (templates.State == Result.Error)
            {
                return(Result.Error);
            }

            var buildGraphResult = _buildGraphFactory.Create(templates.Value);

            if (buildGraphResult.State == Result.Error)
            {
                return(Result.Error);
            }

            var buildGraphsResult = _buildGraphsFactory.Create(buildGraphResult.Value);

            if (buildGraphsResult.State == Result.Error)
            {
                return(Result.Error);
            }

            var buildGraphs = buildGraphsResult.Value.ToList();

            if (!buildGraphs.Any())
            {
                _logger.Log("Nothing to build.", Result.Error);
                return(Result.Error);
            }

            var dockerFilesRootPath = _fileSystem.UniqueName;
            var contextStreamResult = await _contextFactory.Create(dockerFilesRootPath, buildGraphResult.Value.Nodes.Select(i => i.Value).OfType <Image>().Select(i => i.File));

            if (contextStreamResult.State == Result.Error)
            {
                return(Result.Error);
            }

            var contextStream = contextStreamResult.Value;

            using (contextStream)
                using (_logger.CreateBlock("Build"))
                {
                    var labels = new Dictionary <string, string>();
                    foreach (var buildGraph in buildGraphs)
                    {
                        var name = _graphNameFactory.Create(buildGraph).Value ?? "Unnamed graph";
                        if (!string.IsNullOrWhiteSpace(_options.FilterRegex) && !new Regex(_options.FilterRegex).IsMatch(name))
                        {
                            _logger.Log($"\"{name}\" was skipped according to filter \"{_options.FilterRegex}\".", Result.Warning);
                            continue;
                        }

                        using (_logger.CreateBlock(name))
                        {
                            var buildPath = _buildPathProvider.GetPath(buildGraph).ToList();
                            foreach (var buildNode in buildPath)
                            {
                                switch (buildNode.Value)
                                {
                                case Image image:
                                    var dockerFile = image.File;
                                    using (_logger.CreateBlock(dockerFile.ToString()))
                                    {
                                        contextStream.Position = 0;
                                        var dockerFilePathInContext = _pathService.Normalize(Path.Combine(dockerFilesRootPath, dockerFile.Path));
                                        var buildParameters         = new ImageBuildParameters
                                        {
                                            Dockerfile = dockerFilePathInContext,
                                            Tags       = dockerFile.Tags.Distinct().ToList(),
                                            Labels     = labels
                                        };

                                        using (var buildEventStream = await _dockerClient.Images.BuildImageFromDockerfileAsync(
                                                   contextStream,
                                                   buildParameters,
                                                   _cancellationTokenSource.Token))
                                        {
                                            _streamService.ProcessLines(buildEventStream, line => { _messageLogger.Log(line); });
                                        }
                                    }

                                    break;
                                }
                            }
                        }
                    }
                }

            return(Result.Success);
        }
Esempio n. 2
0
        public async Task <Result> Run()
        {
            var templates = _configurationExplorer.Explore(_options.SourcePath, _options.ConfigurationFiles);

            if (templates.State == Result.Error)
            {
                return(Result.Error);
            }

            var buildGraphResult = _buildGraphFactory.Create(templates.Value);

            if (buildGraphResult.State == Result.Error)
            {
                return(Result.Error);
            }

            var buildGraphsResult = _buildGraphsFactory.Create(buildGraphResult.Value);

            if (buildGraphsResult.State == Result.Error)
            {
                return(Result.Error);
            }

            var buildGraphs = buildGraphsResult.Value.ToList();

            if (!buildGraphs.Any())
            {
                _logger.Log("Nothing to build.", Result.Error);
                return(Result.Error);
            }

            var dockerFilesRootPath = _fileSystem.UniqueName;
            var contextStreamResult = await _contextFactory.Create(dockerFilesRootPath, buildGraphResult.Value.Nodes.Select(i => i.Value).OfType <Image>().Select(i => i.File));

            if (contextStreamResult.State == Result.Error)
            {
                return(Result.Error);
            }

            var contextStream = contextStreamResult.Value;

            using (contextStream)
                using (_logger.CreateBlock("Build"))
                {
                    foreach (var buildGraph in buildGraphs)
                    {
                        var nameResult = _nodesDescriptionFactory.Create(buildGraph.Nodes);
                        var name       = nameResult.State != Result.Error ? nameResult.Value.Name : "Unnamed graph";
                        if (!string.IsNullOrWhiteSpace(_options.FilterRegex) && !new Regex(_options.FilterRegex).IsMatch(name))
                        {
                            _logger.Log($"\"{name}\" was skipped according to filter \"{_options.FilterRegex}\".", Result.Warning);
                            continue;
                        }

                        using (_logger.CreateBlock(name))
                        {
                            var buildPath = _buildPathProvider.GetPath(buildGraph).ToList();
                            foreach (var buildNode in buildPath)
                            {
                                switch (buildNode.Value)
                                {
                                case Image image:
                                    var dockerFile = image.File;
                                    using (_logger.CreateBlock(dockerFile.ToString()))
                                    {
                                        var id     = Guid.NewGuid().ToString();
                                        var labels = new Dictionary <string, string> {
                                            { "InternalImageId", id }
                                        };

                                        var tags = (
                                            from tag in dockerFile.Tags
                                            select $"{dockerFile.ImageId}:{tag}")
                                                   .Distinct()
                                                   .ToList();

                                        contextStream.Position = 0;
                                        var dockerFilePathInContext = _pathService.Normalize(Path.Combine(dockerFilesRootPath, dockerFile.Path));
                                        var buildParameters         = new ImageBuildParameters
                                        {
                                            Dockerfile = dockerFilePathInContext,
                                            Tags       = tags,
                                            PullParent = true,
                                            Labels     = labels
                                        };

                                        using (var buildEventStream = await _dockerClient.Images.BuildImageFromDockerfileAsync(
                                                   contextStream,
                                                   buildParameters,
                                                   _cancellationTokenSource.Token))
                                        {
                                            _streamService.ProcessLines(buildEventStream, line => { _messageLogger.Log(line); });
                                        }

                                        var filter = new Dictionary <string, IDictionary <string, bool> >
                                        {
                                            { "label", labels.ToDictionary(i => $"{i.Key}={i.Value}", _ => true) }
                                        };

                                        var images = await _dockerClient.Images.ListImagesAsync(new ImagesListParameters { Filters = filter });

                                        if (images.Count == 0)
                                        {
                                            _logger.Log($"Error while building the image {dockerFile}", Result.Error);
                                            return(Result.Error);
                                        }
                                    }

                                    break;
                                }
                            }
                        }
                    }
                }

            return(Result.Success);
        }