Skip to content

Commit

Permalink
Support debug session via k8s runtime to nginx (#81)
Browse files Browse the repository at this point in the history
* Add start session keys

* Add note about k8s list pods auto runtime behavior

* Support kubernetes session to nginx
  • Loading branch information
eharris128 authored Nov 4, 2024
1 parent c295288 commit 09cc5a7
Show file tree
Hide file tree
Showing 4 changed files with 301 additions and 19 deletions.
3 changes: 3 additions & 0 deletions pkg/app/master/command/debug/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type Volume struct {
}

type CommandParams struct {
KubeComm *KubernetesHandlerComm
/// the runtime environment type
Runtime string
/// the running container which we want to attach to
Expand Down Expand Up @@ -239,6 +240,8 @@ var CLI = &cli.Command{
xc.Exit(-1)
}

// NOTE -> this approach results in the default of `auto` erroring out
// even if the user's system has a `k8s` runtime available`
if commandParams.ActionListPods &&
commandParams.Runtime != crt.KubernetesRuntime {
xc.Out.Error("param", "unsupported runtime flag")
Expand Down
73 changes: 65 additions & 8 deletions pkg/app/master/command/debug/handle_kubernetes_runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
Expand Down Expand Up @@ -817,14 +818,27 @@ func HandleKubernetesRuntime(

fmt.Printf("\n")
//note: blocks until done streaming or failure...
err = attach.StreamWithContext(
ctx,
remotecommand.StreamOptions{
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
Tty: doTTY,
})
if commandParams.TUI {
// TODO - move KubeComm off of command params
reader := &KubeReader{inputChan: commandParams.KubeComm.InputChan}
err = attach.StreamWithContext(
ctx,
remotecommand.StreamOptions{
Stdin: reader,
Stdout: os.Stdout,
Stderr: os.Stderr,
Tty: true, // Later on we may parse this in TUI mode.
})
} else {
err = attach.StreamWithContext(
ctx,
remotecommand.StreamOptions{
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
Tty: doTTY,
})
}

if err != nil {
if apierrors.IsNotFound(err) {
Expand All @@ -844,6 +858,49 @@ func HandleKubernetesRuntime(
}
}

// NOTE -> this input channel reader will be genericized
// as per the comment in `debug/tui.go`.
// An InputReader usable by Docker, Podman, Kubernetes, and Containerd
// will be added to this directory.
type KubeReader struct {
inputChan chan InputKey
}

func (kr *KubeReader) Read(p []byte) (n int, err error) {
inputKey, ok := <-kr.inputChan
if !ok {
return 0, io.EOF
}
log.Debugf("KubeReader received inputKey %v", inputKey)
switch inputKey.Special {
case NotSpecial:
p[0] = byte(inputKey.Rune)
return 1, nil
case Enter:
p[0] = '\n'
return 1, nil
case Backspace:
p[0] = 127
return 1, nil
case Up:
copy(p, []byte{27, 91, 65}) // ESC [ A
return 3, nil
case Down:
copy(p, []byte{27, 91, 66}) // ESC [ B
return 3, nil
case Left:
copy(p, []byte{27, 91, 68}) // ESC [ D
return 3, nil
case Right:
copy(p, []byte{27, 91, 67}) // ESC [ C
return 3, nil
default:
log.Debugf("Unhandled inputKey %v", inputKey)
// Handle other special keys or return an error
return 0, fmt.Errorf("unsupported special key")
}
}

func listNamespaces(ctx context.Context, api *kubernetes.Clientset) ([]string, error) {
namespaces, err := api.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
if err != nil {
Expand Down
Loading

0 comments on commit 09cc5a7

Please sign in to comment.