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

[bug] Cannot complete commands with kubectl kc #786

Closed
nekomeowww opened this issue Oct 17, 2023 · 11 comments · Fixed by #793
Closed

[bug] Cannot complete commands with kubectl kc #786

nekomeowww opened this issue Oct 17, 2023 · 11 comments · Fixed by #793
Assignees

Comments

@nekomeowww
Copy link
Contributor

nekomeowww commented Oct 17, 2023

Describe the bug

Cannot complete commands with kubectl kc.

How to reproduce issues

Cannot complete commands with kubectl kc

Steps to reproduce the behavior:

  1. Install kubecm with kubectl krew install kc
  2. Verify whether auto completion enabled or appended with echo "autoload -U compinit; compinit" >> ~/.zshrc
  3. Configured completion with kubectl kc completion zsh > "${fpath[1]}/_kubecm"
  4. Verify that the kubectl kc list lists all the contexts, got the following outputs:
❯ kubectl kc list
+------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+--------------+
|   CURRENT  |                NAME               |              CLUSTER              |                USER               |               SERVER              |   Namespace  |
+============+===================================+===================================+===================================+===================================+==============+
|            |              minikube             |              minikube             |              minikube             |      https://127.0.0.1:32769      |    default   |
+------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+--------------+

Cluster check succeeded!
Kubernetes version v1.26.7
Kubernetes master is running at https://127.0.0.1:32769
[Summary] Namespace: 9 Node: 1 Pod: 28
  1. Input kubectl kc switch and then tab, got the following outputs:
❯ kubectl kc switch Applications/
Applications/                 Documents/

Expected behavior

Should prompt sub-commands and its all descriptions.

Desktop (please complete the following information):

  • OS: macOS
  • Version: 0.25.0
  • GoOs: darwin
  • GoArch: arm64
@sunny0826
Copy link
Owner

@nekomeowww Thanks for the feedback. This is a known issue, in fact, auto-completion does not work when kubecm is run as a kubectl plugin, this is due to the kubectl mechanism, completion only works when kubecm is run as a standalone CLI.

@nekomeowww
Copy link
Contributor Author

Oh, ok. Thanks for replying!

I never heard of this limitation, I might have to take a look at kubectl cli and its community to seek out a solution or plan.

Is that ok if I create a documentation update Pull Request and state out the limitations of kubectl and the installation through kubectl krew?

@sunny0826
Copy link
Owner

Absolutely! Thank you for your contribution!

@nekomeowww
Copy link
Contributor Author

nekomeowww commented Oct 17, 2023

FYI, it looks like the completion is currently supported for plugins of kubectl since kubernetes/kubernetes#105867 was merged.

However I haven't figure out how to use the documented way of this Pull Request to make the completion possible for kubectl kc. I will keep you updated whether I succeed or failed.

@sunny0826
Copy link
Owner

Thank you very much! Looks like I'm out of date.

@marckhouzam
Copy link

Since this plugin uses Cobra, making shell completion work is very easy.
You need to provide an executable file called kubectl_complete-kc which can be found on $PATH.
Below shows how to generate that file with the proper content.
Kubectl will call that file to obtain the shell completion results.

# Generate the required file
cat <<EOF >kubectl_complete-kc
#!/usr/bin/env sh

# Call the __complete command passing it all arguments
kubectl kc __complete "\$@"
EOF

# Make the file executable
chmod u+x kubectl_complete-kc

Now put the above file somewhere on your $PATH

@sunny0826 You could provide this file in your repo and provide instructions telling users to install it on $PATH.
Note that krew does not yet support installing this file. Ref: kubernetes-sigs/krew#812

@nekomeowww Until this is available you can use this project to automatically make such completions work for any kubectl plugin that uses the https://github.com/spf13/cobra project

I just used it with kc and it works great

@sunny0826
Copy link
Owner

@marckhouzam Thank you so much !

@nekomeowww
Copy link
Contributor Author

nekomeowww commented Oct 23, 2023

Thanks for replying and participating this issue! @marckhouzam

@sunny0826 You could provide this file in your repo and provide instructions telling users to install it on $PATH.
Note that krew does not yet support installing this file. Ref: kubernetes-sigs/krew#812

@nekomeowww Until this is available you can use this project to automatically make such completions work for any kubectl plugin that uses the https://github.com/spf13/cobra project

I've tried either your plugin kubectl-plugin_completion or the direct executable shell for _complete, however I cannot get the completion for kubecm to work properly.

For the manual, and direct shell, the completion file contains the following content:

#!/usr/bin/env zsh

# Call the __complete command passing it all arguments
kubectl kc __complete "\$@"

However, it would produce the following error when trying to use TAB to request the completion:

❯ kubectl kc (eval):1: command not found: _kubectl
(eval):1: command not found: _kubectl

If I try to execute the so do "proxy" completion shell directly, I get the prompt to say the completion ended:

❯ kubectl_complete-kc
:4
Completion ended with directive: ShellCompDirectiveNoFileComp

