kubectl debug: allow set-image-only invocation

This commit is contained in:
Lee Verberne 2020-11-05 13:40:11 +01:00
parent f3fbd17bc8
commit d6024ce18d
2 changed files with 36 additions and 9 deletions

View File

@ -121,6 +121,7 @@ type DebugOptions struct {
TargetContainer string TargetContainer string
TTY bool TTY bool
attachChanged bool
deprecatedInvocation bool deprecatedInvocation bool
shareProcessedChanged bool shareProcessedChanged bool
@ -223,7 +224,8 @@ func (o *DebugOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st
return err return err
} }
// Share processes // Record flags that the user explicitly changed from their defaults
o.attachChanged = cmd.Flags().Changed("attach")
o.shareProcessedChanged = cmd.Flags().Changed("share-processes") o.shareProcessedChanged = cmd.Flags().Changed("share-processes")
return nil return nil
@ -231,6 +233,11 @@ func (o *DebugOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st
// Validate checks that the provided debug options are specified. // Validate checks that the provided debug options are specified.
func (o *DebugOptions) Validate(cmd *cobra.Command) error { func (o *DebugOptions) Validate(cmd *cobra.Command) error {
// Attach
if o.Attach && o.attachChanged && len(o.Image) == 0 && len(o.Container) == 0 {
return fmt.Errorf("you must specify --container or create a new container using --image in order to attach.")
}
// CopyTo // CopyTo
if len(o.CopyTo) > 0 { if len(o.CopyTo) > 0 {
if len(o.Image) == 0 && len(o.SetImages) == 0 && len(o.Args) == 0 { if len(o.Image) == 0 && len(o.SetImages) == 0 && len(o.Args) == 0 {
@ -332,7 +339,7 @@ func (o *DebugOptions) Run(f cmdutil.Factory, cmd *cobra.Command) error {
return visitErr return visitErr
} }
if o.Attach { if o.Attach && len(containerName) > 0 {
opts := &attach.AttachOptions{ opts := &attach.AttachOptions{
StreamOptions: exec.StreamOptions{ StreamOptions: exec.StreamOptions{
IOStreams: o.IOStreams, IOStreams: o.IOStreams,
@ -552,18 +559,22 @@ func (o *DebugOptions) generatePodCopyWithDebugContainer(pod *corev1.Pod) (*core
} }
} }
containerByName := containerNameToRef(copied) name, containerByName := o.Container, containerNameToRef(copied)
name := o.Container
if len(name) == 0 {
name = o.computeDebugContainerName(copied)
}
c, ok := containerByName[name] c, ok := containerByName[name]
if !ok { if !ok {
// Adding a new debug container // Adding a new debug container
if len(o.Image) == 0 { if len(o.Image) == 0 {
if len(o.SetImages) > 0 {
// This was a --set-image only invocation
return copied, "", nil
}
return nil, "", fmt.Errorf("you must specify image when creating new container") return nil, "", fmt.Errorf("you must specify image when creating new container")
} }
if len(name) == 0 {
name = o.computeDebugContainerName(copied)
}
c = &corev1.Container{ c = &corev1.Container{
Name: name, Name: name,
TerminationMessagePolicy: corev1.TerminationMessageReadFile, TerminationMessagePolicy: corev1.TerminationMessageReadFile,

View File

@ -868,7 +868,6 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
name: "Change image for all containers with set-image", name: "Change image for all containers with set-image",
opts: &DebugOptions{ opts: &DebugOptions{
CopyTo: "myapp-copy", CopyTo: "myapp-copy",
Container: "app",
SetImages: map[string]string{"*": "busybox"}, SetImages: map[string]string{"*": "busybox"},
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
@ -898,7 +897,6 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
name: "Change image for multiple containers with set-image", name: "Change image for multiple containers with set-image",
opts: &DebugOptions{ opts: &DebugOptions{
CopyTo: "myapp-copy", CopyTo: "myapp-copy",
Container: "app",
SetImages: map[string]string{"*": "busybox", "app": "app-debugger"}, SetImages: map[string]string{"*": "busybox", "app": "app-debugger"},
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
@ -1361,6 +1359,19 @@ func TestCompleteAndValidate(t *testing.T) {
TargetNames: []string{"mypod"}, TargetNames: []string{"mypod"},
}, },
}, },
{
name: "Pod copy: explicit attach",
args: "mypod --image=busybox --copy-to=my-debugger --attach -- sleep 1d",
wantOpts: &DebugOptions{
Args: []string{"sleep", "1d"},
Attach: true,
CopyTo: "my-debugger",
Image: "busybox",
Namespace: "default",
ShareProcesses: true,
TargetNames: []string{"mypod"},
},
},
{ {
name: "Pod copy: replace single image of existing container", name: "Pod copy: replace single image of existing container",
args: "mypod --image=busybox --container=my-container --copy-to=my-debugger", args: "mypod --image=busybox --container=my-container --copy-to=my-debugger",
@ -1443,6 +1454,11 @@ func TestCompleteAndValidate(t *testing.T) {
args: "mypod --set-image=*=SUPERGOODIMAGE#1!!!! --copy-to=my-debugger", args: "mypod --set-image=*=SUPERGOODIMAGE#1!!!! --copy-to=my-debugger",
wantError: true, wantError: true,
}, },
{
name: "Pod copy: specifying attach without existing or newly created container",
args: "mypod --set-image=*=busybox --copy-to=my-debugger --attach",
wantError: true,
},
{ {
name: "Node: interactive session minimal args", name: "Node: interactive session minimal args",
args: "node/mynode -it --image=busybox", args: "node/mynode -it --image=busybox",