From 5adcc9299fdf8cc51307d16d4edc8575536022cd Mon Sep 17 00:00:00 2001 From: Nir Soffer Date: Wed, 7 Jun 2023 17:35:56 +0300 Subject: [PATCH] Fix kubectl.version() when cluster is not accessible Looks like `kubect version` change the behavior - if kubectl cannot access the cluster, it output the expected json, but fails with non zero error code. This causes `drenv stop` to fail since it assumes that stopped cluster is reported by `kubectl.version()` by reporting version info without server version. This issue is easy to reproduce: 1. Start example env 2. Stop one of the vms (using virt-manager or virsh) 3. Run `drenv stop envs/example.yaml` drenv fails with: drenv.commands.Error: Command failed: command: ('kubectl', 'version', '--context', 'ex1', '--output', 'json') exitcode: 1 output: { "clientVersion": { "major": "1", "minor": "27", "gitVersion": "v1.27.2", "gitCommit": "7f6f68fdabc4df88cfea2dcf9a19b2b830f1e647", "gitTreeState": "clean", "buildDate": "2023-05-17T14:20:07Z", "goVersion": "go1.20.4", "compiler": "gc", "platform": "linux/amd64" }, "kustomizeVersion": "v5.0.1" } error: Unable to connect to the server: dial tcp 192.168.39.232:8443: connect: no route to host Fixed by treating the special case of failing with output as success (as it should be) and returning the output to the caller. The caller can detect that the cluster is not running since the "serverVersion" is missing. Fixes: #817 Signed-off-by: Nir Soffer --- test/drenv/kubectl.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/drenv/kubectl.py b/test/drenv/kubectl.py index c13ac0bd1..147dec23e 100644 --- a/test/drenv/kubectl.py +++ b/test/drenv/kubectl.py @@ -10,7 +10,14 @@ def version(context=None, output=None): APIServer. """ args = ["--output", output] if output else [] - return _run("version", *args, context=context) + try: + return _run("version", *args, context=context) + except commands.Error as e: + # If kubectl provided output this is not really an error and the caller + # can use the output. + if e.output: + return e.output + raise def config(*args, context=None):