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

Merged
merged 32 commits into from
Feb 15, 2025
Merged
Changes from 10 commits
Commits
Show all changes
32 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
bb2ba14
fix: use os module to get uid and gid
yeetypete Feb 10, 2025
12f770a
Revert "fix: use os module to get uid and gid"
yeetypete Feb 10, 2025
bff936a
Update plugins/connection/lxd.py
yeetypete Feb 14, 2025
fe96c1b
fix: omit uid, gid args in lxd file push if root
yeetypete Feb 14, 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
63 changes: 48 additions & 15 deletions plugins/connection/lxd.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@
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.
Expand All @@ -40,6 +47,21 @@
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
project:
description:
- Name of the LXD project to use.
Expand All @@ -63,7 +85,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 +94,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 +103,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")]
)

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