Exemplo n.º 1
0
        public async Task <string> BuildAsync(IImageFromDockerfileConfiguration configuration, CancellationToken ct = default)
        {
            var image = configuration.Image;

            ITarArchive dockerFileArchive = new DockerfileArchive(configuration.DockerfileDirectory, configuration.Dockerfile, image, this.logger);

            var imageExists = await this.ExistsWithNameAsync(image.FullName, ct)
                              .ConfigureAwait(false);

            if (imageExists && configuration.DeleteIfExists)
            {
                await this.DeleteAsync(image, ct)
                .ConfigureAwait(false);
            }

            var buildParameters = new ImageBuildParameters
            {
                Dockerfile = configuration.Dockerfile,
                Tags       = new[] { image.FullName },
                Labels     = configuration.Labels.ToDictionary(item => item.Key, item => item.Value),
            };

            using (var dockerFileStream = new FileStream(dockerFileArchive.Tar(), FileMode.Open))
            {
                await this.Docker.Images.BuildImageFromDockerfileAsync(buildParameters, dockerFileStream, Array.Empty <AuthConfig>(), new Dictionary <string, string>(), this.traceProgress, ct)
                .ConfigureAwait(false);
            }

            this.logger.DockerImageBuilt(image);
            return(image.FullName);
        }
Exemplo n.º 2
0
        private async Task <string> BuildImageAsync(string imageName, string buildContext)
        {
            var archivePath = Path.Combine(buildContext, "context.tar.gz");

            await CreateTarGz(archivePath, buildContext);

            using var archStream = File.OpenRead(archivePath);
            var buildParameters = new ImageBuildParameters
            {
                Dockerfile = "DockerFile",
                Tags       = new[] { imageName }
            };

            if (startOptions.PrivateDockerRegistry != null)
            {
                buildParameters.AuthConfigs = new Dictionary <string, AuthConfig>
                {
                    { startOptions.PrivateDockerRegistry.Address,
                      new AuthConfig
                      {
                          Username = startOptions.PrivateDockerRegistry.Login,
                          Password = startOptions.PrivateDockerRegistry.Password,
                      } }
                };
            }

            var outStream = await dockerClient.Images.BuildImageFromDockerfileAsync(archStream, buildParameters);

            using var streamReader = new StreamReader(outStream);
            return(await streamReader.ReadToEndAsync());
        }
Exemplo n.º 3
0
        public async Task <string> BuildImage(string contextRoot, string repository, string image, string tag)
        {
            var tarFileName = "build.tar.gz";
            var tarFilePath = Path.Combine(Path.GetTempPath(), tarFileName);

            if (File.Exists(tarFilePath))
            {
                File.Delete(tarFilePath);
            }

            TarFolder(tarFilePath, contextRoot);

            var parameters = new ImageBuildParameters
            {
                Tags = new List <string> {
                    $"{repository}/{image}:{tag}"
                }
            };

            using (FileStream fs = new FileStream(tarFilePath, FileMode.Open))
            {
                var res = await _client.Images.BuildImageFromDockerfileAsync(fs, parameters);

                TextReader reader = new StreamReader(res);
                return(reader.ReadToEnd());
            }
        }
        public async Task <IActionResult> Build([FromBody] BuildRequest req)

        {
            //figure out so
            var auth = new AuthConfig()
            {
                Username = "******",
                Password = System.Environment.GetEnvironmentVariable("dockerpassword")
            };
            var authdict = new Dictionary <string, AuthConfig> {
                { "docker.io", auth }
            };

            _log.LogInformation($"fetching manifest for {req.VSTSDropUri}");
            var    drop          = new DropDownloadCore.VSTSDropProxy(req.VSTSDropUri, "/", req.Pat);
            string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            var    imageparams   = new ImageBuildParameters();

            imageparams.Tags = new List <string> {
                req.tag
            };
            imageparams.AuthConfigs = authdict;

            try
            {
                _log.LogInformation($"Putting {req.VSTSDropUri} in {tempDirectory}");
                await drop.Materialize(tempDirectory);

                using (var tar = CreateTar(tempDirectory))
                {
                    //since apparently we use a tarball for context we don't really need to be in the same pod.
                    _log.LogInformation($"Building t{req.tag}");
                    var image = await _client.Images.BuildImageFromDockerfileAsync(tar, imageparams);

                    using (StreamReader reader = new StreamReader(image))
                    {
                        _log.LogInformation(await reader.ReadToEndAsync());
                    }
                    _log.LogInformation($"Pushing image");
                    await _client.Images.PushImageAsync(req.tag, new ImagePushParameters(), auth, new ProgressDumper(_log));
                }
                _log.LogInformation($"Putting {req.VSTSDropUri} in {tempDirectory}");
                return(Ok(tempDirectory));
            }
            finally
            {
                Directory.Delete(tempDirectory, true);
            }
        }
