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

Support debug session via k8s runtime to nginx #81

Merged
merged 3 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading