We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
community.general.lxd connection not working with molecule
### Summary

When I try to run `molecule create` with the [lxd driver](https://github.com/ansible-community/molecule-lxd), it creates the lxc container correctly, but then gives a warning and then fails to run a command on the container.
```
[WARNING]: The "ansible_collections.community.general.plugins.connection.lxd" connection plugin has an improperly configured remote target value, forcing "inventory_hostname" templated value instead of the string
```
After some debugging, I found that the `remote_addr` value was being set to the literal string 'inventory_hostname' instead of the value of the current host's `inventory_hostname`. I found another connection plugin that had [fixed a similar issue](https://github.com/ansible/ansible/pull/77894).

Applying this patch to the `plugins/connection/lxd.py` file fixes the problem.

[fix_lxd_inventory_hostname.patch.txt](https://github.com/ansible-collections/community.general/files/8960273/fix_lxd_inventory_hostname.patch.txt)


### Issue Type

Bug Report

### Component Name

plugins/connection/lxd.py

### Ansible Version

```console (paste below)
$ ansible --version
ansible [core 2.13.1]
  config file = /home/anton/ansible-collection-oit-ne-servers/roles/common/ansible.cfg
  configured module search path = ['/home/anton/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/anton/ansible-collection-oit-ne-servers/.venv/lib/python3.10/site-packages/ansible
  ansible collection location = /home/anton/ansible-collection-oit-ne-servers/roles/common/.collections
  executable location = /home/anton/ansible-collection-oit-ne-servers/.venv/bin/ansible
  python version = 3.10.5 (main, Jun 11 2022, 16:53:24) [GCC 9.4.0]
  jinja version = 3.1.2
  libyaml = False

```


### Community.general Version

```console (paste below)
$ ansible-galaxy collection list community.general
Collection        Version
----------------- -------
community.general 5.2.0 
```


### Configuration

```console (paste below)
$ ansible-config dump --only-changed

```


### OS / Environment

cat /etc/os-release 
NAME="Ubuntu"
VERSION="20.04.4 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.4 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```console
$ mkdir tmp
$ cd tmp
$ python3 -m venv .venv
$ . .venv/bin/activate
$ python3 -m pip install --upgrade pip setuptools wheel
$ python3 -m pip install ansible molecule molecule-lxd
$ molecule init role tmp.common --driver-name lxd
$ cd common
```

Modify `molecule/default/molecule.yml`:
```yaml (paste below)
dependency:
  name: galaxy
driver:
  name: lxd
platforms:
  - name: centos-stream-8
    source:
      type: image
      mode: pull
      server: https://images.linuxcontainers.org
      protocol: simplestreams
      alias: centos/8-Stream/amd64
    profiles: ["default"]
provisioner:
  name: ansible
verifier:
  name: ansible
```

```console
$ molecule create
```

### Expected Results

I expected that the lxd container would be properly created and prepared.

### Actual Results

```console (paste below)
PLAY [Prepare] *****************************************************************

TASK [Install basic packages to bare containers] *******************************
[WARNING]: The "lxd" connection plugin has an improperly configured remote
target value, forcing "inventory_hostname" templated value instead of the
string
fatal: [centos-stream-8]: FAILED! => {"changed": true, "msg": "non-zero return code", "rc": 1, "stderr": "Error: Instance not found\n", "stderr_lines": ["Error: Instance not found"], "stdout": "", "stdout_lines": []}

```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `plugins/connection/lxd.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 # (c) 2016 Matt Clay <matt@mystile.com>
3 # (c) 2017 Ansible Project
4 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5 
6 from __future__ import (absolute_import, division, print_function)
7 __metaclass__ = type
8 
9 DOCUMENTATION = '''
10     author: Matt Clay (@mattclay) <matt@mystile.com>
11     name: lxd
12     short_description: Run tasks in lxc containers via lxc CLI
13     description:
14         - Run commands or put/fetch files to an existing lxc container using lxc CLI
15     options:
16       remote_addr:
17         description:
18             - Container identifier.
19         default: inventory_hostname
20         vars:
21             - name: ansible_host
22             - name: ansible_lxd_host
23       executable:
24         description:
25             - shell to use for execution inside container
26         default: /bin/sh
27         vars:
28             - name: ansible_executable
29             - name: ansible_lxd_executable
30       remote:
31         description:
32             - Name of the LXD remote to use.
33         default: local
34         vars:
35             - name: ansible_lxd_remote
36         version_added: 2.0.0
37       project:
38         description:
39             - Name of the LXD project to use.
40         vars:
41             - name: ansible_lxd_project
42         version_added: 2.0.0
43 '''
44 
45 import os
46 from subprocess import Popen, PIPE
47 
48 from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound
49 from ansible.module_utils.common.process import get_bin_path
50 from ansible.module_utils.common.text.converters import to_bytes, to_text
51 from ansible.plugins.connection import ConnectionBase
52 
53 
54 class Connection(ConnectionBase):
55     """ lxd based connections """
56 
57     transport = 'community.general.lxd'
58     has_pipelining = True
59     default_user = 'root'
60 
61     def __init__(self, play_context, new_stdin, *args, **kwargs):
62         super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
63 
64         self._host = self._play_context.remote_addr
65         try:
66             self._lxc_cmd = get_bin_path("lxc")
67         except ValueError:
68             raise AnsibleError("lxc command not found in PATH")
69 
70         if self._play_context.remote_user is not None and self._play_context.remote_user != 'root':
71             self._display.warning('lxd does not support remote_user, using container default: root')
72 
73     def _connect(self):
74         """connect to lxd (nothing to do here) """
75         super(Connection, self)._connect()
76 
77         if not self._connected:
78             self._display.vvv(u"ESTABLISH LXD CONNECTION FOR USER: root", host=self._host)
79             self._connected = True
80 
81     def exec_command(self, cmd, in_data=None, sudoable=True):
82         """ execute a command on the lxd host """
83         super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
84 
85         self._display.vvv(u"EXEC {0}".format(cmd), host=self._host)
86 
87         local_cmd = [self._lxc_cmd]
88         if self.get_option("project"):
89             local_cmd.extend(["--project", self.get_option("project")])
90         local_cmd.extend([
91             "exec",
92             "%s:%s" % (self.get_option("remote"), self.get_option("remote_addr")),
93             "--",
94             self.get_option("executable"), "-c", cmd
95         ])
96 
97         local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
98         in_data = to_bytes(in_data, errors='surrogate_or_strict', nonstring='passthru')
99 
100         process = Popen(local_cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
101         stdout, stderr = process.communicate(in_data)
102 
103         stdout = to_text(stdout)
104         stderr = to_text(stderr)
105 
106         if stderr == "error: Container is not running.\n":
107             raise AnsibleConnectionFailure("container not running: %s" % self._host)
108 
109         if stderr == "error: not found\n":
110             raise AnsibleConnectionFailure("container not found: %s" % self._host)
111 
112         return process.returncode, stdout, stderr
113 
114     def put_file(self, in_path, out_path):
115         """ put a file from local to lxd """
116         super(Connection, self).put_file(in_path, out_path)
117 
118         self._display.vvv(u"PUT {0} TO {1}".format(in_path, out_path), host=self._host)
119 
120         if not os.path.isfile(to_bytes(in_path, errors='surrogate_or_strict')):
121             raise AnsibleFileNotFound("input path is not a file: %s" % in_path)
122 
123         local_cmd = [self._lxc_cmd]
124         if self.get_option("project"):
125             local_cmd.extend(["--project", self.get_option("project")])
126         local_cmd.extend([
127             "file", "push",
128             in_path,
129             "%s:%s/%s" % (self.get_option("remote"), self.get_option("remote_addr"), out_path)
130         ])
131 
132         local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
133 
134         process = Popen(local_cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
135         process.communicate()
136 
137     def fetch_file(self, in_path, out_path):
138         """ fetch a file from lxd to local """
139         super(Connection, self).fetch_file(in_path, out_path)
140 
141         self._display.vvv(u"FETCH {0} TO {1}".format(in_path, out_path), host=self._host)
142 
143         local_cmd = [self._lxc_cmd]
144         if self.get_option("project"):
145             local_cmd.extend(["--project", self.get_option("project")])
146         local_cmd.extend([
147             "file", "pull",
148             "%s:%s/%s" % (self.get_option("remote"), self.get_option("remote_addr"), in_path),
149             out_path
150         ])
151 
152         local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
153 
154         process = Popen(local_cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
155         process.communicate()
156 
157     def close(self):
158         """ close the connection (nothing to do here) """
159         super(Connection, self).close()
160 
161         self._connected = False
162
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/plugins/connection/lxd.py b/plugins/connection/lxd.py
--- a/plugins/connection/lxd.py
+++ b/plugins/connection/lxd.py
@@ -18,6 +18,7 @@
             - Container identifier.
         default: inventory_hostname
         vars:
+            - name: inventory_hostname
             - name: ansible_host
             - name: ansible_lxd_host
       executable:
@@ -61,7 +62,6 @@
     def __init__(self, play_context, new_stdin, *args, **kwargs):
         super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
 
-        self._host = self._play_context.remote_addr
         try:
             self._lxc_cmd = get_bin_path("lxc")
         except ValueError:
@@ -75,14 +75,14 @@
         super(Connection, self)._connect()
 
         if not self._connected:
-            self._display.vvv(u"ESTABLISH LXD CONNECTION FOR USER: root", host=self._host)
+            self._display.vvv(u"ESTABLISH LXD CONNECTION FOR USER: root", host=self.get_option('remote_addr'))
             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._host)
+        self._display.vvv(u"EXEC {0}".format(cmd), host=self.get_option('remote_addr'))
 
         local_cmd = [self._lxc_cmd]
         if self.get_option("project"):
@@ -104,10 +104,10 @@
         stderr = to_text(stderr)
 
         if stderr == "error: Container is not running.\n":
-            raise AnsibleConnectionFailure("container not running: %s" % self._host)
+            raise AnsibleConnectionFailure("container not running: %s" % self.get_option('remote_addr'))
 
         if stderr == "error: not found\n":
-            raise AnsibleConnectionFailure("container not found: %s" % self._host)
+            raise AnsibleConnectionFailure("container not found: %s" % self.get_option('remote_addr'))
 
         return process.returncode, stdout, stderr
 
@@ -115,7 +115,7 @@
         """ 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._host)
+        self._display.vvv(u"PUT {0} TO {1}".format(in_path, out_path), host=self.get_option('remote_addr'))
 
         if not os.path.isfile(to_bytes(in_path, errors='surrogate_or_strict')):
             raise AnsibleFileNotFound("input path is not a file: %s" % in_path)
@@ -138,7 +138,7 @@
         """ 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._host)
+        self._display.vvv(u"FETCH {0} TO {1}".format(in_path, out_path), host=self.get_option('remote_addr'))
 
         local_cmd = [self._lxc_cmd]
         if self.get_option("project"):

{"golden_diff": "diff --git a/plugins/connection/lxd.py b/plugins/connection/lxd.py\n--- a/plugins/connection/lxd.py\n+++ b/plugins/connection/lxd.py\n@@ -18,6 +18,7 @@\n             - Container identifier.\n         default: inventory_hostname\n         vars:\n+            - name: inventory_hostname\n             - name: ansible_host\n             - name: ansible_lxd_host\n       executable:\n@@ -61,7 +62,6 @@\n     def __init__(self, play_context, new_stdin, *args, **kwargs):\n         super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)\n \n-        self._host = self._play_context.remote_addr\n         try:\n             self._lxc_cmd = get_bin_path(\"lxc\")\n         except ValueError:\n@@ -75,14 +75,14 @@\n         super(Connection, self)._connect()\n \n         if not self._connected:\n-            self._display.vvv(u\"ESTABLISH LXD CONNECTION FOR USER: root\", host=self._host)\n+            self._display.vvv(u\"ESTABLISH LXD CONNECTION FOR USER: root\", host=self.get_option('remote_addr'))\n             self._connected = True\n \n     def exec_command(self, cmd, in_data=None, sudoable=True):\n         \"\"\" execute a command on the lxd host \"\"\"\n         super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)\n \n-        self._display.vvv(u\"EXEC {0}\".format(cmd), host=self._host)\n+        self._display.vvv(u\"EXEC {0}\".format(cmd), host=self.get_option('remote_addr'))\n \n         local_cmd = [self._lxc_cmd]\n         if self.get_option(\"project\"):\n@@ -104,10 +104,10 @@\n         stderr = to_text(stderr)\n \n         if stderr == \"error: Container is not running.\\n\":\n-            raise AnsibleConnectionFailure(\"container not running: %s\" % self._host)\n+            raise AnsibleConnectionFailure(\"container not running: %s\" % self.get_option('remote_addr'))\n \n         if stderr == \"error: not found\\n\":\n-            raise AnsibleConnectionFailure(\"container not found: %s\" % self._host)\n+            raise AnsibleConnectionFailure(\"container not found: %s\" % self.get_option('remote_addr'))\n \n         return process.returncode, stdout, stderr\n \n@@ -115,7 +115,7 @@\n         \"\"\" put a file from local to lxd \"\"\"\n         super(Connection, self).put_file(in_path, out_path)\n \n-        self._display.vvv(u\"PUT {0} TO {1}\".format(in_path, out_path), host=self._host)\n+        self._display.vvv(u\"PUT {0} TO {1}\".format(in_path, out_path), host=self.get_option('remote_addr'))\n \n         if not os.path.isfile(to_bytes(in_path, errors='surrogate_or_strict')):\n             raise AnsibleFileNotFound(\"input path is not a file: %s\" % in_path)\n@@ -138,7 +138,7 @@\n         \"\"\" fetch a file from lxd to local \"\"\"\n         super(Connection, self).fetch_file(in_path, out_path)\n \n-        self._display.vvv(u\"FETCH {0} TO {1}\".format(in_path, out_path), host=self._host)\n+        self._display.vvv(u\"FETCH {0} TO {1}\".format(in_path, out_path), host=self.get_option('remote_addr'))\n \n         local_cmd = [self._lxc_cmd]\n         if self.get_option(\"project\"):\n", "issue": "community.general.lxd connection not working with molecule\n### Summary\r\n\r\nWhen I try to run `molecule create` with the [lxd driver](https://github.com/ansible-community/molecule-lxd), it creates the lxc container correctly, but then gives a warning and then fails to run a command on the container.\r\n```\r\n[WARNING]: The \"ansible_collections.community.general.plugins.connection.lxd\" connection plugin has an improperly configured remote target value, forcing \"inventory_hostname\" templated value instead of the string\r\n```\r\nAfter some debugging, I found that the `remote_addr` value was being set to the literal string 'inventory_hostname' instead of the value of the current host's `inventory_hostname`. I found another connection plugin that had [fixed a similar issue](https://github.com/ansible/ansible/pull/77894).\r\n\r\nApplying this patch to the `plugins/connection/lxd.py` file fixes the problem.\r\n\r\n[fix_lxd_inventory_hostname.patch.txt](https://github.com/ansible-collections/community.general/files/8960273/fix_lxd_inventory_hostname.patch.txt)\r\n\r\n\r\n### Issue Type\r\n\r\nBug Report\r\n\r\n### Component Name\r\n\r\nplugins/connection/lxd.py\r\n\r\n### Ansible Version\r\n\r\n```console (paste below)\r\n$ ansible --version\r\nansible [core 2.13.1]\r\n  config file = /home/anton/ansible-collection-oit-ne-servers/roles/common/ansible.cfg\r\n  configured module search path = ['/home/anton/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']\r\n  ansible python module location = /home/anton/ansible-collection-oit-ne-servers/.venv/lib/python3.10/site-packages/ansible\r\n  ansible collection location = /home/anton/ansible-collection-oit-ne-servers/roles/common/.collections\r\n  executable location = /home/anton/ansible-collection-oit-ne-servers/.venv/bin/ansible\r\n  python version = 3.10.5 (main, Jun 11 2022, 16:53:24) [GCC 9.4.0]\r\n  jinja version = 3.1.2\r\n  libyaml = False\r\n\r\n```\r\n\r\n\r\n### Community.general Version\r\n\r\n```console (paste below)\r\n$ ansible-galaxy collection list community.general\r\nCollection        Version\r\n----------------- -------\r\ncommunity.general 5.2.0 \r\n```\r\n\r\n\r\n### Configuration\r\n\r\n```console (paste below)\r\n$ ansible-config dump --only-changed\r\n\r\n```\r\n\r\n\r\n### OS / Environment\r\n\r\ncat /etc/os-release \r\nNAME=\"Ubuntu\"\r\nVERSION=\"20.04.4 LTS (Focal Fossa)\"\r\nID=ubuntu\r\nID_LIKE=debian\r\nPRETTY_NAME=\"Ubuntu 20.04.4 LTS\"\r\nVERSION_ID=\"20.04\"\r\nHOME_URL=\"https://www.ubuntu.com/\"\r\nSUPPORT_URL=\"https://help.ubuntu.com/\"\r\nBUG_REPORT_URL=\"https://bugs.launchpad.net/ubuntu/\"\r\nPRIVACY_POLICY_URL=\"https://www.ubuntu.com/legal/terms-and-policies/privacy-policy\"\r\nVERSION_CODENAME=focal\r\nUBUNTU_CODENAME=focal\r\n\r\n### Steps to Reproduce\r\n\r\n<!--- Paste example playbooks or commands between quotes below -->\r\n```console\r\n$ mkdir tmp\r\n$ cd tmp\r\n$ python3 -m venv .venv\r\n$ . .venv/bin/activate\r\n$ python3 -m pip install --upgrade pip setuptools wheel\r\n$ python3 -m pip install ansible molecule molecule-lxd\r\n$ molecule init role tmp.common --driver-name lxd\r\n$ cd common\r\n```\r\n\r\nModify `molecule/default/molecule.yml`:\r\n```yaml (paste below)\r\ndependency:\r\n  name: galaxy\r\ndriver:\r\n  name: lxd\r\nplatforms:\r\n  - name: centos-stream-8\r\n    source:\r\n      type: image\r\n      mode: pull\r\n      server: https://images.linuxcontainers.org\r\n      protocol: simplestreams\r\n      alias: centos/8-Stream/amd64\r\n    profiles: [\"default\"]\r\nprovisioner:\r\n  name: ansible\r\nverifier:\r\n  name: ansible\r\n```\r\n\r\n```console\r\n$ molecule create\r\n```\r\n\r\n### Expected Results\r\n\r\nI expected that the lxd container would be properly created and prepared.\r\n\r\n### Actual Results\r\n\r\n```console (paste below)\r\nPLAY [Prepare] *****************************************************************\r\n\r\nTASK [Install basic packages to bare containers] *******************************\r\n[WARNING]: The \"lxd\" connection plugin has an improperly configured remote\r\ntarget value, forcing \"inventory_hostname\" templated value instead of the\r\nstring\r\nfatal: [centos-stream-8]: FAILED! => {\"changed\": true, \"msg\": \"non-zero return code\", \"rc\": 1, \"stderr\": \"Error: Instance not found\\n\", \"stderr_lines\": [\"Error: Instance not found\"], \"stdout\": \"\", \"stdout_lines\": []}\r\n\r\n```\r\n\r\n\r\n### Code of Conduct\r\n\r\n- [X] I agree to follow the Ansible Code of Conduct\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# (c) 2016 Matt Clay <matt@mystile.com>\n# (c) 2017 Ansible Project\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import (absolute_import, division, print_function)\n__metaclass__ = type\n\nDOCUMENTATION = '''\n    author: Matt Clay (@mattclay) <matt@mystile.com>\n    name: lxd\n    short_description: Run tasks in lxc containers via lxc CLI\n    description:\n        - Run commands or put/fetch files to an existing lxc container using lxc CLI\n    options:\n      remote_addr:\n        description:\n            - Container identifier.\n        default: inventory_hostname\n        vars:\n            - name: ansible_host\n            - name: ansible_lxd_host\n      executable:\n        description:\n            - shell to use for execution inside container\n        default: /bin/sh\n        vars:\n            - name: ansible_executable\n            - name: ansible_lxd_executable\n      remote:\n        description:\n            - Name of the LXD remote to use.\n        default: local\n        vars:\n            - name: ansible_lxd_remote\n        version_added: 2.0.0\n      project:\n        description:\n            - Name of the LXD project to use.\n        vars:\n            - name: ansible_lxd_project\n        version_added: 2.0.0\n'''\n\nimport os\nfrom subprocess import Popen, PIPE\n\nfrom ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound\nfrom ansible.module_utils.common.process import get_bin_path\nfrom ansible.module_utils.common.text.converters import to_bytes, to_text\nfrom ansible.plugins.connection import ConnectionBase\n\n\nclass Connection(ConnectionBase):\n    \"\"\" lxd based connections \"\"\"\n\n    transport = 'community.general.lxd'\n    has_pipelining = True\n    default_user = 'root'\n\n    def __init__(self, play_context, new_stdin, *args, **kwargs):\n        super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)\n\n        self._host = self._play_context.remote_addr\n        try:\n            self._lxc_cmd = get_bin_path(\"lxc\")\n        except ValueError:\n            raise AnsibleError(\"lxc command not found in PATH\")\n\n        if self._play_context.remote_user is not None and self._play_context.remote_user != 'root':\n            self._display.warning('lxd does not support remote_user, using container default: root')\n\n    def _connect(self):\n        \"\"\"connect to lxd (nothing to do here) \"\"\"\n        super(Connection, self)._connect()\n\n        if not self._connected:\n            self._display.vvv(u\"ESTABLISH LXD CONNECTION FOR USER: root\", host=self._host)\n            self._connected = True\n\n    def exec_command(self, cmd, in_data=None, sudoable=True):\n        \"\"\" execute a command on the lxd host \"\"\"\n        super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)\n\n        self._display.vvv(u\"EXEC {0}\".format(cmd), host=self._host)\n\n        local_cmd = [self._lxc_cmd]\n        if self.get_option(\"project\"):\n            local_cmd.extend([\"--project\", self.get_option(\"project\")])\n        local_cmd.extend([\n            \"exec\",\n            \"%s:%s\" % (self.get_option(\"remote\"), self.get_option(\"remote_addr\")),\n            \"--\",\n            self.get_option(\"executable\"), \"-c\", cmd\n        ])\n\n        local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]\n        in_data = to_bytes(in_data, errors='surrogate_or_strict', nonstring='passthru')\n\n        process = Popen(local_cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)\n        stdout, stderr = process.communicate(in_data)\n\n        stdout = to_text(stdout)\n        stderr = to_text(stderr)\n\n        if stderr == \"error: Container is not running.\\n\":\n            raise AnsibleConnectionFailure(\"container not running: %s\" % self._host)\n\n        if stderr == \"error: not found\\n\":\n            raise AnsibleConnectionFailure(\"container not found: %s\" % self._host)\n\n        return process.returncode, stdout, stderr\n\n    def put_file(self, in_path, out_path):\n        \"\"\" put a file from local to lxd \"\"\"\n        super(Connection, self).put_file(in_path, out_path)\n\n        self._display.vvv(u\"PUT {0} TO {1}\".format(in_path, out_path), host=self._host)\n\n        if not os.path.isfile(to_bytes(in_path, errors='surrogate_or_strict')):\n            raise AnsibleFileNotFound(\"input path is not a file: %s\" % in_path)\n\n        local_cmd = [self._lxc_cmd]\n        if self.get_option(\"project\"):\n            local_cmd.extend([\"--project\", self.get_option(\"project\")])\n        local_cmd.extend([\n            \"file\", \"push\",\n            in_path,\n            \"%s:%s/%s\" % (self.get_option(\"remote\"), self.get_option(\"remote_addr\"), out_path)\n        ])\n\n        local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]\n\n        process = Popen(local_cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)\n        process.communicate()\n\n    def fetch_file(self, in_path, out_path):\n        \"\"\" fetch a file from lxd to local \"\"\"\n        super(Connection, self).fetch_file(in_path, out_path)\n\n        self._display.vvv(u\"FETCH {0} TO {1}\".format(in_path, out_path), host=self._host)\n\n        local_cmd = [self._lxc_cmd]\n        if self.get_option(\"project\"):\n            local_cmd.extend([\"--project\", self.get_option(\"project\")])\n        local_cmd.extend([\n            \"file\", \"pull\",\n            \"%s:%s/%s\" % (self.get_option(\"remote\"), self.get_option(\"remote_addr\"), in_path),\n            out_path\n        ])\n\n        local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]\n\n        process = Popen(local_cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)\n        process.communicate()\n\n    def close(self):\n        \"\"\" close the connection (nothing to do here) \"\"\"\n        super(Connection, self).close()\n\n        self._connected = False\n", "path": "plugins/connection/lxd.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# (c) 2016 Matt Clay <matt@mystile.com>\n# (c) 2017 Ansible Project\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import (absolute_import, division, print_function)\n__metaclass__ = type\n\nDOCUMENTATION = '''\n    author: Matt Clay (@mattclay) <matt@mystile.com>\n    name: lxd\n    short_description: Run tasks in lxc containers via lxc CLI\n    description:\n        - Run commands or put/fetch files to an existing lxc container using lxc CLI\n    options:\n      remote_addr:\n        description:\n            - Container identifier.\n        default: inventory_hostname\n        vars:\n            - name: inventory_hostname\n            - name: ansible_host\n            - name: ansible_lxd_host\n      executable:\n        description:\n            - shell to use for execution inside container\n        default: /bin/sh\n        vars:\n            - name: ansible_executable\n            - name: ansible_lxd_executable\n      remote:\n        description:\n            - Name of the LXD remote to use.\n        default: local\n        vars:\n            - name: ansible_lxd_remote\n        version_added: 2.0.0\n      project:\n        description:\n            - Name of the LXD project to use.\n        vars:\n            - name: ansible_lxd_project\n        version_added: 2.0.0\n'''\n\nimport os\nfrom subprocess import Popen, PIPE\n\nfrom ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound\nfrom ansible.module_utils.common.process import get_bin_path\nfrom ansible.module_utils.common.text.converters import to_bytes, to_text\nfrom ansible.plugins.connection import ConnectionBase\n\n\nclass Connection(ConnectionBase):\n    \"\"\" lxd based connections \"\"\"\n\n    transport = 'community.general.lxd'\n    has_pipelining = True\n    default_user = 'root'\n\n    def __init__(self, play_context, new_stdin, *args, **kwargs):\n        super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)\n\n        try:\n            self._lxc_cmd = get_bin_path(\"lxc\")\n        except ValueError:\n            raise AnsibleError(\"lxc command not found in PATH\")\n\n        if self._play_context.remote_user is not None and self._play_context.remote_user != 'root':\n            self._display.warning('lxd does not support remote_user, using container default: root')\n\n    def _connect(self):\n        \"\"\"connect to lxd (nothing to do here) \"\"\"\n        super(Connection, self)._connect()\n\n        if not self._connected:\n            self._display.vvv(u\"ESTABLISH LXD CONNECTION FOR USER: root\", host=self.get_option('remote_addr'))\n            self._connected = True\n\n    def exec_command(self, cmd, in_data=None, sudoable=True):\n        \"\"\" execute a command on the lxd host \"\"\"\n        super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)\n\n        self._display.vvv(u\"EXEC {0}\".format(cmd), host=self.get_option('remote_addr'))\n\n        local_cmd = [self._lxc_cmd]\n        if self.get_option(\"project\"):\n            local_cmd.extend([\"--project\", self.get_option(\"project\")])\n        local_cmd.extend([\n            \"exec\",\n            \"%s:%s\" % (self.get_option(\"remote\"), self.get_option(\"remote_addr\")),\n            \"--\",\n            self.get_option(\"executable\"), \"-c\", cmd\n        ])\n\n        local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]\n        in_data = to_bytes(in_data, errors='surrogate_or_strict', nonstring='passthru')\n\n        process = Popen(local_cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)\n        stdout, stderr = process.communicate(in_data)\n\n        stdout = to_text(stdout)\n        stderr = to_text(stderr)\n\n        if stderr == \"error: Container is not running.\\n\":\n            raise AnsibleConnectionFailure(\"container not running: %s\" % self.get_option('remote_addr'))\n\n        if stderr == \"error: not found\\n\":\n            raise AnsibleConnectionFailure(\"container not found: %s\" % self.get_option('remote_addr'))\n\n        return process.returncode, stdout, stderr\n\n    def put_file(self, in_path, out_path):\n        \"\"\" put a file from local to lxd \"\"\"\n        super(Connection, self).put_file(in_path, out_path)\n\n        self._display.vvv(u\"PUT {0} TO {1}\".format(in_path, out_path), host=self.get_option('remote_addr'))\n\n        if not os.path.isfile(to_bytes(in_path, errors='surrogate_or_strict')):\n            raise AnsibleFileNotFound(\"input path is not a file: %s\" % in_path)\n\n        local_cmd = [self._lxc_cmd]\n        if self.get_option(\"project\"):\n            local_cmd.extend([\"--project\", self.get_option(\"project\")])\n        local_cmd.extend([\n            \"file\", \"push\",\n            in_path,\n            \"%s:%s/%s\" % (self.get_option(\"remote\"), self.get_option(\"remote_addr\"), out_path)\n        ])\n\n        local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]\n\n        process = Popen(local_cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)\n        process.communicate()\n\n    def fetch_file(self, in_path, out_path):\n        \"\"\" fetch a file from lxd to local \"\"\"\n        super(Connection, self).fetch_file(in_path, out_path)\n\n        self._display.vvv(u\"FETCH {0} TO {1}\".format(in_path, out_path), host=self.get_option('remote_addr'))\n\n        local_cmd = [self._lxc_cmd]\n        if self.get_option(\"project\"):\n            local_cmd.extend([\"--project\", self.get_option(\"project\")])\n        local_cmd.extend([\n            \"file\", \"pull\",\n            \"%s:%s/%s\" % (self.get_option(\"remote\"), self.get_option(\"remote_addr\"), in_path),\n            out_path\n        ])\n\n        local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]\n\n        process = Popen(local_cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)\n        process.communicate()\n\n    def close(self):\n        \"\"\" close the connection (nothing to do here) \"\"\"\n        super(Connection, self).close()\n\n        self._connected = False\n", "path": "plugins/connection/lxd.py"}]}