Exemplo n.º 5
0
        public async Task <ImageInfo> CreateImage(Language language, string code)
        {
            if (string.IsNullOrWhiteSpace(code))
            {
                throw new ArgumentException("Код пользователя пустой.", nameof(code));
            }

            var buildId      = Guid.NewGuid().ToString();
            var solutionPath = await this.codeSaver.Save(code, language, buildId);

            var archive = this.codeArchiver.CreateArchive(solutionPath, buildId);

            var imageTag = string.Format(ImageTagFormat, buildId, language.Id.ToLower());

            try
            {
                using (var archiveStream = File.OpenRead(archive))
                {
                    var cts = new CancellationTokenSource(this.maxBuildTime);

                    var buildParams = new ImageBuildParameters
                    {
                        Tags = new List <string> {
                            imageTag
                        },
                        Remove      = true,
                        ForceRemove = true
                    };

                    var stream = await this.dockerClient.Images.BuildImageFromDockerfileAsync(archiveStream, buildParams, cts.Token);

                    await Task.WhenAny(this.ReadToEnd(stream, imageTag, cts.Token), Task.Delay(this.maxBuildTime));

                    if (cts.IsCancellationRequested)
                    {
                        throw new BuildImageException($"Не удалось создать образ с именем {imageTag} за выделенное время");
                    }

                    return(new ImageInfo {
                        Tag = imageTag
                    });
                }
            }
            finally
            {
                File.Delete(archive);
                Directory.Delete(solutionPath, true);
            }
        }
Exemplo n.º 6
0
        public Task <Stream> BuildImageFromDockerfileAsync(Stream contents, ImageBuildParameters parameters, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (contents == null)
            {
                throw new ArgumentNullException(nameof(contents));
            }

            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            var          data            = new BinaryRequestContent(contents, "application/tar");
            IQueryString queryParameters = new QueryString <ImageBuildParameters>(parameters);

            return(this._client.MakeRequestForStreamAsync(this._client.NoErrorHandlers, HttpMethod.Post, "build", queryParameters, data, cancellationToken));
        }
Exemplo n.º 7
0
        public Task <Stream> BuildImageFromDockerfileAsync(Stream contents, ImageBuildParameters parameters, CancellationToken cancellationToken)
        {
            if (contents == null)
            {
                throw new ArgumentNullException("contents");
            }

            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }

            BinaryRequestContent data            = new BinaryRequestContent(contents, "application/tar");
            const string         path            = "build";
            IQueryString         queryParameters = new QueryString <ImageBuildParameters>(parameters);

            return(this.Client.MakeRequestForStreamAsync(this.Client.NoErrorHandlers, HttpMethod.Post, path, queryParameters, data, cancellationToken));
        }
        /// <summary>
        /// Builds an image from a Dockerfile. If possible don't use this approach as it can be brittle.
        /// </summary>
        /// <param name="dockerFile">Dockerfile to build</param>
        /// <param name="contextRelativeToDockerfile">Directory to build the docker file from (normally "." or "..")</param>
        /// <param name="buildParameters">Optional parameters</param>
        public DockerfileImageProvider(FileInfo dockerFile, string contextRelativeToDockerfile, ImageBuildParameters buildParameters = null)
        {
            this.buildParameters = buildParameters ??
                                   new ImageBuildParameters
            {
                Remove = true
            };
            this.dockerfilePath = dockerFile.FullName;
            if (!File.Exists(this.dockerfilePath))
            {
                throw new FileNotFoundException("Could not find Dockerfile", this.dockerfilePath);
            }

            this.dockerContextPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(this.dockerfilePath), contextRelativeToDockerfile));
            if (!Directory.Exists(this.dockerContextPath))
            {
                throw new FileNotFoundException("Could not find docker context", this.dockerContextPath);
            }
        }
