in tool/TeamCity.Docker/BuildCommand.cs [67:174]
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;
}