mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
plugins/connection/lxd: convert FQDN to instance name (#7360)
* plugins/connection/lxd: convert FQDN to instance name This allows to use FQDNs in the inventory and have the connection driver do the translation when talking to LXD that uses hostnames (no ".") for instance names. Those are either globally unique or unique per network/ project in LXD. ``` all: # Groups and hosts children: lxd_dmz: vars: ansible_lxd_project: dmz hosts: www01.dmz.example.com: www02.dmz.example.com: ``` ``` $ lxc list --project dmz +---------+---------+----------------+------+-----------+-----------+----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | LOCATION | +-------+---------+------------------+------+-----------+-----------+----------+ | www01 | RUNNING | 192.0.2.1 (eth0) | | CONTAINER | 0 | t1 | +-------+---------+------------------+------+-----------+-----------+----------+ | www02 | RUNNING | 192.0.2.2 (eth0) | | CONTAINER | 0 | t3 | +-------+---------+------------------+------+-----------+-----------+----------+ ``` Signed-off-by: Simon Deziel <simon.deziel@canonical.com> * plugins/connection/lxd: VMs/containers are called instances Update error string parsing to support the new format: $ lxc stop c1 -- true $ lxc exec c1 -- true Error: Instance is not running $ lxc exec does-not-exist -- true Error: Instance not found Signed-off-by: Simon Deziel <simon.deziel@canonical.com> * plugins/connection/lxd: add changelog fragment Signed-off-by: Simon Deziel <simon.deziel@canonical.com> --------- Signed-off-by: Simon Deziel <simon.deziel@canonical.com>
This commit is contained in:
parent
8c7778735d
commit
c7150dd818
2 changed files with 21 additions and 12 deletions
3
changelogs/fragments/7360-lxd-remote-addr-host.yml
Normal file
3
changelogs/fragments/7360-lxd-remote-addr-host.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
minor_changes:
|
||||||
|
- lxd connection plugin - automatically translate ``remote_addr`` from FQDN to (short) hostname (https://github.com/ansible-collections/community.general/pull/7360).
|
||||||
|
- lxd connection plugin - update error parsing to work with newer messages mentioning instances (https://github.com/ansible-collections/community.general/pull/7360).
|
|
@ -16,7 +16,9 @@ DOCUMENTATION = '''
|
||||||
options:
|
options:
|
||||||
remote_addr:
|
remote_addr:
|
||||||
description:
|
description:
|
||||||
- Container identifier.
|
- Instance (container/VM) identifier.
|
||||||
|
- Since community.general 8.0.0, a FQDN can be provided; in that case, the first component (the part before C(.))
|
||||||
|
is used as the instance identifier.
|
||||||
default: inventory_hostname
|
default: inventory_hostname
|
||||||
vars:
|
vars:
|
||||||
- name: inventory_hostname
|
- name: inventory_hostname
|
||||||
|
@ -71,26 +73,30 @@ class Connection(ConnectionBase):
|
||||||
if self._play_context.remote_user is not None and self._play_context.remote_user != 'root':
|
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 container default: root')
|
self._display.warning('lxd does not support remote_user, using container default: root')
|
||||||
|
|
||||||
|
def _host(self):
|
||||||
|
""" translate remote_addr to lxd (short) hostname """
|
||||||
|
return self.get_option("remote_addr").split(".", 1)[0]
|
||||||
|
|
||||||
def _connect(self):
|
def _connect(self):
|
||||||
"""connect to lxd (nothing to do here) """
|
"""connect to lxd (nothing to do here) """
|
||||||
super(Connection, self)._connect()
|
super(Connection, self)._connect()
|
||||||
|
|
||||||
if not self._connected:
|
if not self._connected:
|
||||||
self._display.vvv(u"ESTABLISH LXD CONNECTION FOR USER: root", host=self.get_option('remote_addr'))
|
self._display.vvv(u"ESTABLISH LXD CONNECTION FOR USER: root", host=self._host())
|
||||||
self._connected = True
|
self._connected = True
|
||||||
|
|
||||||
def exec_command(self, cmd, in_data=None, sudoable=True):
|
def exec_command(self, cmd, in_data=None, sudoable=True):
|
||||||
""" execute a command on the lxd host """
|
""" execute a command on the lxd host """
|
||||||
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
|
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
|
||||||
|
|
||||||
self._display.vvv(u"EXEC {0}".format(cmd), host=self.get_option('remote_addr'))
|
self._display.vvv(u"EXEC {0}".format(cmd), host=self._host())
|
||||||
|
|
||||||
local_cmd = [self._lxc_cmd]
|
local_cmd = [self._lxc_cmd]
|
||||||
if self.get_option("project"):
|
if self.get_option("project"):
|
||||||
local_cmd.extend(["--project", self.get_option("project")])
|
local_cmd.extend(["--project", self.get_option("project")])
|
||||||
local_cmd.extend([
|
local_cmd.extend([
|
||||||
"exec",
|
"exec",
|
||||||
"%s:%s" % (self.get_option("remote"), self.get_option("remote_addr")),
|
"%s:%s" % (self.get_option("remote"), self._host()),
|
||||||
"--",
|
"--",
|
||||||
self.get_option("executable"), "-c", cmd
|
self.get_option("executable"), "-c", cmd
|
||||||
])
|
])
|
||||||
|
@ -104,11 +110,11 @@ class Connection(ConnectionBase):
|
||||||
stdout = to_text(stdout)
|
stdout = to_text(stdout)
|
||||||
stderr = to_text(stderr)
|
stderr = to_text(stderr)
|
||||||
|
|
||||||
if stderr == "error: Container is not running.\n":
|
if "is not running" in stderr:
|
||||||
raise AnsibleConnectionFailure("container not running: %s" % self.get_option('remote_addr'))
|
raise AnsibleConnectionFailure("instance not running: %s" % self._host())
|
||||||
|
|
||||||
if stderr == "error: not found\n":
|
if "not found" in stderr:
|
||||||
raise AnsibleConnectionFailure("container not found: %s" % self.get_option('remote_addr'))
|
raise AnsibleConnectionFailure("instance not found: %s" % self._host())
|
||||||
|
|
||||||
return process.returncode, stdout, stderr
|
return process.returncode, stdout, stderr
|
||||||
|
|
||||||
|
@ -116,7 +122,7 @@ class Connection(ConnectionBase):
|
||||||
""" put a file from local to lxd """
|
""" put a file from local to lxd """
|
||||||
super(Connection, self).put_file(in_path, out_path)
|
super(Connection, self).put_file(in_path, out_path)
|
||||||
|
|
||||||
self._display.vvv(u"PUT {0} TO {1}".format(in_path, out_path), host=self.get_option('remote_addr'))
|
self._display.vvv(u"PUT {0} TO {1}".format(in_path, out_path), host=self._host())
|
||||||
|
|
||||||
if not os.path.isfile(to_bytes(in_path, errors='surrogate_or_strict')):
|
if not os.path.isfile(to_bytes(in_path, errors='surrogate_or_strict')):
|
||||||
raise AnsibleFileNotFound("input path is not a file: %s" % in_path)
|
raise AnsibleFileNotFound("input path is not a file: %s" % in_path)
|
||||||
|
@ -127,7 +133,7 @@ class Connection(ConnectionBase):
|
||||||
local_cmd.extend([
|
local_cmd.extend([
|
||||||
"file", "push",
|
"file", "push",
|
||||||
in_path,
|
in_path,
|
||||||
"%s:%s/%s" % (self.get_option("remote"), self.get_option("remote_addr"), out_path)
|
"%s:%s/%s" % (self.get_option("remote"), self._host(), out_path)
|
||||||
])
|
])
|
||||||
|
|
||||||
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
|
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
|
||||||
|
@ -139,14 +145,14 @@ class Connection(ConnectionBase):
|
||||||
""" fetch a file from lxd to local """
|
""" fetch a file from lxd to local """
|
||||||
super(Connection, self).fetch_file(in_path, out_path)
|
super(Connection, self).fetch_file(in_path, out_path)
|
||||||
|
|
||||||
self._display.vvv(u"FETCH {0} TO {1}".format(in_path, out_path), host=self.get_option('remote_addr'))
|
self._display.vvv(u"FETCH {0} TO {1}".format(in_path, out_path), host=self._host())
|
||||||
|
|
||||||
local_cmd = [self._lxc_cmd]
|
local_cmd = [self._lxc_cmd]
|
||||||
if self.get_option("project"):
|
if self.get_option("project"):
|
||||||
local_cmd.extend(["--project", self.get_option("project")])
|
local_cmd.extend(["--project", self.get_option("project")])
|
||||||
local_cmd.extend([
|
local_cmd.extend([
|
||||||
"file", "pull",
|
"file", "pull",
|
||||||
"%s:%s/%s" % (self.get_option("remote"), self.get_option("remote_addr"), in_path),
|
"%s:%s/%s" % (self.get_option("remote"), self._host(), in_path),
|
||||||
out_path
|
out_path
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue