Skip to content

Commit

Permalink
feat: support '--detach-keys' for 'nerdctl (run|start|exec)'
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhsingyuchen committed Mar 23, 2023
1 parent ea92fda commit 1b2898a
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 2 deletions.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ require (
gotest.tools/v3 v3.4.0
)

require github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect

require (
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 // indirect
Expand Down Expand Up @@ -94,6 +96,7 @@ require (
github.com/moby/locker v1.0.1 // indirect
github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/term v0.0.0-20221205130635-1aeaba878587
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.1.0 // indirect
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652/go.mod
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
Expand Down Expand Up @@ -719,6 +720,8 @@ github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGq
github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs=
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A=
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA=
github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
Expand Down
72 changes: 72 additions & 0 deletions pkg/consoleutil/detach.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package consoleutil

import (
"errors"
"fmt"
"io"
"sync"
"syscall"

"github.com/moby/term"
)

var defaultDetachKeys = "ctrl-p,ctrl-q"

type detachableStdin struct {
stdin io.Reader
closer func()
mu sync.Mutex
closed bool
}

// NewDetachableStdin returns a new TTY proxy reader
// which wraps stdin and detects when the specified detach keys are read,
// in which case closer will be called.
func NewDetachableStdin(stdin io.Reader, keys string, closer func()) (io.Reader, error) {
if len(keys) == 0 {
keys = defaultDetachKeys
}
b, err := term.ToBytes(keys)
if err != nil {
return nil, fmt.Errorf("failed to convert the detach keys to bytes: %w", err)
}
return &detachableStdin{
stdin: term.NewEscapeProxy(stdin, b),
closer: closer,
}, nil
}

func (ds *detachableStdin) Read(p []byte) (int, error) {
ds.mu.Lock()
defer ds.mu.Unlock()
if ds.closed {
return 0, syscall.EBADF
}

n, err := ds.stdin.Read(p)
var eerr term.EscapeError
if errors.As(err, &eerr) {
if ds.closer != nil {
ds.closer()
}
ds.closed = true
return n, nil
}
return n, err
}
26 changes: 24 additions & 2 deletions pkg/taskutil/taskutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/containerd/console"
"github.com/containerd/containerd"
"github.com/containerd/containerd/cio"
"github.com/containerd/nerdctl/pkg/consoleutil"
"github.com/containerd/nerdctl/pkg/infoutil"
"github.com/sirupsen/logrus"
"golang.org/x/term"
Expand All @@ -38,11 +39,22 @@ import (
// NewTask is from https://github.com/containerd/containerd/blob/v1.4.3/cmd/ctr/commands/tasks/tasks_unix.go#L70-L108
func NewTask(ctx context.Context, client *containerd.Client, container containerd.Container,
flagA, flagI, flagT, flagD bool, con console.Console, logURI string) (containerd.Task, error) {
closer := func() {
if t, err := container.Task(ctx, nil); err != nil {
logrus.WithError(err).Debugf("failed to get task for closer")
} else {
t.IO().Cancel()
}
}
var ioCreator cio.Creator
if flagA {
logrus.Debug("attaching output instead of using the log-uri")
if flagT {
ioCreator = cio.NewCreator(cio.WithStreams(con, con, nil), cio.WithTerminal)
in, err := consoleutil.NewDetachableStdin(con, "", closer)
if err != nil {
return nil, err
}
ioCreator = cio.NewCreator(cio.WithStreams(in, con, nil), cio.WithTerminal)
} else {
ioCreator = cio.NewCreator(cio.WithStdio)
}
Expand Down Expand Up @@ -79,7 +91,11 @@ func NewTask(ctx context.Context, client *containerd.Client, container container
if runtime.GOOS != "windows" && !term.IsTerminal(0) {
return nil, errors.New("the input device is not a TTY")
}
in = con
var err error
in, err = consoleutil.NewDetachableStdin(con, "", closer)
if err != nil {
return nil, err
}
}
ioCreator = cio.NewCreator(cio.WithStreams(in, con, nil), cio.WithTerminal)
} else if flagD && logURI != "" {
Expand Down Expand Up @@ -115,6 +131,12 @@ func NewTask(ctx context.Context, client *containerd.Client, container container
if err != nil {
return nil, err
}
logrus.Infof("NewTask (task id: %s): is IO() nil? %v", t.ID(), t.IO() == nil)
t2, err := container.Task(ctx, nil)
if err != nil {
return nil, err
}
logrus.Infof("Task (task id: %s): is IO() nil? %v", t2.ID(), t2.IO() == nil)
return t, nil
}

Expand Down

0 comments on commit 1b2898a

Please sign in to comment.