Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lxd_connection: Allow non-root users to connect to an instance #9659

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
433ed7c
fix: add support for non-root user
yeetypete Jan 31, 2025
bb81a7b
fix: show correct info for connection
yeetypete Jan 31, 2025
4ebd4a6
fix: use build_exec_command to execute as nonroot
yeetypete Jan 31, 2025
28fb13b
unset default user
yeetypete Jan 31, 2025
4a66137
feat: add options for setting remote user and become method
yeetypete Jan 31, 2025
de8272c
fix: add root as default remote_user
yeetypete Jan 31, 2025
daf5eaa
fix: remove ansible_ssh_user from remote_user vars
yeetypete Jan 31, 2025
8457056
fix: use single quotes inside f-string
yeetypete Jan 31, 2025
30a6f46
fix: ensure lxc exec comes first
yeetypete Jan 31, 2025
297f3c0
fix: line length
yeetypete Jan 31, 2025
fe0add0
fix: use -c flag with su
yeetypete Jan 31, 2025
553f38a
Update plugins/connection/lxd.py
yeetypete Jan 31, 2025
42a51c9
Update plugins/connection/lxd.py
yeetypete Jan 31, 2025
e40b0e2
Update plugins/connection/lxd.py
yeetypete Jan 31, 2025
eb0989d
doc: add changelog fragment
yeetypete Jan 31, 2025
ad0ff79
fix: use underscore for module name in fragment
yeetypete Jan 31, 2025
4f097d9
Update 9659-lxd_connection-nonroot-user.yml
yeetypete Feb 1, 2025
4eb496c
fix: add put command
yeetypete Feb 2, 2025
b27fdf0
feat: add get_remote_uid_gid placeholder function
yeetypete Feb 2, 2025
cce1c3c
feat: complete placeholder _get_remote_uid_gid function
yeetypete Feb 2, 2025
478b25c
fix: better logging
yeetypete Feb 2, 2025
bdb9ab3
fix: ensure default values are of type str
yeetypete Feb 2, 2025
894c28f
fix: use ints for uid and gid
yeetypete Feb 2, 2025
b258396
fix: print put command
yeetypete Feb 2, 2025
ab11857
fix: format
yeetypete Feb 2, 2025
e2d3fe7
fix: display msg for PUT
yeetypete Feb 2, 2025
bb32620
fix: add comment about defaults
yeetypete Feb 2, 2025
06fb16c
fix: format
yeetypete Feb 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/9659-lxd_connection-nonroot-user.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- lxd_connection - adds ``remote_user`` and ``lxd_become_method`` parameters for allowing a non-root user to connect to an LXD instance (https://github.com/ansible-collections/community.general/pull/9659).
yeetypete marked this conversation as resolved.
Show resolved Hide resolved
66 changes: 51 additions & 15 deletions plugins/connection/lxd.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@
vars:
- name: ansible_executable
- name: ansible_lxd_executable
lxd_become_method:
description:
- Become command used to switch to a non-root user.
yeetypete marked this conversation as resolved.
Show resolved Hide resolved
- Is only used when O(remote_user) is not V(root).
type: str
default: /bin/su
vars:
- name: lxd_become_method
yeetypete marked this conversation as resolved.
Show resolved Hide resolved
version_added: 10.4.0
remote:
description:
- Name of the LXD remote to use.
Expand All @@ -40,6 +49,22 @@
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
default: root
vars:
- name: ansible_user
env:
- name: ANSIBLE_REMOTE_USER
ini:
- section: defaults
key: remote_user
keyword:
- name: remote_user
yeetypete marked this conversation as resolved.
Show resolved Hide resolved
version_added: 10.4.0
project:
description:
- Name of the LXD project to use.
Expand All @@ -63,7 +88,6 @@ class Connection(ConnectionBase):

transport = 'community.general.lxd'
has_pipelining = True
default_user = 'root'

def __init__(self, play_context, new_stdin, *args, **kwargs):
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
Expand All @@ -73,9 +97,6 @@ def __init__(self, play_context, new_stdin, *args, **kwargs):
except ValueError:
raise AnsibleError("lxc command not found in PATH")

if self._play_context.remote_user is not None and self._play_context.remote_user != 'root':
self._display.warning('lxd does not support remote_user, using default: root')

def _host(self):
""" translate remote_addr to lxd (short) hostname """
return self.get_option("remote_addr").split(".", 1)[0]
Expand All @@ -85,25 +106,40 @@ def _connect(self):
super(Connection, self)._connect()

if not self._connected:
self._display.vvv("ESTABLISH LXD CONNECTION FOR USER: root", 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_command(self, cmd) -> str:
"""build the command to execute on the lxd host"""

exec_cmd = [self._lxc_cmd]

if self.get_option("project"):
exec_cmd.extend(["--project", self.get_option("project")])

exec_cmd.extend(["exec", f"{self.get_option('remote')}:{self._host()}", "--"])

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"), "-c"]
)

exec_cmd.extend([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._lxc_cmd]
if self.get_option("project"):
local_cmd.extend(["--project", self.get_option("project")])
local_cmd.extend([
"exec",
f"{self.get_option('remote')}:{self._host()}",
"--",
self.get_option("executable"), "-c", cmd
])

local_cmd = self._build_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]
Expand Down