dotnet / Docker.DotNet

:whale: .NET (C#) Client Library for Docker API
https://www.nuget.org/packages/Docker.DotNet/
MIT License
2.23k stars 381 forks source link

Need help with writing an interactive client #628

Open ghost opened 1 year ago

ghost commented 1 year ago

Currently i am trying to write an interactive client, like the terminal in Docker Desktop.

I tried the approch from Ticket #479 , but this would lead to crash of the pipline or no result.

Could anyone provide a better documentation from the exec interface or sample? I made also a sample, but this wouldn't work in my case. I want it to be like a ssh console.

public static async Task SendCommand(DockerClient client, string msysql, string command)
        {
            var execCreateParameters = new ContainerExecCreateParameters
            {
                Cmd = command.Split(' '),
                AttachStdin = true,
                AttachStdout = true,
                AttachStderr = true,
            };

            var execCreateResponse = await client.Exec.ExecCreateContainerAsync(msysql, execCreateParameters, default(CancellationToken));

            using (var stdOutAndErrStream = await client.Exec.StartAndAttachContainerExecAsync(execCreateResponse.ID, false, default(CancellationToken)))
            {
                var (stdout, stderr) = await stdOutAndErrStream.ReadOutputToEndAsync(default(CancellationToken));

                var execInspectResponse = await client.Exec.InspectContainerExecAsync(execCreateResponse.ID, default(CancellationToken));

                Console.WriteLine($"Standard Out: {stdout}");
                Console.WriteLine($"Standard Error: {stderr}");
                Console.WriteLine($"Exit Code: {execInspectResponse.ExitCode}");
                Console.Read();
            }
        }
ueadian commented 1 year ago

I'm convinced this feature is broken at the moment. I made a ticket over a month ago about having the same issues. Attaching to a container is not working at the moment, I spent 30+ hours trying various ways of doing it and could never get it to work. I had better luck making my own WebSocket attach using the Docker API's websocket attach. Still doesn't work well though, seems Go or another language is better for this particular use case.

HofmeisterAn commented 1 year ago

Executing a command inside a container works fine in Testcontainers.

galvesribeiro commented 1 year ago

Although I agree the implementation of the attach (and any streaming APIs) inside Docker.DotNet is not ideal right now, it should work.

ghost commented 1 year ago

Sending commands does work, but its far away from working like a ssh console(or interactive client), which would be my goal. I had multiple connection losses trying to send one command and then retrieving the console. Also if this would work, it would still be no interactive client, because after the command was sent i can't send another in the same session with ExecCreateContainerAsync, please correct me if i am wrong.

HofmeisterAn commented 1 year ago

I think you may be using the wrong API. I assume that the exec endpoint closes the connection along with the termination of the process. You may want to try attaching to the container instead.

ghost commented 1 year ago

Thanks for the provided documentation, do you also have any samples of the usage of this interface? I already tried attaching like in the ticket #479 with stdin and stdout, but this also didn't worked very well

HofmeisterAn commented 1 year ago

Not specific to the input stream, I just used it to continuously read the output streams. I would guess that if you use a simple bash as the entry point, it should work. Perhaps you could share a small reproducer as an example.