Beispiel #1
0
        public static async Task <long> Execute(string containerId)
        {
            // container may be up but postgres might not quite be fully started yet
            using (var config = DockerClientConfigurationFactory.Create())
                using (var client = config.CreateClient())
                {
                    var createArgs = new ContainerExecCreateParameters
                    {
                        AttachStdin  = true,
                        AttachStdout = true,
                        Cmd          = new List <string>()
                        {
                            "pg_isready",
                            // "-h blah" // to test failures
                        },
                        Tty          = true,
                        AttachStderr = true,
                        Detach       = true
                    };

                    var created = await client.Containers.ExecCreateContainerAsync(containerId, createArgs);

                    await client.Containers.StartContainerExecAsync(created.ID);

                    // pg_isready returns 0 to the shell if the server is accepting connections normally,
                    // 1 if the server is rejecting connections (for example during startup),
                    // 2 if there was no response to the connection attempt,
                    // and 3 if no attempt was made (for example due to invalid parameters).
                    var result = await client.Containers.InspectContainerExecAsync(created.ID);

                    return(result.ExitCode);
                }
        }
Beispiel #2
0
        public async Task <ExecResult> ExecAsync(string id, IList <string> command, CancellationToken ct = default)
        {
            this.logger.ExecuteCommandInDockerContainer(id, command);

            var execCreateParameters = new ContainerExecCreateParameters
            {
                Cmd          = command,
                AttachStdout = true,
                AttachStderr = true,
            };

            var execCreateResponse = await this.Docker.Exec.ExecCreateContainerAsync(id, execCreateParameters, ct)
                                     .ConfigureAwait(false);

            using (var stdOutAndErrStream = await this.Docker.Exec.StartAndAttachContainerExecAsync(execCreateResponse.ID, false, ct)
                                            .ConfigureAwait(false))
            {
                var(stdout, stderr) = await stdOutAndErrStream.ReadOutputToEndAsync(ct)
                                      .ConfigureAwait(false);

                var execInspectResponse = await this.Docker.Exec.InspectContainerExecAsync(execCreateResponse.ID, ct)
                                          .ConfigureAwait(false);

                return(new ExecResult(stdout, stderr, execInspectResponse.ExitCode));
            }
        }
Beispiel #3
0
        public static async Task InvokeCommand(
            ContainerExecCreateParameters parameters,
            IImageSettings settings)
        {
            ContainerExecCreateResponse response = await _client.Containers
                                                   .ExecCreateContainerAsync(
                settings.ContainerId,
                parameters);

            if (!string.IsNullOrEmpty(response.ID))
            {
                using (MultiplexedStream stream = await _client.Containers
                                                  .StartAndAttachContainerExecAsync(
                           response.ID, false))
                {
                    (string stdout, string stderr)output = await stream
                                                           .ReadOutputToEndAsync(CancellationToken.None);

                    if (!string.IsNullOrEmpty(output.stderr) && output.stderr.Contains("error"))
                    {
                        var error = new StringBuilder();
                        error.AppendLine($"Error when invoking command \"{string.Join(" ", parameters.Cmd)}\"");
                        error.AppendLine(output.stderr);

                        throw new ContainerException(error.ToString());
                    }
                }
            }
        }
Beispiel #4
0
        public void Accept()
        {
            var execParameters = new ContainerExecCreateParameters {
                Cmd = new[] { "/opt/ripple/bin/rippled", "ledger_accept", "--conf", "/etc/opt/ripple/rippled.cfg" },
            };

            var exec = Client.Exec.ExecCreateContainerAsync(ID, execParameters).Result;

            Client.Exec.StartContainerExecAsync(exec.ID).Wait();
        }