Exemplo n.º 9
0
        public Task BuildImageFromDockerfileAsync(ImageBuildParameters parameters, Stream contents, IEnumerable <AuthConfig> authConfigs, IDictionary <string, string> headers, IProgress <JSONMessage> progress, CancellationToken cancellationToken = default)
        {
            if (contents == null)
            {
                throw new ArgumentNullException(nameof(contents));
            }

            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            HttpMethod httpMethod = HttpMethod.Post;

            var data = new BinaryRequestContent(contents, TarContentType);

            IQueryString queryParameters = new QueryString <ImageBuildParameters>(parameters);

            Dictionary <string, string> customHeaders = RegistryConfigHeaders(authConfigs);

            if (headers != null)
            {
                foreach (string key in headers.Keys)
                {
                    customHeaders[key] = headers[key];
                }
            }

            return(StreamUtil.MonitorResponseForMessagesAsync(
                       this._client.MakeRequestForRawResponseAsync(
                           httpMethod,
                           "build",
                           queryParameters,
                           data,
                           customHeaders,
                           cancellationToken),
                       this._client,
                       cancellationToken,
                       progress
                       ));
        }
Exemplo n.º 10
0
        public async Task Build()
        {
            var tag = "1";

            var parameters = new ImageBuildParameters();

            parameters.Tags = new List <string> {
                ImageName + ":" + tag
            };

            using (var httpClient = new HttpClient())
            {
                var response = await httpClient.GetStringAsync("https://raw.githubusercontent.com/emallard/dotnetcore_0/master/Dockerfile");

                File.WriteAllText("../../Dockerfile", response);
            }

            tarHelper.CreateTarFile("../../Dockerfile", "../../Dockerfile.tar");
            var tarStream = new FileStream("../../Dockerfile.tar", FileMode.Open);

            var log = await NSwagDockerClientCreate.BuildImageAsync(
                tarStream,
                ImageName + ":" + tag,
                "https://github.com/emallard/dotnetcore_0.git",
                true,
                false
                );

            await dockerWrapper.DeleteDanglingImages();

            /* Broken pipe problem with Docker.DotNet
             * using (var client = dockerWrapper.GetClient())
             * {
             *  parameters.RemoteContext = "https://github.com/emallard/dotnetcore_0.git";
             *
             *  var stream = await client.Images.BuildImageFromDockerfileAsync(tarStream, parameters);
             *  Console.WriteLine("coucou");
             * }
             */
        }
        protected override void ProcessRecord()
        {
            base.ProcessRecord();

            using (var reader = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.None, 65536))
            {
                var tarTask = Task.Run(async() =>
                {
                    using (var writer = new AnonymousPipeClientStream(PipeDirection.Out, reader.ClientSafePipeHandle))
                    {
                        var tar = new TarWriter(writer);
                        await tar.CreateEntriesFromDirectoryAsync(string.IsNullOrEmpty(Path) ? "." : Path, ".");
                        await tar.CloseAsync();
                        writer.Close();
                    }
                });

                var parameters = new ImageBuildParameters
                {
                    NoCache     = SkipCache.ToBool(),
                    ForceRemove = ForceRemoveIntermediateContainers.ToBool(),
                    Remove      = !PreserveIntermediateContainers.ToBool(),
                };

                string repoTag = null;
                if (!string.IsNullOrEmpty(Repository))
                {
                    repoTag = Repository;
                    if (!string.IsNullOrEmpty(Tag))
                    {
                        repoTag += ":";
                        repoTag += Tag;
                    }
                    parameters.Tags.Add(repoTag);
                }
                else if (!string.IsNullOrEmpty(Tag))
                {
                    throw new Exception("tag without a repo???");
                }

                string imageId = null;
                bool   failed  = false;

                var buildTask = DkrClient.Miscellaneous.BuildImageFromDockerfileAsync(reader, parameters, CancelSignal.Token);
                using (var progress = buildTask.AwaitResult())
                    using (var progressReader = new StreamReader(progress, new UTF8Encoding(false)))
                    {
                        string line;
                        while ((line = progressReader.ReadLine()) != null)
                        {
                            var message = JsonConvert.DeserializeObject <JsonMessage>(line);
                            if (message.Stream != null)
                            {
                                if (message.Stream.StartsWith(_successfullyBuilt))
                                {
                                    // This is probably the image ID.
                                    imageId = message.Stream.Substring(_successfullyBuilt.Length).Trim();
                                }

                                var infoRecord = new HostInformationMessage();
                                infoRecord.Message = message.Stream;
                                WriteInformation(infoRecord, new string[] { "PSHOST" });
                            }

                            if (message.Error != null)
                            {
                                var error = new ErrorRecord(new Exception(message.Error.Message), null, ErrorCategory.OperationStopped, null);
                                WriteError(error);
                                failed = true;
                            }
                        }
                    }

                tarTask.WaitUnwrap();
                if (imageId == null && !failed)
                {
                    throw new Exception("Could not find image, but no error was returned");
                }

                WriteObject(ContainerOperations.GetImageById(imageId, DkrClient));
            }
        }
Exemplo n.º 12
0
        protected override async Task ProcessRecordAsync()
        {
            var directory = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path ?? "");

            // Ensure the path is a directory.
            if (!Directory.Exists(directory))
            {
                throw new DirectoryNotFoundException(directory);
            }

            WriteVerbose(string.Format("Archiving the contents of {0}", directory));

            using (var reader = Archiver.CreateTarStream(new List<string> { directory }, CmdletCancellationToken))
            {
                var parameters = new ImageBuildParameters
                {
                    NoCache = SkipCache.ToBool(),
                    ForceRemove = ForceRemoveIntermediateContainers.ToBool(),
                    Remove = !PreserveIntermediateContainers.ToBool(),
                };

                string repoTag = null;
                if (!string.IsNullOrEmpty(Repository))
                {
                    repoTag = Repository;
                    if (!string.IsNullOrEmpty(Tag))
                    {
                        repoTag += ":";
                        repoTag += Tag;
                    }

                    parameters.Tags = new List<string>
                    {
                        repoTag
                    };
                }
                else if (!string.IsNullOrEmpty(Tag))
                {
                    throw new Exception("You must specify a repository name in order to specify a tag.");
                }

                string imageId = null;
                bool failed = false;

                var progress = new Progress<ProgressReader.Status>();
                var progressRecord = new ProgressRecord(0, "Dockerfile context", "Uploading");
                progress.ProgressChanged += (o, status) =>
                {
                    if (status.Complete)
                    {
                        progressRecord.CurrentOperation = null;
                        progressRecord.StatusDescription = "Processing";
                    }
                    else
                    {
                        progressRecord.StatusDescription = string.Format("Uploaded {0} bytes", status.TotalBytesRead);
                    }

                    WriteProgress(progressRecord);
                };

                var progressReader = new ProgressReader(reader, progress, 512 * 1024);
                var buildTask = DkrClient.Miscellaneous.BuildImageFromDockerfileAsync(progressReader, parameters, CmdletCancellationToken);
                var messageWriter = new JsonMessageWriter(this);

                using (var buildStream = await buildTask)
                {
                    // Complete the upload progress bar.
                    progressRecord.RecordType = ProgressRecordType.Completed;
                    WriteProgress(progressRecord);

                    // ReadLineAsync is not cancellable without closing the whole stream, so register a callback to do just that.
                    using (CmdletCancellationToken.Register(() => buildStream.Close()))
                    using (var buildReader = new StreamReader(buildStream, new UTF8Encoding(false)))
                    {
                        string line;
                        while ((line = await buildReader.ReadLineAsync()) != null)
                        {
                            var message = JsonConvert.DeserializeObject<JsonMessage>(line);
                            if (message.Stream != null && message.Stream.StartsWith(_successfullyBuilt))
                            {
                                // This is probably the image ID.
                                imageId = message.Stream.Substring(_successfullyBuilt.Length).Trim();
                            }

                            if (message.Error != null)
                            {
                                failed = true;
                            }

                            messageWriter.WriteJsonMessage(message);
                        }
                    }
                }

                messageWriter.ClearProgress();
                if (imageId != null)
                {
                    WriteObject(await ContainerOperations.GetImageById(imageId, DkrClient));
                }
                else if (!failed)
                {
                    throw new Exception("Could not find image, but no error was returned");
                }
            }
        }
Exemplo n.º 13
0
        protected override async Task ProcessRecordAsync()
        {
            var directory = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path ?? "");

            // Ensure the path is a directory.
            if (!Directory.Exists(directory))
            {
                throw new DirectoryNotFoundException(directory);
            }

            WriteVerbose(string.Format("Archiving the contents of {0}", directory));

            using (var reader = Archiver.CreateTarStream(new List <string> {
                directory
            }, CmdletCancellationToken))
            {
                var parameters = new ImageBuildParameters
                {
                    NoCache     = SkipCache,
                    ForceRemove = ForceRemoveIntermediateContainers,
                    Remove      = !PreserveIntermediateContainers,
                };

                if (this.Isolation != IsolationType.Default)
                {
                    parameters.Isolation = this.Isolation.ToString();
                }

                string repoTag = null;
                if (!string.IsNullOrEmpty(Repository))
                {
                    repoTag = Repository;
                    if (!string.IsNullOrEmpty(Tag))
                    {
                        repoTag += ":";
                        repoTag += Tag;
                    }

                    parameters.Tags = new List <string>
                    {
                        repoTag
                    };
                }
                else if (!string.IsNullOrEmpty(Tag))
                {
                    throw new Exception("You must specify a repository name in order to specify a tag.");
                }

                string imageId = null;
                bool   failed  = false;

                var progress       = new Progress <ProgressReader.Status>();
                var progressRecord = new ProgressRecord(0, "Dockerfile context", "Uploading");
                progress.ProgressChanged += (o, status) =>
                {
                    if (status.Complete)
                    {
                        progressRecord.CurrentOperation  = null;
                        progressRecord.StatusDescription = "Processing";
                    }
                    else
                    {
                        progressRecord.StatusDescription = string.Format("Uploaded {0} bytes", status.TotalBytesRead);
                    }

                    WriteProgress(progressRecord);
                };

                var progressReader = new ProgressReader(reader, progress, 512 * 1024);
                var buildTask      = DkrClient.Miscellaneous.BuildImageFromDockerfileAsync(progressReader, parameters, CmdletCancellationToken);
                var messageWriter  = new JsonMessageWriter(this);

                using (var buildStream = await buildTask)
                {
                    // Complete the upload progress bar.
                    progressRecord.RecordType = ProgressRecordType.Completed;
                    WriteProgress(progressRecord);

                    // ReadLineAsync is not cancellable without closing the whole stream, so register a callback to do just that.
                    using (CmdletCancellationToken.Register(() => buildStream.Dispose()))
                        using (var buildReader = new StreamReader(buildStream, new UTF8Encoding(false)))
                        {
                            string line;
                            while ((line = await buildReader.ReadLineAsync()) != null)
                            {
                                var message = JsonConvert.DeserializeObject <JsonMessage>(line);
                                if (message.Stream != null && message.Stream.StartsWith(SuccessfullyBuilt))
                                {
                                    // This is probably the image ID.
                                    imageId = message.Stream.Substring(SuccessfullyBuilt.Length).Trim();
                                }

                                if (message.Error != null)
                                {
                                    failed = true;
                                }

                                messageWriter.WriteJsonMessage(message);
                            }
                        }
                }

                messageWriter.ClearProgress();
                if (imageId != null)
                {
                    WriteObject(await ContainerOperations.GetImageById(imageId, DkrClient));
                }
                else if (!failed)
                {
                    throw new Exception("Could not find image, but no error was returned");
                }
            }
        }
Exemplo n.º 14
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);
        }
Exemplo n.º 15
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"))
                {
                    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);
        }
Exemplo n.º 16
0
        public async Task <bool> RunScriptAsync(UserConfiguration config)
        {
            var hs = new HomeControllerService();

            // https://stackoverflow.com/questions/43387693/build-docker-in-asp-net-core-no-such-file-or-directory-error
            // https://stackoverflow.com/questions/2849341/there-is-no-viewdata-item-of-type-ienumerableselectlistitem-that-has-the-key

            // Upload License if provided
            this.UploadFile(config);

            // Upload model input data if provided
            this.UploadModelInputData(config);

            // Generate Dockerfile
            var programDockerfilePath = hs.CreateGamsDockerfile(config);
            var fullpat = Path.GetFullPath(programDockerfilePath);

            // ------- CREATE IMAGE FROM DOCKERFILE
            try
            {
                //// https://github.com/Microsoft/Docker.DotNet/issues/197
                var path = fullpat;

                const string tarFile = "Dockerfile.tar";

                if (!System.IO.File.Exists(tarFile))
                {
                    System.IO.File.Delete(tarFile);
                }

                hs.CreateTarGz(tarFile, path);

                Logger.Log("\n\n\n\n======== DOCKERFILE START =======================================");
                using (var sr = new StreamReader(path))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        Logger.Log(line);
                    }
                }
                Logger.Log("========= DOCKERFILE END ======================================\n\n\n\n\n");

                //hs.DownloadZipDataToFolder("http://geonode_geonode_1/documents/3/download/", @"./OutputZip/data.zip");

                var networks = await Client.Networks.ListNetworksAsync();

                var network = networks.First(x => x.Name.Contains("webinterface_default")); //networks.First(x => x.Name.Contains("geonode"));

                var imageName = "gams/iiasa";
                var tag       = "latest";

                // https://docs.docker.com/edge/engine/reference/commandline/build/
                // https://docs.docker.com/engine/api/v1.25/#operation/ImageList
                var imageBuildParameters = new ImageBuildParameters()
                {
                    Remove      = true,
                    ForceRemove = true,
                    Tags        = new List <string> {
                        imageName + ":" + tag
                    },
                    NetworkMode = network.Name,
                    NoCache     = true
                };

                var errorDetected = false;
                using (var fs = new FileStream(tarFile, FileMode.Open))
                {
                    // https://stackoverflow.com/questions/33997089/how-can-i-create-a-stream-for-dockerdotnet-buildimagefromdockerfile-method
                    var statusUpdate = await Client.Images.BuildImageFromDockerfileAsync(
                        fs,
                        imageBuildParameters,
                        CancellationToken.None);

                    using (var streamReader = new StreamReader(statusUpdate))
                    {
                        string line;
                        while ((line = streamReader.ReadLine()) != null)
                        {
                            Logger.Log(line);
                            if (line.ToLower().Contains("error"))
                            {
                                errorDetected = true;
                            }
                        }
                    }

                    fs.Dispose();
                }

                if (errorDetected)
                {
                    Logger.Log("!!! ERRORS DETECTED!!!\nContainer Creation Aborted!");
                    return(false);
                }

                var containerName = imageName.Replace("/", "_") + "_container";

                var containers =
                    await Client.Containers.ListContainersAsync(new ContainersListParameters
                {
                    All = true,
                },
                                                                CancellationToken.None);

                var containerList = containers.ToList();

                foreach (var container in containerList)
                {
                    foreach (var name in container.Names)
                    {
                        if (name.Contains(containerName))
                        {
                            await Client.Containers.RemoveContainerAsync(container.ID,
                                                                         new ContainerRemoveParameters { Force = true });
                        }
                    }
                }

                var containerResponse = await Client.Containers.CreateContainerAsync(new CreateContainerParameters
                {
                    AttachStderr = true,
                    AttachStdin  = true,
                    AttachStdout = true,
                    Image        = imageName,
                    Name         = containerName,
                },
                                                                                     CancellationToken.None);

                var res = await Client.Containers.StartContainerAsync(containerResponse.ID, new ContainerStartParameters(),
                                                                      CancellationToken.None);

                if (res)
                {
                    Logger.Log("=== Container Created and Started ===");

                    var outputResponse = await Client.Containers.GetArchiveFromContainerAsync(containerResponse.ID,
                                                                                              new GetArchiveFromContainerParameters
                    {
                        Path = "/output"
                    },
                                                                                              false,
                                                                                              CancellationToken.None);

                    using (Stream s = System.IO.File.Create("./Result/result.tar"))
                    {
                        outputResponse.Stream.CopyTo(s);
                    }

                    Logger.Log("output finished!");

                    return(true);
                }

                Logger.Log("ERROR\n=== Container Could Not Be Created! ===");
                return(false);
            }
            catch (Exception ex)
            {
                Logger.Log(
                    "=================== ERROR ===========================================================================");
                Logger.Log(ex.Message); //ex.FullMessage());

                if (ex.InnerException != null)
                {
                    Logger.Log(ex.InnerException.Message);
                }

                Logger.Log(
                    "=====================================================================================================");

                return(false);
            }
        }
 /// <summary>
 /// Builds an image from a Dockerfile in the solution's folder with a matching label.
 /// </summary>
 /// <param name="label">Label to match</param>
 /// <param name="contextRelativeToDockerfile">Directory to build the docker file from (normally "." or "..")</param>
 /// <param name="buildParameters">Optional parameters</param>
 /// <param name="locator">Locates Dockerfile</param>
 public DockerfileImageProvider(KeyValuePair <string, string> label, string contextRelativeToDockerfile, ImageBuildParameters buildParameters = null, IDockerfileLocator locator = null)
     : this((locator ?? new DockerfileLocator()).GetDockerfile(label), contextRelativeToDockerfile, buildParameters)
 {
 }
 /// <summary>
 /// Builds an image from a Dockerfile in the solution's folder with a matching "project" label.
 /// </summary>
 /// <param name="projectName">Value of the project label</param>
 /// <param name="contextRelativeToDockerfile">Directory to build the docker file from (normally "." or "..")</param>
 /// <param name="buildParameters">Optional parameters</param>
 /// <param name="locator">Locates Dockerfile</param>
 public DockerfileImageProvider(string projectName, string contextRelativeToDockerfile, ImageBuildParameters buildParameters = null, IDockerfileLocator locator = null)
     : this(new KeyValuePair <string, string>("project", projectName), contextRelativeToDockerfile, buildParameters, locator)
 {
 }
