From f7efd92dabd9e44abcc86464020dd0d5316b3367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20P=C3=A9rez?= Date: Wed, 25 Sep 2024 12:38:43 -0400 Subject: [PATCH] Only drop capabilities that are not added (#3972) It appears that containerd has changed the behavior around adding/dropping linux capabilities and added caps no longer take precedence over dropped ones --- paasta_tools/kubernetes_tools.py | 10 +++++++++- tests/test_kubernetes_tools.py | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/paasta_tools/kubernetes_tools.py b/paasta_tools/kubernetes_tools.py index 1cb8b743b5..a61c9cfcdb 100644 --- a/paasta_tools/kubernetes_tools.py +++ b/paasta_tools/kubernetes_tools.py @@ -1396,7 +1396,15 @@ def get_security_context(self) -> Optional[V1SecurityContext]: return V1SecurityContext(capabilities=V1Capabilities(drop=CAPS_DROP)) else: return V1SecurityContext( - capabilities=V1Capabilities(add=cap_add, drop=CAPS_DROP) + # XXX: we should probably generally work in sets, but V1Capabilities is typed as accepting + # lists of string only + capabilities=V1Capabilities( + add=cap_add, + # NOTE: this is necessary as containerd differs in behavior from dockershim: in dockershim + # dropped capabilities were overriden if the same capability was added - but in containerd + # the dropped capabilities appear to have higher priority. + drop=list(set(CAPS_DROP) - set(cap_add)), + ) ) def get_kubernetes_containers( diff --git a/tests/test_kubernetes_tools.py b/tests/test_kubernetes_tools.py index a43c1ba0a1..7b8818d350 100644 --- a/tests/test_kubernetes_tools.py +++ b/tests/test_kubernetes_tools.py @@ -1067,8 +1067,9 @@ def test_get_security_context_without_cap_add(self): def test_get_security_context_with_cap_add(self): self.deployment.config_dict["cap_add"] = ["SETGID"] + expected_dropped_caps = list(set(CAPS_DROP) - {"SETGID"}) expected_security_context = V1SecurityContext( - capabilities=V1Capabilities(add=["SETGID"], drop=CAPS_DROP) + capabilities=V1Capabilities(add=["SETGID"], drop=expected_dropped_caps) ) assert self.deployment.get_security_context() == expected_security_context