diff --git a/changelogs/fragments/249-nsenter-fixes.yml b/changelogs/fragments/249-nsenter-fixes.yml new file mode 100644 index 00000000..ea5e0c75 --- /dev/null +++ b/changelogs/fragments/249-nsenter-fixes.yml @@ -0,0 +1,3 @@ +bugfixes: + - "nsenter connection plugin - ensure the ``nsenter_pid`` option is retrieved in ``_connect`` instead of ``__init__`` to prevent a crasher due to bad initialization order (https://github.com/ansible-collections/community.docker/pull/249)." + - "nsenter connection plugin - replace the use of ``--all-namespaces`` with specific namespaces to support compatibility with Busybox nsenter (used on, for example, Alpine containers) (https://github.com/ansible-collections/community.docker/pull/249)." diff --git a/plugins/connection/nsenter.py b/plugins/connection/nsenter.py index 04ab35af..17bef1f9 100644 --- a/plugins/connection/nsenter.py +++ b/plugins/connection/nsenter.py @@ -70,9 +70,10 @@ class Connection(ConnectionBase): def __init__(self, *args, **kwargs): super(Connection, self).__init__(*args, **kwargs) self.cwd = None - self._nsenter_pid = self.get_option("nsenter_pid") def _connect(self): + self._nsenter_pid = self.get_option("nsenter_pid") + # Because nsenter requires very high privileges, our remote user # is always assumed to be root. self._play_context.remote_user = "root" @@ -99,18 +100,24 @@ class Connection(ConnectionBase): " Please verify if the executable exists and re-try." % executable) # Rewrite the provided command to prefix it with nsenter + nsenter_cmd_parts = [ + "nsenter", + "--ipc", + "--mount", + "--net", + "--pid", + "--uts", + "--preserve-credentials", + "--target={0}".format(self._nsenter_pid), + "--", + ] + if isinstance(cmd, (text_type, binary_type)): - nsenter_cmd = "nsenter --all --preserve-credentials --target={0} -- ".format(self._nsenter_pid) - cmd = to_bytes(nsenter_cmd) + to_bytes(cmd) + cmd_parts = nsenter_cmd_parts + [cmd] + cmd = to_bytes(" ".join(cmd_parts)) else: - nsenter_cmd = [ - "nsenter", - "--all", - "--preserve-credentials", - "--target={0}".format(self._nsenter_pid), - "--", - ] - cmd = [to_bytes(arg) for arg in nsenter_cmd + cmd] + cmd_parts = nsenter_cmd_parts + cmd + cmd = [to_bytes(arg) for arg in cmd_parts] display.vvv(u"EXEC {0}".format(to_text(cmd)), host=self._play_context.remote_addr) display.debug("opening command with Popen()")