Skip to content

Commit

Permalink
feat(debug): Add cluster debug-pod command
Browse files Browse the repository at this point in the history
  • Loading branch information
erebe committed Jan 21, 2025
1 parent f04df08 commit e2c720e
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 12 deletions.
71 changes: 71 additions & 0 deletions cmd/cluster_debug_pod.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package cmd

import (
"github.com/qovery/qovery-cli/pkg"
"github.com/qovery/qovery-cli/pkg/usercontext"
"github.com/qovery/qovery-cli/utils"
"github.com/spf13/cobra"
"os"
)

var clusterDebugPodCmd = &cobra.Command{
Use: "debug-pod",
Short: "Launch a debug pod and attach to it",
Run: func(cmd *cobra.Command, args []string) {
utils.Capture(cmd)

tokenType, token, err := utils.GetAccessToken()
if err != nil {
utils.PrintlnError(err)
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

client := utils.GetQoveryClient(tokenType, token)
organizationId, err := usercontext.GetOrganizationContextResourceId(client, organizationName)
if err != nil {
utils.PrintlnError(err)
os.Exit(1)
panic("unreachable") // staticcheck false positive: https://staticcheck.io/docs/checks#SA5011
}

flavor := "REGULAR_PRIVILEGE"
if fullPriviledge {
flavor = "FULL_PRIVILEGE"
}
request := DebugPodRequest{
utils.Id(organizationId),
utils.Id(clusterId),
0,
0,
flavor,
nodeSelector,
}

pkg.ExecShell(&request, "/shell/debug")
},
}

type DebugPodRequest struct {
OrganizationID utils.Id `url:"organization"`
ClusterID utils.Id `url:"cluster"`
TtyWidth uint16 `url:"tty_width"`
TtyHeight uint16 `url:"tty_height"`
Flavor string `url:"flavor"`
NodeSelector string `url:"node_selector,omitempty"`
}

func (s *DebugPodRequest) SetTtySize(width uint16, height uint16) {
s.TtyWidth = width
s.TtyHeight = height
}

var fullPriviledge bool
var nodeSelector string

func init() {
clusterCmd.AddCommand(clusterDebugPodCmd)
clusterDebugPodCmd.Flags().StringVarP(&clusterId, "cluster-id", "c", "", "Cluster ID")
clusterDebugPodCmd.Flags().StringVarP(&nodeSelector, "node-selector", "n", "", "Specify a node selector for the debug pod to be started on")
clusterDebugPodCmd.Flags().BoolVarP(&fullPriviledge, "full-privilege", "p", false, "Start a full privileged debug pod which has access to host machine. ")
}
4 changes: 2 additions & 2 deletions cmd/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"golang.org/x/net/context"

"github.com/qovery/qovery-cli/pkg"
"github.com/qovery/qovery-cli/utils"
"github.com/qovery/qovery-cli/pkg/usercontext"
"github.com/qovery/qovery-cli/utils"
)

var shellCmd = &cobra.Command{
Expand Down Expand Up @@ -52,7 +52,7 @@ var shellCmd = &cobra.Command{
return
}

pkg.ExecShell(shellRequest)
pkg.ExecShell(shellRequest, "/shell/exec")
},
}

Expand Down
28 changes: 18 additions & 10 deletions pkg/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import (

const StdinBufferSize = 4096

type TerminalSize interface {
SetTtySize(width uint16, height uint16)
}

type ShellRequest struct {
ServiceID utils.Id `url:"service"`
EnvironmentID utils.Id `url:"environment"`
Expand All @@ -29,7 +33,12 @@ type ShellRequest struct {
TtyHeight uint16 `url:"tty_height"`
}

func ExecShell(req *ShellRequest) {
func (s *ShellRequest) SetTtySize(width uint16, height uint16) {
s.TtyWidth = width
s.TtyHeight = height
}

func ExecShell(req TerminalSize, path string) {
currentConsole := console.Current()
defer func() {
_ = currentConsole.Reset()
Expand All @@ -39,10 +48,9 @@ func ExecShell(req *ShellRequest) {
if err != nil {
log.Fatal("Cannot get terminal size", err)
}
req.TtyWidth = winSize.Width
req.TtyHeight = winSize.Height
req.SetTtySize(winSize.Width, winSize.Height)

wsConn, err := createWebsocketConn(req)
wsConn, err := CreateWebsocketConn(req, path)
if err != nil {
log.Fatal("error while creating websocket connection", err)
}
Expand All @@ -59,8 +67,8 @@ func ExecShell(req *ShellRequest) {
done := make(chan struct{})
stdIn := make(chan []byte)

go readWebsocketConnection(wsConn, currentConsole, done)
go readUserConsole(currentConsole, stdIn, done)
go ReadWebsocketConnection(wsConn, currentConsole, done)
go ReadUserConsole(currentConsole, stdIn, done)

for {
select {
Expand All @@ -75,13 +83,13 @@ func ExecShell(req *ShellRequest) {
}
}

func createWebsocketConn(req *ShellRequest) (*websocket.Conn, error) {
func CreateWebsocketConn(req interface{}, path string) (*websocket.Conn, error) {
command, err := query.Values(req)
if err != nil {
return nil, err
}

wsURL, err := url.Parse(fmt.Sprintf("%s/shell/exec", utils.WebsocketUrl()))
wsURL, err := url.Parse(fmt.Sprintf("%s%s", utils.WebsocketUrl(), path))
if err != nil {
return nil, err
}
Expand All @@ -101,7 +109,7 @@ func createWebsocketConn(req *ShellRequest) (*websocket.Conn, error) {
return wsConn, nil
}

func readWebsocketConnection(wsConn *websocket.Conn, currentConsole console.Console, done chan struct{}) {
func ReadWebsocketConnection(wsConn *websocket.Conn, currentConsole console.Console, done chan struct{}) {
defer close(done)
for {
msgType, msg, err := wsConn.ReadMessage()
Expand Down Expand Up @@ -134,7 +142,7 @@ func readWebsocketConnection(wsConn *websocket.Conn, currentConsole console.Cons
}
}

func readUserConsole(currentConsole console.Console, stdIn chan []byte, done chan struct{}) {
func ReadUserConsole(currentConsole console.Console, stdIn chan []byte, done chan struct{}) {
defer close(done)
buffer := make([]byte, StdinBufferSize)
for {
Expand Down

0 comments on commit e2c720e

Please sign in to comment.