diff --git a/changelogs/fragments/7360-lxd-remote-addr-host.yml b/changelogs/fragments/7360-lxd-remote-addr-host.yml new file mode 100644 index 0000000000..31a389e7a6 --- /dev/null +++ b/changelogs/fragments/7360-lxd-remote-addr-host.yml @@ -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). diff --git a/plugins/connection/lxd.py b/plugins/connection/lxd.py index affb87dfd0..4ad81be399 100644 --- a/plugins/connection/lxd.py +++ b/plugins/connection/lxd.py @@ -16,7 +16,9 @@ DOCUMENTATION = ''' options: remote_addr: 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 vars: - 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': 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): """connect to lxd (nothing to do here) """ super(Connection, self)._connect() 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 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(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] if self.get_option("project"): local_cmd.extend(["--project", self.get_option("project")]) local_cmd.extend([ "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 ]) @@ -104,11 +110,11 @@ class Connection(ConnectionBase): stdout = to_text(stdout) stderr = to_text(stderr) - if stderr == "error: Container is not running.\n": - raise AnsibleConnectionFailure("container not running: %s" % self.get_option('remote_addr')) + if "is not running" in stderr: + raise AnsibleConnectionFailure("instance not running: %s" % self._host()) - if stderr == "error: not found\n": - raise AnsibleConnectionFailure("container not found: %s" % self.get_option('remote_addr')) + if "not found" in stderr: + raise AnsibleConnectionFailure("instance not found: %s" % self._host()) return process.returncode, stdout, stderr @@ -116,7 +122,7 @@ class Connection(ConnectionBase): """ put a file from local to lxd """ 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')): raise AnsibleFileNotFound("input path is not a file: %s" % in_path) @@ -127,7 +133,7 @@ class Connection(ConnectionBase): local_cmd.extend([ "file", "push", 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] @@ -139,14 +145,14 @@ class Connection(ConnectionBase): """ fetch a file from lxd to local """ 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] if self.get_option("project"): local_cmd.extend(["--project", self.get_option("project")]) local_cmd.extend([ "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 ])