From c22bf43ba3257614a02a28c444b4b5c7111e6c2f Mon Sep 17 00:00:00 2001 From: Jacob Tomlinson Date: Thu, 4 Jan 2024 14:00:07 +0000 Subject: [PATCH 1/2] Add support for v5 Exec protocol when using Kubernetes 1.29+ --- kr8s/_exec.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/kr8s/_exec.py b/kr8s/_exec.py index 4d784b4f..e90e66c5 100644 --- a/kr8s/_exec.py +++ b/kr8s/_exec.py @@ -20,7 +20,6 @@ ERROR_CHANNEL = 3 RESIZE_CHANNEL = 4 CLOSE_CHANNEL = 255 -EXEC_PROTOCOL = "v4.channel.k8s.io" class Exec: @@ -55,10 +54,15 @@ def __init__( async def run( self, ) -> None: + version = await self._resource.api.version() + if int(version["major"]) > 1 or int(version["minor"]) > 28: + exec_protocol = "v5.channel.k8s.io" + else: + exec_protocol = "v4.channel.k8s.io" async with self._resource.api.open_websocket( version=self._resource.version, url=f"{self._resource.endpoint}/{self._resource.name}/exec", - protocols=(EXEC_PROTOCOL,), + protocols=(exec_protocol,), namespace=self._resource.namespace, params={ "command": self.args, @@ -72,7 +76,7 @@ async def run( if ws.protocol != "v5.channel.k8s.io": raise ExecError( "Stdin is not supported with protocol " - f"{ws.protocol}, only with v5.channel.k8s.io" + f"{ws.protocol}, only with v5.channel.k8s.io from Kubernetes 1.29+" ) if isinstance(self._stdin, str): await ws.send_bytes(STDIN_CHANNEL.to_bytes() + self._stdin.encode()) From 6c49345e61061b616e7a5f243d7071c6946b66c5 Mon Sep 17 00:00:00 2001 From: Jacob Tomlinson Date: Thu, 4 Jan 2024 14:02:34 +0000 Subject: [PATCH 2/2] Update test to be version aware --- kr8s/tests/test_objects.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/kr8s/tests/test_objects.py b/kr8s/tests/test_objects.py index 3b6b1867..c6e92d39 100644 --- a/kr8s/tests/test_objects.py +++ b/kr8s/tests/test_objects.py @@ -759,10 +759,15 @@ async def test_pod_exec_to_file(ubuntu_pod): assert b"invalid date" in tmp.read() -@pytest.mark.xfail(reason="Exec protocol v5.channel.k8s.io not available") async def test_pod_exec_stdin(ubuntu_pod): - ex = await ubuntu_pod.exec(["cat"], stdin="foo") - assert b"foo" in ex.stdout + api = await kr8s.asyncio.api() + version = await api.version() + if int(version["major"]) == 1 and int(version["minor"]) < 29: + with pytest.raises(ExecError): + await ubuntu_pod.exec(["cat"], stdin="foo") + else: + ex = await ubuntu_pod.exec(["cat"], stdin="foo") + assert b"foo" in ex.stdout async def test_configmap_data(ns):