Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support '--detach-keys' for 'nerdctl (run|start)' #2128

Merged
merged 1 commit into from
Jun 11, 2023

Conversation

davidhsingyuchen
Copy link
Contributor

@davidhsingyuchen davidhsingyuchen commented Mar 23, 2023

Control Flow

  1. Detect if the detach keys are present in stdin.
  2. After detecting the detach keys, cancel the current I/O operations. This means that the underlying I/O FIFOs should be left intact, and containerd should keep writing to/reading from those FIFOs, but nerdctl should stop writing to/reading from them. It seems that cio.IO.Cancel() should be used for this, but there's an issue: IO.Cancel() becomes a no-op if the FIFOs are already opened containerd#8326.
  3. After starting the task, we need to call IO.Wait, and after it returns, we need to see if the container exits or it's just the user detaching from the container by checking the state of the container.

Notes

  • It may be better to support nerdctl exec --detach-keys in a follow-up PR so that we can minimize the changes needed in this PR as the control flow of it is a bit different from that of run|start.

TODOs

Before this PR can be merged, I need to:

  • Revert the temporarily use the containerd feature branch commit and use the released containerd version.

@davidhsingyuchen
Copy link
Contributor Author

@AkihiroSuda PTAL, thanks!

@davidhsingyuchen davidhsingyuchen changed the title [WIP] feat: support '--detach-keys' for 'nerdctl (run|start|exec)' [WIP, but PTAL] feat: support '--detach-keys' for 'nerdctl (run|start|exec)' Mar 28, 2023
go.mod Outdated Show resolved Hide resolved
pkg/consoleutil/detach.go Outdated Show resolved Hide resolved
Comment on lines 58 to 60
if ds.closed {
return 0, syscall.EBADF
}
Copy link
Member

@fahedouch fahedouch Mar 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if this condition is relevant here (is it possible to read from already closed (detached) stdin ?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're right. It turned out IO.Cancel() doesn't really close the FIFOs (containerd/containerd#8326), so if this check is removed, closer() will keep being called, and the debug logs (i.e., "Cancelling IO" and "IO cancelled") will overflow my screen. As a result, when term.EscapeError is detected, I'm returning a non-nil error for now , and I added a TODO to return a nil error afrer the issue is fixed and before this PR can be merged.

pkg/taskutil/taskutil.go Outdated Show resolved Hide resolved
closed bool
}

// NewDetachableStdin returns a new TTY proxy reader
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NewDetachableStdin returns a new detachableStdin which uses a TTY proxy reader to read specified detach keys from stdin, in which case closer will be called

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'm not sure if we want to mention the underlying unexported struct here, maybe the users of this function shouldn't need to know that implementation detail?

Copy link
Member

@fahedouch fahedouch Mar 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but just one thing was confusing me : NewDetachableStdin returns a new TTY proxy reader. In fact the NewDetachableStdin is not returning a TTY proxy reader but it is wrapping a a TTY proxy reader

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah you're right! Updated the comment accordingly, plz let me know if it works for you :)

@fahedouch
Copy link
Member

fahedouch commented Mar 29, 2023

After detecting the detach keys, cancel the current I/O operations. This means that the underlying I/O FIFOs should be left intact, and containerd should keep writing to/reading from those FIFOs, but nerdctl should stop writing to/reading from them. It seems that cio.IO.Cancel() should work, but I'm not 100% sure due to the nil IO() thing below.

Cancel will aborts all current io operations ( from nerdctl and containerd). but nerdctl is fully controlling the io of the task (nerdctl is creating task with specefic io) , so I am wondering why not making task.CloseIO() ( this will abort io and clean fifos) , I also think that we no longer use the exsiting fifos after detach

@davidhsingyuchen
Copy link
Contributor Author

After detecting the detach keys, cancel the current I/O operations. This means that the underlying I/O FIFOs should be left intact, and containerd should keep writing to/reading from those FIFOs, but nerdctl should stop writing to/reading from them. It seems that cio.IO.Cancel() should work, but I'm not 100% sure due to the nil IO() thing below.

Cancel will aborts all current io operations ( from nerdctl and containerd). but nerdctl is fully controlling the io of the task (nerdctl is creating task with specefic io) , so I am wondering why not making task.CloseIO() ( this will abort io and clean fifos) , I also think that we no longer use the exsiting fifos after detach

After we detach from a container, we should be able to reattach to it again. Docker:

~ docker attach test
/ #
/ #
/ # read escape sequence~ docker attach test
/ #
/ #
/ # read escape sequence

@davidhsingyuchen davidhsingyuchen force-pushed the detach-keys branch 5 times, most recently from 1305692 to 585588c Compare March 29, 2023 20:50
@davidhsingyuchen davidhsingyuchen changed the title [WIP, but PTAL] feat: support '--detach-keys' for 'nerdctl (run|start|exec)' [WIP, but PTAL] feat: support '--detach-keys' for 'nerdctl (run|start)' Mar 29, 2023
@davidhsingyuchen davidhsingyuchen requested review from fahedouch and removed request for yuchanns March 29, 2023 21:09
@davidhsingyuchen davidhsingyuchen force-pushed the detach-keys branch 2 times, most recently from 8047c15 to cce73c3 Compare March 29, 2023 23:29
cmd/nerdctl/container_run_test.go Outdated Show resolved Hide resolved
cmd/nerdctl/container_run_test.go Outdated Show resolved Hide resolved
cmd/nerdctl/container_run_test.go Outdated Show resolved Hide resolved
@davidhsingyuchen
Copy link
Contributor Author

@fahedouch Thanks a lot for the quick review! In the new revision, besides addressing the comments, I also made it print read detach keys when detaching from the container so that it's clearer to the users what's happening, and it's also aligned to UX of docker. Also updated e2e tests accordingly.

@davidhsingyuchen
Copy link
Contributor Author

davidhsingyuchen commented Mar 31, 2023

The latest revision: If I replace containerd/containerd in nerdctl's go.mod with the version from containerd/containerd#8334, it seems to be working.

davidhyc@lima-dev:/Users/davidhyc/dev/containerd/nerdctl$ ./_output/nerdctl run -it --name detach busybox
/ #
/ # INFO[0001] read detach keys
davidhyc@lima-dev:/Users/davidhyc/dev/containerd/nerdctl$ nerdctl ps -a
CONTAINER ID    IMAGE                               COMMAND    CREATED          STATUS    PORTS    NAMES
fd3b77abf607    docker.io/library/busybox:latest    "sh"       4 seconds ago    Up                 detach

@fahedouch
Copy link
Member

@davidhsingyuchen

It seems that cio.IO.Cancel() should be used for this, but there's an issue: containerd/containerd#8326.

please see

@AkihiroSuda
Copy link
Member

Needs rebase

@davidhsingyuchen
Copy link
Contributor Author

@AkihiroSuda Thank you for the reminder. Could you help take a look at containerd/containerd#8326 and/or containerd/containerd#8334? I'll rebase the feature branch after the blocker is resolved, thanks!

@davidhsingyuchen davidhsingyuchen force-pushed the detach-keys branch 3 times, most recently from a0635be to 8e25eae Compare June 6, 2023 23:33
@davidhsingyuchen davidhsingyuchen changed the title [WIP, but PTAL] feat: support '--detach-keys' for 'nerdctl (run|start)' feat: support '--detach-keys' for 'nerdctl (run|start)' Jun 7, 2023
@davidhsingyuchen davidhsingyuchen marked this pull request as ready for review June 7, 2023 00:37
@davidhsingyuchen
Copy link
Contributor Author

@fahedouch PTAL, thanks! The failed jobs seem to be flaky as all the jobs pass at least once:

go.mod Outdated
@@ -57,12 +58,14 @@ require (
golang.org/x/term v0.8.0
golang.org/x/text v0.9.0
gopkg.in/yaml.v3 v3.0.1
gotest.tools v2.2.0+incompatible
gotest.tools/v3 v3.4.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid mixing up v2 and v3?

go.mod Outdated
@@ -37,6 +37,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0
github.com/moby/sys/mount v0.3.3
github.com/moby/sys/signal v0.7.0
github.com/moby/term v0.0.0-20221205130635-1aeaba878587
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Control flow:

1. Detect if the detach keys are present in stdin.
2. After detecting the detach keys, cancel the current I/O operations by calling IO.Cancel().
   This means that the underlying I/O FIFOs should be left intact,
   and containerd should keep writing to/reading from those FIFOs,
   but nerdctl should stop writing to/reading from them.
3. After starting the task, we need to call IO.Wait(), and after it returns,
   we need to see if the container exits or it's just the user detaching from the container
   by checking the state of the container.

Signed-off-by: Hsing-Yu (David) Chen <davidhsingyuchen@gmail.com>
@davidhsingyuchen
Copy link
Contributor Author

@AkihiroSuda Thanks for the reminder. Both are fixed.

Copy link
Member

@AkihiroSuda AkihiroSuda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

@fahedouch fahedouch merged commit 8c08e1e into containerd:main Jun 11, 2023
@davidhsingyuchen davidhsingyuchen deleted the detach-keys branch June 12, 2023 16:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants