mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-07 19:23:40 +00:00
Fix incorrect message when attaching to ephemeral containers
This commit is contained in:
parent
f8e80d32c0
commit
8d4ec9ac9d
@ -20,6 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -286,8 +287,8 @@ func (o *AttachOptions) Run() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !o.Quiet && o.Stdin && t.Raw && o.Pod.Spec.RestartPolicy == corev1.RestartPolicyAlways {
|
if msg := o.reattachMessage(containerToAttach.Name, t.Raw); msg != "" {
|
||||||
fmt.Fprintf(o.Out, "Session ended, resume using '%s %s -c %s -i -t' command when the pod is running\n", o.CommandName, o.Pod.Name, containerToAttach.Name)
|
fmt.Fprintln(o.Out, msg)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -317,3 +318,15 @@ func (o *AttachOptions) GetContainerName(pod *corev1.Pod) (string, error) {
|
|||||||
}
|
}
|
||||||
return c.Name, nil
|
return c.Name, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reattachMessage returns a message to print after attach has completed, or
|
||||||
|
// the empty string if no message should be printed.
|
||||||
|
func (o *AttachOptions) reattachMessage(containerName string, rawTTY bool) string {
|
||||||
|
if o.Quiet || !o.Stdin || !rawTTY || o.Pod.Spec.RestartPolicy != corev1.RestartPolicyAlways {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if _, path := podcmd.FindContainerByName(o.Pod, containerName); strings.HasPrefix(path, "spec.ephemeralContainers") {
|
||||||
|
return fmt.Sprintf("Session ended, the ephemeral container will not be restarted but may be reattached using '%s %s -c %s -i -t' if it is still running", o.CommandName, o.Pod.Name, containerName)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Session ended, resume using '%s %s -c %s -i -t' command when the pod is running", o.CommandName, o.Pod.Name, containerName)
|
||||||
|
}
|
||||||
|
@ -484,3 +484,76 @@ func setDefaultContainer(pod *corev1.Pod, name string) *corev1.Pod {
|
|||||||
pod.Annotations[podcmd.DefaultContainerAnnotationName] = name
|
pod.Annotations[podcmd.DefaultContainerAnnotationName] = name
|
||||||
return pod
|
return pod
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReattachMessage(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
pod *corev1.Pod
|
||||||
|
rawTTY, stdin bool
|
||||||
|
container string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "normal interactive session",
|
||||||
|
pod: attachPod(),
|
||||||
|
container: "bar",
|
||||||
|
rawTTY: true,
|
||||||
|
stdin: true,
|
||||||
|
expected: "Session ended, resume using",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no stdin",
|
||||||
|
pod: attachPod(),
|
||||||
|
container: "bar",
|
||||||
|
rawTTY: true,
|
||||||
|
stdin: false,
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "not connected to a real TTY",
|
||||||
|
pod: attachPod(),
|
||||||
|
container: "bar",
|
||||||
|
rawTTY: false,
|
||||||
|
stdin: true,
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no restarts",
|
||||||
|
pod: &corev1.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test"},
|
||||||
|
Spec: corev1.PodSpec{
|
||||||
|
RestartPolicy: corev1.RestartPolicyNever,
|
||||||
|
Containers: []corev1.Container{{Name: "bar"}},
|
||||||
|
},
|
||||||
|
Status: corev1.PodStatus{Phase: corev1.PodRunning},
|
||||||
|
},
|
||||||
|
container: "bar",
|
||||||
|
rawTTY: true,
|
||||||
|
stdin: true,
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ephemeral container",
|
||||||
|
pod: attachPod(),
|
||||||
|
container: "debugger",
|
||||||
|
rawTTY: true,
|
||||||
|
stdin: true,
|
||||||
|
expected: "Session ended, the ephemeral container will not be restarted",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
options := &AttachOptions{
|
||||||
|
StreamOptions: exec.StreamOptions{
|
||||||
|
Stdin: test.stdin,
|
||||||
|
},
|
||||||
|
Pod: test.pod,
|
||||||
|
}
|
||||||
|
if msg := options.reattachMessage(test.container, test.rawTTY); test.expected == "" && msg != "" {
|
||||||
|
t.Errorf("reattachMessage(%v, %v) = %q, wanted empty string", test.container, test.rawTTY, msg)
|
||||||
|
} else if !strings.Contains(msg, test.expected) {
|
||||||
|
t.Errorf("reattachMessage(%v, %v) = %q, want string containing %q", test.container, test.rawTTY, msg, test.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -364,7 +364,6 @@ func (o *DebugOptions) Run(f cmdutil.Factory, cmd *cobra.Command) error {
|
|||||||
TTY: o.TTY,
|
TTY: o.TTY,
|
||||||
Quiet: o.Quiet,
|
Quiet: o.Quiet,
|
||||||
},
|
},
|
||||||
// TODO(verb): kubectl prints an incorrect "Session ended" message for debug containers.
|
|
||||||
CommandName: cmd.Parent().CommandPath() + " attach",
|
CommandName: cmd.Parent().CommandPath() + " attach",
|
||||||
|
|
||||||
Attach: &attach.DefaultRemoteAttach{},
|
Attach: &attach.DefaultRemoteAttach{},
|
||||||
|
Loading…
Reference in New Issue
Block a user