diff -Nru kubectx-0.5.0/debian/changelog kubectx-0.6.1/debian/changelog --- kubectx-0.5.0/debian/changelog 2018-06-20 15:48:38.000000000 +0000 +++ kubectx-0.6.1/debian/changelog 2018-08-31 01:48:27.000000000 +0000 @@ -1,3 +1,12 @@ +kubectx (0.6.1-1) unstable; urgency=medium + + * New upstream release. + * Bump Standards-Version to 4.2.1. + * Add upstream patch to fix zsh autocompletion. + * Add debian/upstream/metadata. + + -- ChangZhuo Chen (陳昌倬) Fri, 31 Aug 2018 09:48:27 +0800 + kubectx (0.5.0-2) unstable; urgency=medium * Support bash, fish, zsh auto completion. diff -Nru kubectx-0.5.0/debian/control kubectx-0.6.1/debian/control --- kubectx-0.5.0/debian/control 2018-06-20 15:28:32.000000000 +0000 +++ kubectx-0.6.1/debian/control 2018-08-31 01:48:00.000000000 +0000 @@ -3,7 +3,7 @@ Priority: optional Maintainer: ChangZhuo Chen (陳昌倬) Build-Depends: debhelper (>= 11) -Standards-Version: 4.1.4 +Standards-Version: 4.2.1 Homepage: https://github.com/ahmetb/kubectx Vcs-Git: https://salsa.debian.org/debian/kubectx.git Vcs-Browser: https://salsa.debian.org/debian/kubectx diff -Nru kubectx-0.5.0/debian/patches/0001-zsh-fix-kubectx-completion-for-2-contexts.patch kubectx-0.6.1/debian/patches/0001-zsh-fix-kubectx-completion-for-2-contexts.patch --- kubectx-0.5.0/debian/patches/0001-zsh-fix-kubectx-completion-for-2-contexts.patch 1970-01-01 00:00:00.000000000 +0000 +++ kubectx-0.6.1/debian/patches/0001-zsh-fix-kubectx-completion-for-2-contexts.patch 2018-08-31 01:42:58.000000000 +0000 @@ -0,0 +1,25 @@ +From: =?utf-8?b?IkNoYW5nWmh1byBDaGVuICjpmbPmmIzlgKwpIg==?= + +Date: Fri, 31 Aug 2018 09:42:31 +0800 +Subject: zsh: fix kubectx completion for 2+ contexts + +From https://github.com/ahmetb/kubectx/commit/20e56722e22917393995e718398685c855bac8c7 +--- + completion/kubectx.zsh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/completion/kubectx.zsh b/completion/kubectx.zsh +index c24779c..76ed555 100644 +--- a/completion/kubectx.zsh ++++ b/completion/kubectx.zsh +@@ -5,8 +5,8 @@ PREV="" + if [ -f "$KUBECTX" ]; then + # show '-' only if there's a saved previous context + local PREV=$(cat "${KUBECTX}") +- _arguments "1: :((- \ +- $(kubectl config get-contexts --output='name')))" ++ _arguments "1: :(- \ ++ $(kubectl config get-contexts --output='name'))" + else + _arguments "1: :($(kubectl config get-contexts --output='name'))" + fi diff -Nru kubectx-0.5.0/debian/patches/series kubectx-0.6.1/debian/patches/series --- kubectx-0.5.0/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ kubectx-0.6.1/debian/patches/series 2018-08-31 01:42:58.000000000 +0000 @@ -0,0 +1 @@ +0001-zsh-fix-kubectx-completion-for-2-contexts.patch diff -Nru kubectx-0.5.0/debian/upstream/metadata kubectx-0.6.1/debian/upstream/metadata --- kubectx-0.5.0/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ kubectx-0.6.1/debian/upstream/metadata 2018-08-31 01:46:06.000000000 +0000 @@ -0,0 +1,6 @@ +--- +Name: kubectx +Repository: https://github.com/ahmetb/kubectx.git +Repository-Browse: https://github.com/ahmetb/kubectx +Bug-Database: https://github.com/ahmetb/kubectx/issues +Bug-Submit: https://github.com/ahmetb/kubectx/issues/new Binary files /tmp/tmpbGkY7V/B4J4Bv37lX/kubectx-0.5.0/img/kubectx-interactive.gif and /tmp/tmpbGkY7V/bYsFpABNKv/kubectx-0.6.1/img/kubectx-interactive.gif differ diff -Nru kubectx-0.5.0/kubectx kubectx-0.6.1/kubectx --- kubectx-0.5.0/kubectx 2018-04-09 23:06:51.000000000 +0000 +++ kubectx-0.6.1/kubectx 2018-08-24 16:28:10.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # kubectx(1) is a utility to manage and switch between kubectl contexts. @@ -21,23 +21,23 @@ set -eou pipefail IFS=$'\n\t' +SELF_CMD="$0" KUBECTX="${HOME}/.kube/kubectx" usage() { cat <<"EOF" USAGE: - kubectx : list the contexts - kubectx : switch to context - kubectx - : switch to the previous context - kubectx = : rename context to - kubectx =. : rename current-context to - kubectx -d : delete context ('.' for current-context) - (this command won't delete the user/cluster entry - that is used by the context) + kubectx : list the contexts + kubectx : switch to context + kubectx - : switch to the previous context + kubectx = : rename context to + kubectx =. : rename current-context to + kubectx -d [] : delete context ('.' for current-context) + (this command won't delete the user/cluster entry + that is used by the context) kubectx -h,--help : show this message EOF - exit 1 } current_context() { @@ -54,13 +54,17 @@ cur="$(current_context)" local yellow darkbg normal - yellow=$(tput setaf 3) - darkbg=$(tput setab 0) - normal=$(tput sgr0) + yellow=$(tput setaf 3 || true) + darkbg=$(tput setab 0 || true) + normal=$(tput sgr0 || true) + + local cur_ctx_fg cur_ctx_bg + cur_ctx_fg=${KUBECTX_CURRENT_FGCOLOR:-$yellow} + cur_ctx_bg=${KUBECTX_CURRENT_BGCOLOR:-$darkbg} for c in $(get_contexts); do - if [[ "${c}" = "${cur}" ]]; then - echo "${darkbg}${yellow}${c}${normal}" + if [[ -t 1 && -z "${NO_COLOR:-}" && "${c}" = "${cur}" ]]; then + echo "${cur_ctx_bg}${cur_ctx_fg}${c}${normal}" else echo "${c}" fi @@ -86,6 +90,17 @@ kubectl config use-context "${1}" } +choose_context_interactive() { + local choice + choice="$(FZF_DEFAULT_COMMAND="${SELF_CMD}" fzf --ansi || true)" + if [[ -z "${choice}" ]]; then + echo 2>&1 "error: you did not choose any of the options" + exit 1 + else + set_context "${choice}" + fi +} + set_context() { local prev prev="$(current_context)" @@ -107,18 +122,6 @@ set_context "${ctx}" } -user_of_context() { - # TODO(ahmetb) no longer used, consider deleting - kubectl config view \ - -o=jsonpath="{.contexts[?(@.name==\"${1}\")].context.user}" -} - -cluster_of_context() { - # TODO(ahmetb) no longer used, consider deleting - kubectl config view \ - -o=jsonpath="{.contexts[?(@.name==\"${1}\")].context.cluster}" -} - context_exists() { grep -q ^"${1}"\$ <(kubectl config get-contexts -o=name) } @@ -131,15 +134,6 @@ old_name="$(current_context)" fi - # TODO(ahmetb) old_user and old_cluster are no longer used, clean up - local old_user old_cluster - old_user="$(user_of_context "${old_name}")" - old_cluster="$(cluster_of_context "${old_name}")" - if [[ -z "$old_user" || -z "$old_cluster" ]]; then - echo "error: Cannot retrieve context ${old_name}." >&2 - exit 1 - fi - if context_exists "${new_name}"; then echo "Context \"${new_name}\" exists, deleting..." >&2 kubectl config delete-context "${new_name}" 1>/dev/null 2>&1 @@ -148,6 +142,12 @@ kubectl config rename-context "${old_name}" "${new_name}" } +delete_contexts() { + for i in "${@}"; do + delete_context "${i}" + done +} + delete_context() { local ctx ctx="${1}" @@ -160,19 +160,22 @@ main() { if [[ "$#" -eq 0 ]]; then - list_contexts + if [[ -t 1 && "$(type fzf &>/dev/null; echo $?)" -eq 0 ]]; then + choose_context_interactive + else + list_contexts + fi elif [[ "${1}" == "-d" ]]; then if [[ "$#" -lt 2 ]]; then echo "error: missing context NAME" >&2 usage - elif [[ "$#" -gt 2 ]]; then - echo "error: too many arguments" >&2 - usage + exit 1 fi - delete_context "${2}" + delete_contexts "${@:2}" elif [[ "$#" -gt 1 ]]; then echo "error: too many arguments" >&2 usage + exit 1 elif [[ "$#" -eq 1 ]]; then if [[ "${1}" == "-" ]]; then swap_context @@ -181,6 +184,7 @@ elif [[ "${1}" =~ ^-(.*) ]]; then echo "error: unrecognized flag \"${1}\"" >&2 usage + exit 1 elif [[ "${1}" =~ (.+)=(.+) ]]; then rename_context "${BASH_REMATCH[2]}" "${BASH_REMATCH[1]}" else @@ -188,6 +192,7 @@ fi else usage + exit 1 fi } diff -Nru kubectx-0.5.0/kubens kubectx-0.6.1/kubens --- kubectx-0.5.0/kubens 2018-04-09 23:06:51.000000000 +0000 +++ kubectx-0.6.1/kubens 2018-08-24 16:28:10.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # kubenx(1) is a utility to switch between Kubernetes namespaces. @@ -21,6 +21,7 @@ set -eou pipefail IFS=$'\n\t' +SELF_CMD="$0" KUBENS_DIR="${HOME}/.kube/kubens" usage() { @@ -31,7 +32,6 @@ kubens - : switch to the previous namespace in this context kubens -h,--help : show this message EOF - exit 1 } current_namespace() { @@ -86,6 +86,25 @@ echo "Active namespace is \"${2}\".">&2 } +choose_namespace_interactive() { + # directly calling kubens via fzf might fail with a cryptic error like + # "$FZF_DEFAULT_COMMAND failed", so try to see if we can list namespaces + # locally first + if [[ -z "$(list_namespaces)" ]]; then + echo >&2 "error: could not list namespaces (is the cluster accessible?)" + exit 1 + fi + + local choice + choice="$(FZF_DEFAULT_COMMAND="${SELF_CMD}" fzf --ansi || true)" + if [[ -z "${choice}" ]]; then + echo 2>&1 "error: you did not choose any of the options" + exit 1 + else + set_namespace "${choice}" + fi +} + set_namespace() { local ctx prev ctx="$(current_context)" @@ -105,16 +124,20 @@ list_namespaces() { local yellow darkbg normal - yellow=$(tput setaf 3) - darkbg=$(tput setab 0) - normal=$(tput sgr0) + yellow=$(tput setaf 3 || true) + darkbg=$(tput setab 0 || true) + normal=$(tput sgr0 || true) + + local cur_ctx_fg cur_ctx_bg + cur_ctx_fg=${KUBECTX_CURRENT_FGCOLOR:-$yellow} + cur_ctx_bg=${KUBECTX_CURRENT_BGCOLOR:-$darkbg} local cur ns_list cur="$(current_namespace)" ns_list=$(get_namespaces) for c in $ns_list; do - if [[ "${c}" = "${cur}" ]]; then - echo "${darkbg}${yellow}${c}${normal}" + if [[ -t 1 && -z "${NO_COLOR:-}" && "${c}" = "${cur}" ]]; then + echo "${cur_ctx_bg}${cur_ctx_fg}${c}${normal}" else echo "${c}" fi @@ -134,7 +157,11 @@ main() { if [[ "$#" -eq 0 ]]; then - list_namespaces + if [[ -t 1 && "$(type fzf &>/dev/null; echo $?)" -eq 0 ]]; then + choose_namespace_interactive + else + list_namespaces + fi elif [[ "$#" -eq 1 ]]; then if [[ "${1}" == '-h' || "${1}" == '--help' ]]; then usage @@ -143,6 +170,7 @@ elif [[ "${1}" =~ ^-(.*) ]]; then echo "error: unrecognized flag \"${1}\"" >&2 usage + exit 1 elif [[ "${1}" =~ (.+)=(.+) ]]; then alias_context "${BASH_REMATCH[2]}" "${BASH_REMATCH[1]}" else @@ -151,6 +179,7 @@ else echo "error: too many flags" >&2 usage + exit 1 fi } diff -Nru kubectx-0.5.0/README.md kubectx-0.6.1/README.md --- kubectx-0.5.0/README.md 2018-04-09 23:06:51.000000000 +0000 +++ kubectx-0.6.1/README.md 2018-08-24 16:28:10.000000000 +0000 @@ -1,10 +1,10 @@ This repository provides both `kubectx` and `kubens` tools. -**`kubectx`** help you switch between clusters back and forth: +**`kubectx`** helps you switch between clusters back and forth: ![kubectx demo GIF](img/kubectx-demo.gif) -**`kubens`** help you switch between Kubernetes namespaces smoothly: +**`kubens`** helps you switch between Kubernetes namespaces smoothly: ![kubens demo GIF](img/kubens-demo.gif) # kubectx(1) @@ -18,7 +18,9 @@ kubectx - : switch to the previous context kubectx = : rename context to kubectx =. : rename current-context to - kubectx -h,--help : show this message + kubectx -d : delete context ('.' for current-context) + (this command won't delete the user/cluster entry + that is used by the context) ``` ### Usage @@ -52,7 +54,6 @@ kubens : list the namespaces kubens : change the active namespace kubens - : switch to the previous namespace - kubens -h,--help : show this message ``` @@ -74,7 +75,7 @@ ## Installation -**macOS:** +### macOS :confetti_ball: Use the [Homebrew](https://brew.sh/) package manager: @@ -89,7 +90,7 @@ - If you like to add context/namespace info to your shell prompt (`$PS1`), I recommend trying out [kube-ps1](https://github.com/jonmosco/kube-ps1). -**Linux:** +### Linux Since `kubectx`/`kubens` are written in Bash, you should be able to instal them to any POSIX environment that has Bash installed. @@ -110,6 +111,44 @@ sudo ln -s /opt/kubectx/kubens /usr/local/bin/kubens ``` +#### Arch Linux + +An unofficial [AUR package](https://aur.archlinux.org/packages/kubectx) `kubectx` +is available. Install instructions can be found on the [Arch +wiki](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages). + +#### Debian/Ubuntu + +Available as a Debian package for [Debian Buster (testing)](https://packages.debian.org/buster/kubectx), [Sid (unstable)](https://packages.debian.org/sid/kubectx) (_note: if you are unfamiliar with Debian release process and how to enable testing/unstable repos, check the [Debian Wiki](https://wiki.debian.org/DebianReleases)_): + +``` bash +sudo apt install kubectx +``` + +----- + +### Interactive mode + +If you want `kubectx` and `kubens` commands to present you an interactive menu +with fuzzy searching, you just need to [install +`fzf`](https://github.com/junegunn/fzf) in your PATH. + +![kubectx interactive search with fzf](img/kubectx-interactive.gif) + +----- + +### Customizing colors + +If you like to customize the colors indicating the current namespace or context, set the environment variables `KUBECTX_CURRENT_FGCOLOR` and `KUBECTX_CURRENT_BGCOLOR` (refer color codes [here](https://linux.101hacks.com/ps1-examples/prompt-color-using-tput/)): + +``` +export KUBECTX_CURRENT_FGCOLOR=$(tput setaf 6) # blue text +export KUBECTX_CURRENT_BGCOLOR=$(tput setaf 7) # white background +``` + +Colors in the output can be disabled by setting the +[`NO_COLOR`](http://no-color.org/) environment variable. + ----- #### Users