Skip to content

Commit

Permalink
Support websocket transport for exec and attach
Browse files Browse the repository at this point in the history
This allows end users to choose the transport to be used as well as
runtime developers to experiment on feature development.

Supersedes: kubernetes-sigs#1305

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
  • Loading branch information
saschagrunert committed Mar 21, 2024
1 parent f5e5b37 commit 85bcb15
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
8 changes: 7 additions & 1 deletion cmd/crictl/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ var runtimeAttachCommand = &cli.Command{
Aliases: []string{"i"},
Usage: "Keep STDIN open",
},
&cli.StringFlag{
Name: transportFlag,
Aliases: []string{"r"},
Value: transportSpdy,
Usage: fmt.Sprintf("Transport protocol to be used, must be one of: %s, %s", transportSpdy, transportWebsocket),
},
},
Action: func(c *cli.Context) error {
id := c.Args().First()
Expand Down Expand Up @@ -109,5 +115,5 @@ func Attach(ctx context.Context, client internalapi.RuntimeService, opts attachO
}

logrus.Debugf("Attach URL: %v", URL)
return stream(ctx, opts.stdin, opts.tty, URL)
return stream(ctx, opts.stdin, opts.tty, opts.transport, URL)
}
47 changes: 37 additions & 10 deletions cmd/crictl/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
mobyterm "github.com/moby/term"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest"
remoteclient "k8s.io/client-go/tools/remotecommand"
internalapi "k8s.io/cri-api/pkg/apis"
pb "k8s.io/cri-api/pkg/apis/runtime/v1"
Expand All @@ -37,6 +37,10 @@ const (
// TODO: make this configurable in kubelet.
kubeletURLSchema = "http"
kubeletURLHost = "http://127.0.0.1:10250"

transportFlag = "transport"
transportWebsocket = "websocket"
transportSpdy = "spdy"
)

const detachSequence = "ctrl-p,ctrl-q"
Expand Down Expand Up @@ -67,6 +71,12 @@ var runtimeExecCommand = &cli.Command{
Aliases: []string{"i"},
Usage: "Keep STDIN open",
},
&cli.StringFlag{
Name: transportFlag,
Aliases: []string{"r"},
Value: transportSpdy,
Usage: fmt.Sprintf("Transport protocol to be used, must be one of: %s, %s", transportSpdy, transportWebsocket),
},
},
Action: func(c *cli.Context) error {
if c.NArg() < 2 {
Expand All @@ -79,11 +89,12 @@ var runtimeExecCommand = &cli.Command{
}

var opts = execOptions{
id: c.Args().First(),
timeout: c.Int64("timeout"),
tty: c.Bool("tty"),
stdin: c.Bool("interactive"),
cmd: c.Args().Slice()[1:],
id: c.Args().First(),
timeout: c.Int64("timeout"),
tty: c.Bool("tty"),
stdin: c.Bool("interactive"),
cmd: c.Args().Slice()[1:],
transport: c.String(transportFlag),
}
if c.Bool("sync") {
exitCode, err := ExecSync(runtimeClient, opts)
Expand Down Expand Up @@ -160,13 +171,13 @@ func Exec(ctx context.Context, client internalapi.RuntimeService, opts execOptio
}

logrus.Debugf("Exec URL: %v", URL)
return stream(ctx, opts.stdin, opts.tty, URL)
return stream(ctx, opts.stdin, opts.tty, opts.transport, URL)
}

func stream(ctx context.Context, in, tty bool, url *url.URL) error {
executor, err := remoteclient.NewSPDYExecutor(&restclient.Config{TLSClientConfig: restclient.TLSClientConfig{Insecure: true}}, "POST", url)
func stream(ctx context.Context, in, tty bool, transport string, url *url.URL) error {
executor, err := getExecutor(transport, url)
if err != nil {
return err
return fmt.Errorf("get executor: %w", err)
}

stdin, stdout, stderr := mobyterm.StdStreams()
Expand Down Expand Up @@ -204,3 +215,19 @@ func stream(ctx context.Context, in, tty bool, url *url.URL) error {
streamOptions.TerminalSizeQueue = t.MonitorSize(t.GetSize())
return t.Safe(func() error { return executor.StreamWithContext(ctx, streamOptions) })
}

func getExecutor(transport string, url *url.URL) (exec remoteclient.Executor, err error) {
config := &rest.Config{TLSClientConfig: rest.TLSClientConfig{Insecure: true}}

switch transport {
case transportSpdy:
return remoteclient.NewSPDYExecutor(config, "POST", url)

case transportWebsocket:
return remoteclient.NewWebSocketExecutor(config, "GET", url.String())

default:
return nil, fmt.Errorf("unknown transport: %s", transport)

}
}
4 changes: 4 additions & 0 deletions cmd/crictl/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ type execOptions struct {
stdin bool
// Command to exec
cmd []string
// transport to be used
transport string
}
type attachOptions struct {
// id of container
Expand All @@ -122,6 +124,8 @@ type attachOptions struct {
tty bool
// Whether pass Stdin to container
stdin bool
// transport to be used
transport string
}

type portforwardOptions struct {
Expand Down

0 comments on commit 85bcb15

Please sign in to comment.