I just used it with kc and it works great

So how does your kubectl kc works?

@marckhouzam
Copy link

I've tried either your plugin kubectl-plugin_completion or the direct executable shell for _complete, however I cannot get the completion for kubecm to work properly.

For the manual, and direct shell, the completion file contains the following content:

#!/usr/bin/env zsh

# Call the __complete command passing it all arguments
kubectl kc __complete "\$@"

There should not be a \ before the $ sign in the script. The \ was in my output because I was using cat

However, it would produce the following error when trying to use TAB to request the completion:

❯ kubectl kc (eval):1: command not found: _kubectl
(eval):1: command not found: _kubectl

Not sure about the above. Let's see if the other comments get rid of it.

If I try to execute the so do "proxy" completion shell directly, I get the prompt to say the completion ended:

❯ kubectl_complete-kc
:4
Completion ended with directive: ShellCompDirectiveNoFileComp

Try kubectl_complete-kc ''

Assuming you have shell completion working for kubectl this is what I did.
Make sure that $HOME/.kubectl-plugin-completion/ is on your PATH.

$ echo $SHELL
/bin/zsh

$ kubectl version --client
Client Version: v1.28.3
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3

$ kubectl krew install kc
Updated the local copy of plugin index.
Installing plugin: kc
W1023 10:12:49.612027    2698 install.go:160] Skipping plugin "kc", it is already installed

$ kubectl plugin-completion generate
[...]
# The above should generate the following file.
# Note that it is a little fancier than what I recommended in the previous
# command as it tries to complete the --namespace flag value as well
# but you don't really need that.
$ cat ~/.kubectl-plugin-completion/kubectl_complete-kc
#!/bin/bash
out=$(kubectl kc __complete "$@")

# If, once we remove the directive, there are completions, let's print them
if [ -n "${out%%:*}" ]; then
   printf "%s\n" "${out[@]}"
elif [[ ${@: -2:1} = "-n" ]] || [[ ${@: -2:1} = "--namespace" ]]; then
   # If there are no completions we provide completions if the previous argument is -n/--namespace.
   # This case is pretty common but normally requires the plugin to have added support for it.
   kubectl get namespaces --output go-template='{{ range .items }}{{ .metadata.name }}{{"\n"}}{{ end }}'
   # Turn off file completion
   echo :4
fi

$ kubectl <TAB>
annotate           -- Update the annotations on a resource
api-resources      -- Print the supported API resources on the server
api-versions       -- Print the supported API versions on the server, in the form of "group/version"
[...]
kc                 -- The command kc is a plugin installed by the user
[...]


$ kubectl kc <TAB>
add         -- Add KubeConfig to $HOME/.kube/config
alias       -- Generate alias for all contexts
clear       -- Clear lapsed context, cluster and user
cloud       -- Manage kubeconfig from cloud
completion  -- Generate completion script
create      -- Create new KubeConfig(experiment)
delete      -- Delete the specified context from the kubeconfig
export      -- Export the specified context from the kubeconfig
help        -- Help about any command
list        -- List KubeConfig
merge       -- Merge multiple kubeconfig files into one
namespace   -- Switch or change namespace interactively
rename      -- Rename the contexts of kubeconfig
switch      -- Switch Kube Context interactively
version     -- Print version info

@nekomeowww
Copy link
Contributor Author

nekomeowww commented Oct 24, 2023

There should not be a \ before the $ sign in the script. The \ was in my output because I was using cat

Try kubectl_complete-kc ''

Thanks for pointing out these incorrect setup for me. I didn't find out these mistakes before.

And I can get

kubectl_complete-kc ''

working right now.

However, both kubectl plugin-completion generate generated and hand written completion helper failed to be executed when used with kubectl kc, it still prompts

❯ kubectl kc (eval):1: command not found: _kubectl
(eval):1: command not found: _kubectl

My kubectl version results as

❯ kubectl version
Client Version: v1.28.3
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.27.3

which should be compatible with the feature you added.

And indeed my completion for kubectl somehow be broken at some point of time. Let me investigate it and update when I find out the cause of it.

@nekomeowww
Copy link
Contributor Author

Ok I've located the root cause. Such issue consists two major cause:

  1. Auto completion script for zsh (which is source <(kubectl completion zsh)) must be incorrectly modified by myself when I playing around krew, kubectl plugin-completion generate and messing around with my .zshrc, it miss-commented out at some point.
  2. When I remove the comment to my kubectl, completion plugins is still not working, with which kubectl I found out that my kubectl somehow pointed to /usr/local/bin/kubectl, while zsh of kubectl points to 1.28.3, bash didn't include the required $PATH for homebrew installation, it still uses the old v1.22.5 build, must be installed by the other applications or scripts.

I have gathered my needed blocks to test and contribute to kubecm, I will submit a Pull Request ASAP later this day or tomorrow.

Again, thanks for debugging and providing me such details @marckhouzam , much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants