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); } }
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)); } }
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()); } } } }
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(); }
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));
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); }
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)); }
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); }
private SqlCommand( string command, ContainerResourceSettings settings) { Parameters = GetContainerExecParameters(command, settings); }