Beispiel #5
0
 private CreateDbCommand(
     string dbname,
     ContainerResourceSettings settings)
 {
     Parameters = GetContainerExecParameters(
         $@"CREATE DATABASE {dbname};
            CREATE ROLE developer_{dbname};
            GRANT alter,create,delete,drop,index,insert,select,update,trigger,alter routine,
                     create routine, execute, create temporary tables 
            ON {dbname}.* 
            TO '{settings.Username}';",
         settings);
 }
        /// <inheritdoc />
        public async Task <(string stdout, string stderr)> ExecuteCommand(params string[] command)
        {
            if (ContainerInfo == null)
            {
                throw new InvalidOperationException(
                          "Container must be started before mapped ports can be retrieved");
            }

            var parameters = new ContainerExecCreateParameters
            {
                AttachStderr = true, AttachStdout = true, Cmd = command
            };

            var response = await DockerClient.Containers.ExecCreateContainerAsync(ContainerId, parameters);

            var stream = await DockerClient.Containers.StartAndAttachContainerExecAsync(response.ID, false);

            return(await stream.ReadOutputToEndAsync(default));
Beispiel #7
0
        public async Task <string> Post([FromBody] string id)
        {
            var request = new ContainerExecCreateParameters()
            {
                Tty          = true,
                AttachStderr = true,
                AttachStdin  = true,
                AttachStdout = true,
                Cmd          = new List <string>()
                {
                    "sh"
                },
                DetachKeys = "ctrl-p,ctrl-q"
            };
            var resp = await client.Exec.ExecCreateContainerAsync(id, request);

            return(resp.ID);
        }
Beispiel #8
0
        public async Task <ContainerExecCreateResponse> ExecCreateContainerAsync(string id, ContainerExecCreateParameters parameters)
        {
            if (string.IsNullOrEmpty(id))
            {
                throw new ArgumentNullException(nameof(id));
            }

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

            var data     = new JsonRequestContent <ContainerExecCreateParameters>(parameters, this._client.JsonSerializer);
            var response = await this._client.MakeRequestAsync(new[] { NoSuchContainerHandler }, HttpMethod.Post, $"containers/{id}/exec", null, data).ConfigureAwait(false);

            return(this._client.JsonSerializer.DeserializeObject <ContainerExecCreateResponse>(response.Body));
        }
Beispiel #9
0
        public static async Task <long> Execute(string containerId, string filename, string logFilename)
        {
            Trace.WriteLine($"Initializing docker client");

            using (var config = DockerClientConfigurationFactory.Create())
                using (var client = config.CreateClient())
                {
                    var createArgs = new ContainerExecCreateParameters
                    {
                        AttachStdin  = true,
                        AttachStdout = true,

                        // psql -U postgres -f home/path/script.sql -v ON_ERROR_STOP=1
                        Cmd = new List <string>()
                        {
                            //"bash",
                            //"/usr/lib/postgresql/11/bin/psql",
                            "touch /home/test.txt",
                            //"-U postgres",
                            //@"-c \'l'"
                            //"-e",
                            //$"-f {filename}",
                            //$"-L {logFilename}",
                            //"-v",
                            //"ON_ERROR_STOP=1"
                        },
                        Tty          = false,
                        AttachStderr = true,
                        Detach       = false,
                        //Privileged = true
                    };

                    Trace.WriteLine($"exec create for container {containerId}");
                    var created = await client.Containers.ExecCreateContainerAsync(containerId, createArgs);

                    Trace.WriteLine($"starting container execution for created id {created.ID}");
                    await client.Containers.StartContainerExecAsync(created.ID);

                    ContainerExecInspectResponse result;

                    do
                    {
                        /*
                         * psql returns 0 to the shell if it finished normally,
                         * 1 if a fatal error of its own occurs (e.g. out of memory, file not found),
                         * 2 if the connection to the server went bad and the session was not interactive,
                         * and 3 if an error occurred in a script and the variable ON_ERROR_STOP was set.
                         */
                        result = await client.Containers.InspectContainerExecAsync(created.ID);

                        Trace.WriteLine($"Inspect result => Pid: {result.Pid}, running: {result.Running}, exit code: {result.ExitCode}");

                        var logArgs = new ContainerLogsParameters
                        {
                            ShowStderr = true,
                            ShowStdout = true
                        };

                        using (var logStream = await client.Containers.GetContainerLogsAsync(containerId, logArgs))
                            using (var reader = new StreamReader(logStream))
                            {
                                var logs = reader.ReadToEnd();
                                Trace.WriteLine(logs);
                            }

                        await Task.Delay(250);
                    } while (result.Running);

                    return(result.ExitCode);
                }
        }
        public static async Task <bool> RunCommandAsync(string command, string containerId)
        {
            //const string id = "EOSCDT";

            try
            {
                var echo = Encoding.UTF8.GetBytes("ls -al");
                //var ping = Encoding.UTF8.GetBytes("/bin/ping -c 3 127.0.0.1");
                //var cmdToExecuteCP = Encoding.UTF8.GetBytes("cp -R /data /eosio.contracts/ \n");
                var cmdToExecute = Encoding.UTF8.GetBytes(command + "\n");

                var config = new ContainerExecCreateParameters
                {
                    AttachStderr = true,
                    AttachStdin  = true,
                    AttachStdout = true,
                    Cmd          = new string[] { "env", "TERM=xterm-256color", "bash" },
                    Detach       = false,
                    Tty          = false,
                    User         = "******",
                    Privileged   = true
                };

                var execId = await client.Containers.ExecCreateContainerAsync(containerId, config);

                logger.Info("ExecCreateContainerAsync {0}", execId.ID);

                var configStart = new ContainerExecStartParameters
                {
                    AttachStderr = true,
                    AttachStdin  = true,
                    AttachStdout = true,
                    Cmd          = new string[] { "env", "TERM=xterm-256color", "bash" },
                    Detach       = false,
                    Tty          = false,
                    User         = "******",
                    Privileged   = true
                };

                var buffer = new byte[1024];
                using (var stream = await client.Containers.StartWithConfigContainerExecAsync(execId.ID, configStart, default(CancellationToken)))
                {
                    //await stream.WriteAsync(cmdToExecuteCP, 0, cmdToExecuteCP.Length, default(CancellationToken));
                    await stream.WriteAsync(cmdToExecute, 0, cmdToExecute.Length, default(CancellationToken));

                    stream.CloseWrite();

                    var result = await stream.ReadOutputAsync(buffer, 0, buffer.Length, default(CancellationToken));

                    do
                    {
                        String printMe = Encoding.UTF8.GetString(buffer, 0, result.Count);
                        // Strip the local docker path from the output so that when VSCode get it, it can treat it as a relative path
                        logger.Info(printMe.Replace("/data/", ""));
                        result = await stream.ReadOutputAsync(buffer, 0, buffer.Length, default(CancellationToken));
                    }while (!result.EOF);

                    logger.Info("End EOSIO contract build");
                }
            }
            catch (Exception ex)
            {
                logger.Error("x" + ex.Message);
                logger.Error("x" + ex.InnerException);
                logger.Error(ex.StackTrace);
            }

            return(true);
        }
        public async Task ExecContainerAsync(string jobName, string instanceParam, ILogger logger, CancellationToken cancellationToken = default(CancellationToken))
        {
            var execConfig = readParameters <DockerExecParamsModel>(jobName);

            if (string.IsNullOrWhiteSpace(execConfig.containerId))
            {
                throw new Exception($"No containerId for launchConfig ");
            }

            if (null == execConfig.commands || execConfig.commands.Length == 0 ||
                string.IsNullOrWhiteSpace(execConfig.commands[0]))
            {
                throw new Exception($"No command for launchConfig ");
            }


            var client = createDockerClient();

            var cmd = execConfig.commands;

            if (!string.IsNullOrEmpty(instanceParam))
            {
                cmd = cmd.Concat(new[] { instanceParam }).ToArray();
            }

            ///
            if (!execConfig.runNakedCommand)
            {
                cmd = new[] { "bash", "-c", $"if {string.Join(" ", cmd)}; then echo all done; else echo NESCHEDULAR_COMMAND_FAILED; fi" };
            }

            logger.LogDebug("Running command " + string.Join(" ", cmd));

            ContainerExecCreateResponse created;
            var createParams = new ContainerExecCreateParameters
            {
                AttachStderr = true,
                AttachStdin  = true,
                AttachStdout = true,
                Cmd          = cmd,
                Detach       = false,
                Tty          = false
            };

            try
            {
                created = await client.Containers.ExecCreateContainerAsync(execConfig.containerId, createParams);
            }
            catch (DockerApiException ex)
            {
                logger.LogInformation(ex, $"container :{execConfig.containerId} is not running. We will attempt to start it");

                if (!await client.Containers.StartContainerAsync(execConfig.containerId, new ContainerStartParameters {
                }, cancellationToken))
                {
                    throw new Exception("failed to start container");
                }

                created = await client.Containers.ExecCreateContainerAsync(execConfig.containerId, createParams);
            }

            using (var containerStream = await client.Containers.StartAndAttachContainerExecAsync(created.ID, false, cancellationToken))
            {
                var  buffer              = new byte[1024];
                bool isError             = false;
                var  currentOutputString = string.Empty;
                var  containerLogs       = string.Empty;
                while (true)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    Array.Clear(buffer, 0, buffer.Length);

                    var result = await containerStream.ReadOutputAsync(buffer, 0, buffer.Length, cancellationToken);

                    var output = Encoding.UTF8.GetString(buffer, 0, result.Count);
                    containerLogs += output;

                    //seems like we don't get error messages in all cases
                    if (output.Contains(@" exec failed") || output.Contains(@"NESCHEDULAR_COMMAND_FAILED"))
                    {
                        isError = true;
                    }

                    var splitted = (currentOutputString + output).Split('\n');

                    //sometime buffer returns in mid string. we always want to LOg complete strings
                    var toLog = string.Join("\n", splitted.SkipLast(1)).Trim();
                    if (!string.IsNullOrWhiteSpace(toLog))
                    {
                        logger.LogDebug(new EventId(0, "output"), "{jobName} ->{log}", jobName, toLog);
                    }

                    currentOutputString = splitted.Last();

                    /* There are all sort of scripts that write to stdErr even if success
                     * if (null == errorString && MultiplexedStream.TargetStream.StandardError == result.Target)
                     * {
                     *  errorString = output;
                     * }
                     */

                    if (result.EOF)
                    {
                        if (!string.IsNullOrWhiteSpace(currentOutputString))
                        {
                            logger.LogDebug(new EventId(0, "output"), "{jobName} ->{log}", jobName, currentOutputString);
                        }
                        break;
                    }
                }

                if (isError)
                {
                    throw new Exception("Run failed with error :\n" + containerLogs);
                }
            }
        }
        protected async Task <ConnectionSettings> GetConnectionSettings(string dbName = null)
        {
            DockerClientConfiguration dockerClientConfiguration;

//            var dockerClient = new DockerClientConfiguration()
//                .CreateClient();
//
            if (Environment.OSVersion.Platform == PlatformID.Unix ||
                Environment.OSVersion.Platform == PlatformID.MacOSX)
            {
                dockerClientConfiguration = new DockerClientConfiguration(
                    new Uri("unix:///var/run/docker.sock"));
            }
            else
            {
                dockerClientConfiguration = new DockerClientConfiguration(
                    new Uri("npipe://./pipe/docker_engine"));
            }

            var dockerClient = dockerClientConfiguration.CreateClient();
            var parameters   = new CreateContainerParameters
            {
                Name  = "my_sql",
                Image = "mysql:5.7",
                Env   = new List <string>()
                {
                    "MYSQL_ROOT_PASSWORD=pass"
                },
                HostConfig = new HostConfig
                {
                    Binds = new List <string>()
                    {
                        "D:\\backups:/backups"
                    },                                                   //Create volumes binding to share folder
                    PortBindings = new Dictionary <string, IList <PortBinding> >
                    {
                        { "3306/tcp", new[] { new PortBinding {
                                                  HostPort = "3306"
                                              } } }
                    }
                }
            };

            var container = await dockerClient.Containers.CreateContainerAsync(parameters);

            await dockerClient.Containers.StartContainerAsync(container.ID, null);

//Create backup
            var createParams = new ContainerExecCreateParameters()
            {
                Cmd = new List <string>()
                {
                    "/bin/sh", "-c", "mysqldump --all-databases -uroot -ppass > backups/script.sql",
                }
            };

            var exec = await dockerClient.Containers.ExecCreateContainerAsync(container.ID, createParams);

            await dockerClient.Containers.StartContainerExecAsync(exec.ID);


            var connectionSettings = new ConnectionSettings();

            connectionSettings.DbHost     = "localhost";
            connectionSettings.DbUser     = "******";
            connectionSettings.DbPassword = "******";
            connectionSettings.DbPort     = "5432";

            if (dbName == null)
            {
                connectionSettings.DbName = "test_db";
            }
            else
            {
                connectionSettings.DbName = dbName;
            }

            return(connectionSettings);
        }
Beispiel #13
0
 private SqlCommand(
     string command,
     ContainerResourceSettings settings)
 {
     Parameters = GetContainerExecParameters(command, settings);
 }