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

Rework pod-exec and node-exec #628

Merged
merged 2 commits into from
May 23, 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
2 changes: 1 addition & 1 deletion .docs/commands/havener.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ See the individual commands to get the complete overview.
### Options

```
--kubeconfig string Kubernetes configuration file (default "~/.kube/config")
--kubeconfig string Kubernetes configuration (default "~/.kube/config")
--terminal-width int disable autodetection and specify an explicit terminal width (default -1)
--terminal-height int disable autodetection and specify an explicit terminal height (default -1)
--fatal fatal output - level 1
Expand Down
2 changes: 1 addition & 1 deletion .docs/commands/havener_events.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ havener events [flags]
--debug debug output - level 5
--error error output - level 2
--fatal fatal output - level 1
--kubeconfig string Kubernetes configuration file (default "~/.kube/config")
--kubeconfig string Kubernetes configuration (default "~/.kube/config")
--terminal-height int disable autodetection and specify an explicit terminal height (default -1)
--terminal-width int disable autodetection and specify an explicit terminal width (default -1)
--trace trace output - level 6
Expand Down
2 changes: 1 addition & 1 deletion .docs/commands/havener_logs.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ havener logs [flags]
--debug debug output - level 5
--error error output - level 2
--fatal fatal output - level 1
--kubeconfig string Kubernetes configuration file (default "~/.kube/config")
--kubeconfig string Kubernetes configuration (default "~/.kube/config")
--terminal-height int disable autodetection and specify an explicit terminal height (default -1)
--terminal-width int disable autodetection and specify an explicit terminal width (default -1)
--trace trace output - level 6
Expand Down
36 changes: 19 additions & 17 deletions .docs/commands/havener_node-exec.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,24 @@ Execute command on Kubernetes node

### Synopsis

Execute a command on a node.
Execute a command on a node

This executes a command directly on the node itself. Therefore, havener creates
a temporary pod which enables the user to access the shell of the node. The pod
Execute a command directly on the node itself. For this, havener creates a
temporary pod, which enables the user to access the shell of the node. The pod
is deleted automatically afterwards.

The command can be omitted which will result in the default command: /bin/sh. For
example 'havener node-exec foo' will search for a node named 'foo' and open a
shell if found.
example havener node-exec foo will search for a node named 'foo' and open a
shell if the node can be found.

Typically, the TTY flag does have to be specified. By definition, if one one
target node is provided, it is assumed that TTY is desired and STDIN is attached
to the remote process. Analog, for the distributed mode with multiple nodes,
no TTY is set, and the STDIN is multiplexed into each remote process.
When more than one node is specified, it will execute the command on all nodes.
In this distributed mode, both passing the StdIn as well as TTY mode are not
available. By default, the number of parallel node executions is limited to 5
in parallel in order to not create to many requests at the same time. This
value can be overwritten. Handle with care.

If you run the 'node-exec' without any additional arguments, it will print a
list of available nodes.
If you run the node-exec without any additional arguments, it will print a
list of available nodes in the cluster.

For convenience, if the target node name all is used, havener will look up
all nodes automatically.
Expand All @@ -34,12 +35,13 @@ havener node-exec [flags] [<node>[,<node>,...]] [<command>]
### Options

```
--block show distributed shell output as block for each node
-i, --stdin Pass stdin to the container
-t, --tty Stdin is a TTY
--image string Container image used for helper pod (from which the root-shell is accessed) (default "docker.io/library/alpine")
--timeout duration Timeout for the setup of the helper pod (default 30s)
--max-parallel int Number of parallel executions (value less or equal than zero means unlimited) (default 5)
--block Show distributed shell output as block for each node
-h, --help help for node-exec
--image string set image for helper pod from which the root-shell is accessed (default "alpine")
--max-parallel int number of parallel executions (defaults to number of nodes)
--no-tty do not allocate pseudo-terminal for command execution
--timeout int set timout in seconds for the setup of the helper pod (default 10)
```

### Options inherited from parent commands
Expand All @@ -48,7 +50,7 @@ havener node-exec [flags] [<node>[,<node>,...]] [<command>]
--debug debug output - level 5
--error error output - level 2
--fatal fatal output - level 1
--kubeconfig string Kubernetes configuration file (default "~/.kube/config")
--kubeconfig string Kubernetes configuration (default "~/.kube/config")
--terminal-height int disable autodetection and specify an explicit terminal height (default -1)
--terminal-width int disable autodetection and specify an explicit terminal width (default -1)
--trace trace output - level 6
Expand Down
33 changes: 17 additions & 16 deletions .docs/commands/havener_pod-exec.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@ Execute command on Kubernetes pod

### Synopsis

Execute a shell command on a pod.
Execute a command on a pod

This is similar to the kubectl exec command with just a slightly
different syntax. In contrast to kubectl, you do not have to specify
the namespace of the pod.
This is similar to the kubectl exec command with just a slightly different
syntax. In contrast to kubectl, you do not have to specify the namespace
of the pod.

If no namespace is given, havener will search all namespaces for
a pod that matches the name.
If no namespace is given, havener will search all namespaces for a pod that
matches the name.

Also, you can omit the command which will result in the default
command: /bin/sh. For example 'havener pod-exec api-0' will search
for a pod named 'api-0' in all namespaces and open a shell if found.
Also, you can omit the command which will result in the default command: /bin/sh.
For example havener pod-exec api-0 will search for a pod named api-0 in all
namespaces and open a shell if found.

In case no container name is given, havener will assume you want to
execute the command in the first container found in the pod.
In case no container name is given, havener will assume you want to execute the
command in the first container found in the pod.

If you run the 'pod-exec' without any additional arguments, it will print a
list of available pods.

For convenience, if the target pod name _all_ is used, havener will look up
For convenience, if the target pod name all is used, havener will look up
all pods in all namespaces automatically.


Expand All @@ -34,9 +34,10 @@ havener pod-exec [flags] [[<namespace>/]<pod>[/container]] [<command>]
### Options

```
--block show distributed shell output as block for each pod
-h, --help help for pod-exec
--no-tty do not allocate pseudo-terminal for command execution
-i, --stdin Pass stdin to the container
-t, --tty Stdin is a TTY
--block show distributed shell output as block for each pod
-h, --help help for pod-exec
```

### Options inherited from parent commands
Expand All @@ -45,7 +46,7 @@ havener pod-exec [flags] [[<namespace>/]<pod>[/container]] [<command>]
--debug debug output - level 5
--error error output - level 2
--fatal fatal output - level 1
--kubeconfig string Kubernetes configuration file (default "~/.kube/config")
--kubeconfig string Kubernetes configuration (default "~/.kube/config")
--terminal-height int disable autodetection and specify an explicit terminal height (default -1)
--terminal-width int disable autodetection and specify an explicit terminal width (default -1)
--trace trace output - level 6
Expand Down
2 changes: 1 addition & 1 deletion .docs/commands/havener_top.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ havener top [flags]
--debug debug output - level 5
--error error output - level 2
--fatal fatal output - level 1
--kubeconfig string Kubernetes configuration file (default "~/.kube/config")
--kubeconfig string Kubernetes configuration (default "~/.kube/config")
--terminal-height int disable autodetection and specify an explicit terminal height (default -1)
--terminal-width int disable autodetection and specify an explicit terminal width (default -1)
--trace trace output - level 6
Expand Down
2 changes: 1 addition & 1 deletion .docs/commands/havener_version.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ havener version [flags]
--debug debug output - level 5
--error error output - level 2
--fatal fatal output - level 1
--kubeconfig string Kubernetes configuration file (default "~/.kube/config")
--kubeconfig string Kubernetes configuration (default "~/.kube/config")
--terminal-height int disable autodetection and specify an explicit terminal height (default -1)
--terminal-width int disable autodetection and specify an explicit terminal width (default -1)
--trace trace output - level 6
Expand Down
2 changes: 1 addition & 1 deletion .docs/commands/havener_watch.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ havener watch [flags]
--debug debug output - level 5
--error error output - level 2
--fatal fatal output - level 1
--kubeconfig string Kubernetes configuration file (default "~/.kube/config")
--kubeconfig string Kubernetes configuration (default "~/.kube/config")
--terminal-height int disable autodetection and specify an explicit terminal height (default -1)
--terminal-width int disable autodetection and specify an explicit terminal width (default -1)
--trace trace output - level 6
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/gonvenience/wait v1.0.3
github.com/gonvenience/wrap v1.2.0
github.com/lucasb-eyer/go-colorful v1.2.0
github.com/mattn/go-isatty v0.0.18
github.com/onsi/ginkgo/v2 v2.17.3
github.com/onsi/gomega v1.33.1
github.com/spf13/cobra v1.8.0
Expand Down Expand Up @@ -58,7 +59,6 @@ require (
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/mitchellh/go-ps v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/spdystream v0.2.0 // indirect
Expand Down
37 changes: 7 additions & 30 deletions internal/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,41 +21,14 @@
package cmd

import (
"io"
"os"

"github.com/gonvenience/wrap"
"github.com/mattn/go-isatty"
)

// duplicateReader creates a given number of io.Reader duplicates based on the
// provided input reader. This way it is possible to use one input reader for
// more than one consumer.
func duplicateReader(reader io.Reader, count int) []io.Reader {
writers := []io.Writer{}
readers := []io.Reader{}
for i := 0; i < count; i++ {
r, w := io.Pipe()
writers = append(writers, w)
readers = append(readers, r)
}

writer := io.MultiWriter(writers...)
go func() {
if _, err := io.Copy(writer, reader); err != nil {
panic(err)
}

for i := range writers {
if w, ok := writers[i].(io.Closer); ok {
w.Close()
}
}
}()

return readers
}

func combineErrorsFromChannel(context string, c chan error) error {
errors := []error{}
var errors []error

Check warning on line 31 in internal/cmd/common.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/common.go#L31

Added line #L31 was not covered by tests
for err := range c {
if err != nil {
errors = append(errors, err)
Expand All @@ -70,3 +43,7 @@
return wrap.Errors(errors, context)
}
}

func isTerminal(fd uintptr) bool { return isatty.IsTerminal(fd) || isatty.IsCygwinTerminal(fd) }

Check warning on line 47 in internal/cmd/common.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/common.go#L47

Added line #L47 was not covered by tests

func isStdinTerminal() bool { return isTerminal(os.Stdin.Fd()) }

Check warning on line 49 in internal/cmd/common.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/common.go#L49

Added line #L49 was not covered by tests
3 changes: 1 addition & 2 deletions internal/cmd/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
package cmd

import (
"context"
"fmt"
"strings"
"time"
Expand Down Expand Up @@ -86,7 +85,7 @@
continue
}

watcher, err := hvnr.Client().CoreV1().Events(namespace).Watch(context.TODO(), metav1.ListOptions{})
watcher, err := hvnr.Client().CoreV1().Events(namespace).Watch(hvnr.Context(), metav1.ListOptions{})

Check warning on line 88 in internal/cmd/events.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/events.go#L88

Added line #L88 was not covered by tests
if err != nil {
return fmt.Errorf("failed to setup event watcher: %w", err)
}
Expand Down
Loading