danielfoehrKn / kubeswitch

The kubectx for operators.
https://danielfoehrkn.medium.com/the-case-of-kubeswitch-aff4b6a04ae7
Apache License 2.0
832 stars 80 forks source link

Bash on Windows (MINGW): the configured kubeconfig directory "C" does not exist #145

Open needleshaped opened 6 hours ago

needleshaped commented 6 hours ago

TLDR: Using Windows with Bash (e.g. git-bash from Git For Windows) + Windows version of kubeswitch results in

user@HOST MINGW64 /c/Users/user
$ s
switched to context dev-cluster

$ s
Error: the configured kubeconfig directory "C" does not exist
the configured kubeconfig directory "C" does not exist

$ s --debug
time="2024-10-17T12:40:16+03:00" level=debug msg="Adding kubeconfig path from KUBECONFIG env C:\\Users\\user/.kube/.switch_tmp\\config.2558873022.tmp"
time="2024-10-17T12:40:17+03:00" level=debug msg="Starting search for store: filesystem" store=filesystem
Error: the configured kubeconfig directory "C" does not exist
the configured kubeconfig directory "C" does not exist

$ echo $KUBECONFIG
KUBECONFIG=C:\Users\user/.kube/.switch_tmp\config.705829183.tmp

! Notice mixed Windows and Linux style paths:

This stems from the fact, that binary and shell do work together: https://github.com/danielfoehrKn/kubeswitch/blob/master/docs/how_it_works.md

  1. The switcher binary writes the filepath to the kubeconfig to STDOUT
  2. The switch.sh script captures this filepath and executes export KUBECONFIG=</path/to/tmp/kubeconfig/file>

HOWEVER, convertion of KUBECONFIG to NEITHER Unix or Bash format works:

# trying UNIX path format
$ unset KUBECONFIG && s
switched to context dev-cluster
$ export KUBECONFIG=$(echo "$KUBECONFIG" | sed -e "s|^C:\\\\|/c/|" -e "s|\\\\|/|g") # same can be achieved by `cygpath -u $KUBECONFIG`, provided by https://www.msys2.org/docs/filesystem-paths/
$ echo $KUBECONFIG && s --debug
/c/Users/user/.kube/.switch_tmp/config.2988942920.tmp

time="2024-10-17T13:40:19+03:00" level=debug msg="Adding kubeconfig path from KUBECONFIG env C:/Users/user/.kube/.switch_tmp/config.2988942920.tmp"
time="2024-10-17T13:40:20+03:00" level=debug msg="Starting search for store: filesystem" store=filesystem
Error: the configured kubeconfig directory "C" does not exist
the configured kubeconfig directory "C" does not exist

# and if we try WINDOWS path format:
$ export KUBECONFIG=$(cygpath -w $KUBECONFIG) && echo $KUBECONFIG && switch --debug
C:\Users\user\.kube\.switch_tmp\config.78735667.tmp

time="2024-10-17T14:01:09+03:00" level=debug msg="Adding kubeconfig path from KUBECONFIG env C:\\Users\\user\\.kube\\.switch_tmp\\config.78735667.tmp"
time="2024-10-17T14:01:10+03:00" level=debug msg="Starting search for store: filesystem" store=filesystem
Error: the configured kubeconfig directory "C" does not exist
the configured kubeconfig directory "C" does not exist

# Using binary directly does not help, same error:
$  switcher --debug
...
the configured kubeconfig directory "C" does not exist

Workaround:

unset KUBECONFIG before running switcher (we loose current context, bad)

Environment:

How to repeat

  1. Install Git For Windows (https://gitforwindows.org) or get it automatically, if you have https://scoop.sh installed
  2. Download Windows binary of kubeswitch: https://github.com/danielfoehrKn/kubeswitch/releases/
  3. Get into bash.exe
  4. Do Bash installation steps were used from documentation

P.S.:

Configuration uses ~ and it works fine, shows up in selection

- kind: filesystem
  kubeconfigName: "*.config"
  paths:
    - ~/.kube/configs-FOO/
- kind: filesystem
  kubeconfigName: "*.config"
  paths:
    - ~/.kube/configs-BAR/
needleshaped commented 5 hours ago

Update! I have installed same binary in Powershell, and noted, that

PS Write-Output $env:KUBECONFIG
/Users/user/.kube/.switch_tmp/config.3246108154.tmp

is without /c or C:\

Also, from original comment you can see, that Windows binary translates path to Windows format on it's own, always.

I see related issue https://github.com/danielfoehrKn/kubeswitch/issues/131

So let's try another workaround, removing disk C

# try with UNIX style path
$ unset KUBECONFIG
$ switch # switched to context dev-cluster
$ export KUBECONFIG=$(cygpath -u "$KUBECONFIG" | sed 's|/c||')
$ echo $KUBECONFIG
/Users/user/.kube/.switch_tmp/config.2390096444.tmp
$ switch --debug
time="2024-10-17T14:41:24+03:00" level=debug msg="Adding kubeconfig path from KUBECONFIG env C:/scoop/apps/git/2.46.0/Users/user/.kube/.switch_tmp/config.2390096444.tmp"
time="2024-10-17T14:41:24+03:00" level=debug msg="Starting search for store: filesystem" store=filesystem
Error: the configured kubeconfig directory "C" does not exist
time="2024-10-17T14:41:24+03:00" level=debug msg="Starting search for store: filesystem" store=filesystem
the configured kubeconfig directory "C" does not exist

Wow, Switcher binary constructs KUBECONFIG path from path to bash.exe + KUBECONFIG without disk

# try with Windows style path
$ unset KUBECONFIG
$ switch # switched to context dev-cluster
$ export KUBECONFIG=$(cygpath -w "$KUBECONFIG" | sed 's|C:||')
$ echo $KUBECONFIG
\Users\user\.kube\.switch_tmp\config.2719742217.tmp
$ switch --debug

And that finally works!

Workaround that works 💡

s() {
    switch "$@" && export KUBECONFIG=$(cygpath -w "$KUBECONFIG" | sed 's|C:||')
    # cygpath used by MINGW https://www.msys2.org/docs/filesystem-paths/
}

Reason?

The code line is: https://github.com/danielfoehrKn/kubeswitch/blame/master/cmd/switcher/init.go#L219 $KUBECONFIG_PATH = $KUBECONFIG_PATH -replace "C:", ""

I wonder, WHY disk is removed from path? this is so awkward, confusing. 😢 Is it attempt to make it portable?