Exemplo n.º 19
0
        protected override async Task <int> ExecuteAsync(CommandContext context, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(Name))
            {
                Console.WriteLine("No name was specified.");
                return(1);
            }

            var tag = $"{DeviceType.ToLower()}-agent-{Name.Trim().ToLower()}";

            using (var temporaryFile = new TemporaryFile())
            {
                //Create the tar in a temporary place
                TarUtil.CreateTarGZ(temporaryFile.Path, Source);

                //Create the docker client
                using (var dockerClient = CreateDockerClient())
                {
                    //Open up the temp file
                    using (var tarStream = File.OpenRead(temporaryFile.Path))
                    {
                        //Set up the build
                        var imageBuildParmeters = new ImageBuildParameters
                        {
                            Tags = new List <string>
                            {
                                tag
                            },
                            Dockerfile = $"{DeviceType}.Agent.Dockerfile"
                        };

                        BuildResult result;

                        //Build it!!!!!
                        using (var resultStream =
                                   await dockerClient.Images.BuildImageFromDockerfileAsync(tarStream, imageBuildParmeters,
                                                                                           cancellationToken))
                        {
                            //Deal with the result
                            result = await resultStream.ProcessBuildStreamAsync();
                        }

                        //Check to see if we have any errors
                        if (result.Errors.Any())
                        {
                            Console.WriteLine($"Build completed with {result.Errors.Count} errors.");

                            return(1);
                        }

                        //Let us deploy
                        if (Deploy)
                        {
                            return(await DeployAsync(context, dockerClient, result, tag, cancellationToken));
                        }

                        await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);

                        return(0);
                    }
                }
            }
        }
        /// <summary>
        /// Runs the docker image build command to build this image
        /// </summary>
        /// <inheritdoc />
        public override async Task <string> Resolve(CancellationToken ct = default)
        {
            if (ct.IsCancellationRequested)
            {
                return(null);
            }

            if (DeleteOnExit)
            {
                ResourceReaper.RegisterImageForCleanup(ImageName, DockerClient);
            }

            _logger.LogDebug("Begin building image: {}", ImageName);

            var tempTarPath = Path.Combine(Path.GetTempPath(), ImageName.Replace('/', '_') + ".tar");

            try
            {
                using (var tempFile = new FileStream(tempTarPath, FileMode.Create))
                    using (var tarArchive = TarArchive.CreateOutputTarArchive(tempFile))
                    {
                        if (!string.IsNullOrWhiteSpace(BasePath))
                        {
                            // the algorithm here is carefully crafted to minimise the use of
                            // Path.GetFullPath. Path.GetFullPath is used very sparingly and
                            // completely avoided in loops. The reason is because Path.GetFullPath
                            // is a very expensive call and can reduce CPU time by at least 1 order
                            // of magnitude if avoided
                            var fullBasePath = Path.GetFullPath(OS.NormalizePath(BasePath));

                            var ignoreFullPaths = GetIgnores(fullBasePath);

                            // sending a full path will result in entries with full path
                            var allFullPaths = GetAllFilesInDirectory(fullBasePath);

                            // a thread pool that is starved can decrease the performance of
                            // this method dramatically. Using `AsParallel()` will circumvent such issues.
                            // as a result, methods and classes used by this needs to be thread safe.
                            var validFullPaths = allFullPaths
                                                 .AsParallel()
                                                 .Where(f => !IsFileIgnored(ignoreFullPaths, f));

                            foreach (var fullPath in validFullPaths)
                            {
                                // we can safely perform a substring without expanding the paths
                                // using Path.GetFullPath because we know fullBasePath has already been
                                // expanded and the paths in validFullPaths are derived from fullBasePath
                                var relativePath = fullPath.Substring(fullBasePath.Length);

                                // if fullBasePath does not end with directory separator,
                                // relativePath will start with directory separator and that should not be the case
                                if (relativePath.StartsWith(Path.DirectorySeparatorChar.ToString()))
                                {
                                    relativePath = relativePath.Substring(1);
                                }

                                await new MountableFile(fullPath)
                                .TransferTo(tarArchive, relativePath, ct)
                                .ConfigureAwait(false);
                            }

                            _logger.LogDebug("Transferred base path [{}] into tar archive", BasePath);
                        }

                        foreach (var entry in Transferables)
                        {
                            var destinationPath = entry.Key;
                            var transferable    = entry.Value;
                            await transferable
                            .TransferTo(tarArchive, destinationPath, ct)
                            .ConfigureAwait(false);

                            _logger.LogDebug("Transferred [{}] into tar archive", destinationPath);
                        }

                        tarArchive.Close();
                    }

                if (ct.IsCancellationRequested)
                {
                    return(null);
                }

                var buildImageParameters = new ImageBuildParameters
                {
                    Dockerfile = DockerfilePath,
                    Labels     = DeleteOnExit ? ResourceReaper.Labels : null,
                    Tags       = new List <string> {
                        ImageName
                    }
                };

                using (var tempFile = new FileStream(tempTarPath, FileMode.Open))
                {
                    var output =
                        await DockerClient.Images.BuildImageFromDockerfileAsync(tempFile, buildImageParameters, ct);

                    using (var reader = new StreamReader(output))
                    {
                        while (!reader.EndOfStream)
                        {
                            _logger.LogTrace(reader.ReadLine());
                        }
                    }
                }
            }
            finally
            {
                File.Delete(tempTarPath);
            }

            _logger.LogInformation("Dockerfile image built: {}", ImageName);

            // we should not catch exceptions thrown by inspect because the image is
            // expected to be available since we've just built it
            var image = await DockerClient.Images.InspectImageAsync(ImageName, ct);

            ImageId = image.ID;

            return(ImageId);
        }