From 4a661375bb025282280849d6b6fc027e24318e13 Mon Sep 17 00:00:00 2001 From: Peter Siegel Date: Fri, 31 Jan 2025 16:01:03 +0100 Subject: [PATCH] feat: add options for setting remote user and become method --- plugins/connection/lxd.py | 64 +++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/plugins/connection/lxd.py b/plugins/connection/lxd.py index 31ed990981..969f57ce96 100644 --- a/plugins/connection/lxd.py +++ b/plugins/connection/lxd.py @@ -32,6 +32,13 @@ options: vars: - name: ansible_executable - name: ansible_lxd_executable + lxd_become_method: + description: + - Become command used to switch to a non-root user. + type: str + default: /bin/su + vars: + - name: lxd_become_method remote: description: - Name of the LXD remote to use. @@ -40,6 +47,21 @@ options: vars: - name: ansible_lxd_remote version_added: 2.0.0 + remote_user: + description: + - User to login/authenticate as. + - Can be set from the CLI via the C(--user) or C(-u) options. + type: string + vars: + - name: ansible_user + - name: ansible_ssh_user + env: + - name: ANSIBLE_REMOTE_USER + ini: + - section: defaults + key: remote_user + keyword: + - name: remote_user project: description: - Name of the LXD project to use. @@ -63,7 +85,6 @@ class Connection(ConnectionBase): transport = 'community.general.lxd' has_pipelining = True - default_user = None def __init__(self, play_context, new_stdin, *args, **kwargs): super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs) @@ -73,8 +94,6 @@ class Connection(ConnectionBase): except ValueError: raise AnsibleError("lxc command not found in PATH") - self._play_user = self._play_context.remote_user or self.default_user - def _host(self): """ translate remote_addr to lxd (short) hostname """ return self.get_option("remote_addr").split(".", 1)[0] @@ -84,33 +103,40 @@ class Connection(ConnectionBase): super(Connection, self)._connect() if not self._connected: - self._display.vvv(f"ESTABLISH LXD CONNECTION FOR USER: {self._play_user}", host=self._host()) + self._display.vvv(f"ESTABLISH LXD CONNECTION FOR USER: {self.get_option("remote_user")}", host=self._host()) self._connected = True - def _build_exec_command(self, cmd): - """ build the command to execute """ - if self._play_user != "root": - cmd = f"su {self._play_user} {cmd}" - return cmd + def _build_exec_command(self, cmd) -> str: + """ build the command to execute on the lxd host """ - def exec_command(self, cmd, in_data=None, sudoable=True): - """ execute a command on the lxd host """ + exec_cmd = [self._lxc_cmd] - cmd = self._build_exec_command(cmd) - super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable) - - self._display.vvv(f"EXEC {cmd}", host=self._host()) - - local_cmd = [self._lxc_cmd] if self.get_option("project"): - local_cmd.extend(["--project", self.get_option("project")]) - local_cmd.extend([ + exec_cmd.extend(["--project", self.get_option("project")]) + + if self.get_option("remote_user") != "root": + self._display.vvv( + f"INFO: Running as non-root user: {self.get_option('remote_user')}, trying to run 'lxc exec' with become method: {self.get_option('lxd_become_method')}", + host=self._host(), + ) + exec_cmd.extend([self.get_option("lxd_become_method"), self.get_option("remote_user")]) + + exec_cmd.extend([ "exec", f"{self.get_option('remote')}:{self._host()}", "--", self.get_option("executable"), "-c", cmd ]) + return exec_cmd + + def exec_command(self, cmd, in_data=None, sudoable=True): + """ execute a command on the lxd host """ + super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable) + + self._display.vvv(f"EXEC {cmd}", host=self._host()) + + local_cmd = self._build_exec_command(cmd) self._display.vvvvv(f"EXEC {local_cmd}", host=self._host()) local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]