We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Hardcoded location of the chroot executable
On Gentoo, chroot is in /usr/bin and not /usr/sbin as ansible assumes.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lib/ansible/runner/connection_plugins/chroot.py`
Content:
```
1 # Based on local.py (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
2 # (c) 2013, Maykel Moya <mmoya@speedyrails.com>
3 #
4 # This file is part of Ansible
5 #
6 # Ansible is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # Ansible is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
18 
19 import traceback
20 import os
21 import pipes
22 import shutil
23 import subprocess
24 import select
25 import fcntl
26 from ansible import errors
27 from ansible import utils
28 from ansible.callbacks import vvv
29 
30 class Connection(object):
31     ''' Local chroot based connections '''
32 
33     def __init__(self, runner, host, port, *args, **kwargs):
34         self.chroot = host
35 
36         if os.geteuid() != 0:
37             raise errors.AnsibleError("chroot connection requires running as root")
38 
39         # we're running as root on the local system so do some
40         # trivial checks for ensuring 'host' is actually a chroot'able dir
41         if not os.path.isdir(self.chroot):
42             raise errors.AnsibleError("%s is not a directory" % self.chroot)
43 
44         chrootsh = os.path.join(self.chroot, 'bin/sh')
45         if not utils.is_executable(chrootsh):
46             raise errors.AnsibleError("%s does not look like a chrootable dir (/bin/sh missing)" % self.chroot)
47 
48         self.runner = runner
49         self.host = host
50         # port is unused, since this is local
51         self.port = port
52 
53     def connect(self, port=None):
54         ''' connect to the chroot; nothing to do here '''
55 
56         vvv("THIS IS A LOCAL CHROOT DIR", host=self.chroot)
57 
58         return self
59 
60     def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False, executable='/bin/sh'):
61         ''' run a command on the chroot '''
62 
63         # We enter chroot as root so sudo stuff can be ignored
64 
65         chroot_cmd = '/usr/sbin/chroot'
66 
67         if executable:
68             local_cmd = [chroot_cmd, self.chroot, executable, '-c', cmd]
69         else:
70             local_cmd = '%s "%s" %s' % (chroot_cmd, self.chroot, cmd)
71 
72         vvv("EXEC %s" % (local_cmd), host=self.chroot)
73         p = subprocess.Popen(local_cmd, shell=isinstance(local_cmd, basestring),
74                              cwd=self.runner.basedir,
75                              stdin=subprocess.PIPE,
76                              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
77 
78         stdout, stderr = p.communicate()
79         return (p.returncode, '', stdout, stderr)
80 
81     def put_file(self, in_path, out_path):
82         ''' transfer a file from local to chroot '''
83 
84         if not out_path.startswith(os.path.sep):
85             out_path = os.path.join(os.path.sep, out_path)
86         normpath = os.path.normpath(out_path)
87         out_path = os.path.join(self.chroot, normpath[1:])
88 
89         vvv("PUT %s TO %s" % (in_path, out_path), host=self.chroot)
90         if not os.path.exists(in_path):
91             raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path)
92         try:
93             shutil.copyfile(in_path, out_path)
94         except shutil.Error:
95             traceback.print_exc()
96             raise errors.AnsibleError("failed to copy: %s and %s are the same" % (in_path, out_path))
97         except IOError:
98             traceback.print_exc()
99             raise errors.AnsibleError("failed to transfer file to %s" % out_path)
100 
101     def fetch_file(self, in_path, out_path):
102         ''' fetch a file from chroot to local '''
103 
104         if not in_path.startswith(os.path.sep):
105             in_path = os.path.join(os.path.sep, in_path)
106         normpath = os.path.normpath(in_path)
107         in_path = os.path.join(self.chroot, normpath[1:])
108 
109         vvv("FETCH %s TO %s" % (in_path, out_path), host=self.chroot)
110         if not os.path.exists(in_path):
111             raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path)
112         try:
113             shutil.copyfile(in_path, out_path)
114         except shutil.Error:
115             traceback.print_exc()
116             raise errors.AnsibleError("failed to copy: %s and %s are the same" % (in_path, out_path))
117         except IOError:
118             traceback.print_exc()
119             raise errors.AnsibleError("failed to transfer file to %s" % out_path)
120 
121     def close(self):
122         ''' terminate the connection; nothing to do here '''
123         pass
124
```
--- 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/lib/ansible/runner/connection_plugins/chroot.py b/lib/ansible/runner/connection_plugins/chroot.py
--- a/lib/ansible/runner/connection_plugins/chroot.py
+++ b/lib/ansible/runner/connection_plugins/chroot.py
@@ -16,13 +16,11 @@
 # You should have received a copy of the GNU General Public License
 # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
 
+import distutils.spawn
 import traceback
 import os
-import pipes
 import shutil
 import subprocess
-import select
-import fcntl
 from ansible import errors
 from ansible import utils
 from ansible.callbacks import vvv
@@ -45,6 +43,10 @@
         if not utils.is_executable(chrootsh):
             raise errors.AnsibleError("%s does not look like a chrootable dir (/bin/sh missing)" % self.chroot)
 
+        self.chroot_cmd = distutils.spawn.find_executable('chroot')
+        if not self.chroot_cmd:
+            raise errors.AnsibleError("chroot command not found in PATH")
+
         self.runner = runner
         self.host = host
         # port is unused, since this is local
@@ -62,12 +64,10 @@
 
         # We enter chroot as root so sudo stuff can be ignored
 
-        chroot_cmd = '/usr/sbin/chroot'
-
         if executable:
-            local_cmd = [chroot_cmd, self.chroot, executable, '-c', cmd]
+            local_cmd = [self.chroot_cmd, self.chroot, executable, '-c', cmd]
         else:
-            local_cmd = '%s "%s" %s' % (chroot_cmd, self.chroot, cmd)
+            local_cmd = '%s "%s" %s' % (self.chroot_cmd, self.chroot, cmd)
 
         vvv("EXEC %s" % (local_cmd), host=self.chroot)
         p = subprocess.Popen(local_cmd, shell=isinstance(local_cmd, basestring),

{"golden_diff": "diff --git a/lib/ansible/runner/connection_plugins/chroot.py b/lib/ansible/runner/connection_plugins/chroot.py\n--- a/lib/ansible/runner/connection_plugins/chroot.py\n+++ b/lib/ansible/runner/connection_plugins/chroot.py\n@@ -16,13 +16,11 @@\n # You should have received a copy of the GNU General Public License\n # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.\n \n+import distutils.spawn\n import traceback\n import os\n-import pipes\n import shutil\n import subprocess\n-import select\n-import fcntl\n from ansible import errors\n from ansible import utils\n from ansible.callbacks import vvv\n@@ -45,6 +43,10 @@\n         if not utils.is_executable(chrootsh):\n             raise errors.AnsibleError(\"%s does not look like a chrootable dir (/bin/sh missing)\" % self.chroot)\n \n+        self.chroot_cmd = distutils.spawn.find_executable('chroot')\n+        if not self.chroot_cmd:\n+            raise errors.AnsibleError(\"chroot command not found in PATH\")\n+\n         self.runner = runner\n         self.host = host\n         # port is unused, since this is local\n@@ -62,12 +64,10 @@\n \n         # We enter chroot as root so sudo stuff can be ignored\n \n-        chroot_cmd = '/usr/sbin/chroot'\n-\n         if executable:\n-            local_cmd = [chroot_cmd, self.chroot, executable, '-c', cmd]\n+            local_cmd = [self.chroot_cmd, self.chroot, executable, '-c', cmd]\n         else:\n-            local_cmd = '%s \"%s\" %s' % (chroot_cmd, self.chroot, cmd)\n+            local_cmd = '%s \"%s\" %s' % (self.chroot_cmd, self.chroot, cmd)\n \n         vvv(\"EXEC %s\" % (local_cmd), host=self.chroot)\n         p = subprocess.Popen(local_cmd, shell=isinstance(local_cmd, basestring),\n", "issue": "Hardcoded location of the chroot executable\nOn Gentoo, chroot is in /usr/bin and not /usr/sbin as ansible assumes.\n\n", "before_files": [{"content": "# Based on local.py (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>\n# (c) 2013, Maykel Moya <mmoya@speedyrails.com>\n#\n# This file is part of Ansible\n#\n# Ansible is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# Ansible is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.\n\nimport traceback\nimport os\nimport pipes\nimport shutil\nimport subprocess\nimport select\nimport fcntl\nfrom ansible import errors\nfrom ansible import utils\nfrom ansible.callbacks import vvv\n\nclass Connection(object):\n    ''' Local chroot based connections '''\n\n    def __init__(self, runner, host, port, *args, **kwargs):\n        self.chroot = host\n\n        if os.geteuid() != 0:\n            raise errors.AnsibleError(\"chroot connection requires running as root\")\n\n        # we're running as root on the local system so do some\n        # trivial checks for ensuring 'host' is actually a chroot'able dir\n        if not os.path.isdir(self.chroot):\n            raise errors.AnsibleError(\"%s is not a directory\" % self.chroot)\n\n        chrootsh = os.path.join(self.chroot, 'bin/sh')\n        if not utils.is_executable(chrootsh):\n            raise errors.AnsibleError(\"%s does not look like a chrootable dir (/bin/sh missing)\" % self.chroot)\n\n        self.runner = runner\n        self.host = host\n        # port is unused, since this is local\n        self.port = port\n\n    def connect(self, port=None):\n        ''' connect to the chroot; nothing to do here '''\n\n        vvv(\"THIS IS A LOCAL CHROOT DIR\", host=self.chroot)\n\n        return self\n\n    def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False, executable='/bin/sh'):\n        ''' run a command on the chroot '''\n\n        # We enter chroot as root so sudo stuff can be ignored\n\n        chroot_cmd = '/usr/sbin/chroot'\n\n        if executable:\n            local_cmd = [chroot_cmd, self.chroot, executable, '-c', cmd]\n        else:\n            local_cmd = '%s \"%s\" %s' % (chroot_cmd, self.chroot, cmd)\n\n        vvv(\"EXEC %s\" % (local_cmd), host=self.chroot)\n        p = subprocess.Popen(local_cmd, shell=isinstance(local_cmd, basestring),\n                             cwd=self.runner.basedir,\n                             stdin=subprocess.PIPE,\n                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\n        stdout, stderr = p.communicate()\n        return (p.returncode, '', stdout, stderr)\n\n    def put_file(self, in_path, out_path):\n        ''' transfer a file from local to chroot '''\n\n        if not out_path.startswith(os.path.sep):\n            out_path = os.path.join(os.path.sep, out_path)\n        normpath = os.path.normpath(out_path)\n        out_path = os.path.join(self.chroot, normpath[1:])\n\n        vvv(\"PUT %s TO %s\" % (in_path, out_path), host=self.chroot)\n        if not os.path.exists(in_path):\n            raise errors.AnsibleFileNotFound(\"file or module does not exist: %s\" % in_path)\n        try:\n            shutil.copyfile(in_path, out_path)\n        except shutil.Error:\n            traceback.print_exc()\n            raise errors.AnsibleError(\"failed to copy: %s and %s are the same\" % (in_path, out_path))\n        except IOError:\n            traceback.print_exc()\n            raise errors.AnsibleError(\"failed to transfer file to %s\" % out_path)\n\n    def fetch_file(self, in_path, out_path):\n        ''' fetch a file from chroot to local '''\n\n        if not in_path.startswith(os.path.sep):\n            in_path = os.path.join(os.path.sep, in_path)\n        normpath = os.path.normpath(in_path)\n        in_path = os.path.join(self.chroot, normpath[1:])\n\n        vvv(\"FETCH %s TO %s\" % (in_path, out_path), host=self.chroot)\n        if not os.path.exists(in_path):\n            raise errors.AnsibleFileNotFound(\"file or module does not exist: %s\" % in_path)\n        try:\n            shutil.copyfile(in_path, out_path)\n        except shutil.Error:\n            traceback.print_exc()\n            raise errors.AnsibleError(\"failed to copy: %s and %s are the same\" % (in_path, out_path))\n        except IOError:\n            traceback.print_exc()\n            raise errors.AnsibleError(\"failed to transfer file to %s\" % out_path)\n\n    def close(self):\n        ''' terminate the connection; nothing to do here '''\n        pass\n", "path": "lib/ansible/runner/connection_plugins/chroot.py"}], "after_files": [{"content": "# Based on local.py (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>\n# (c) 2013, Maykel Moya <mmoya@speedyrails.com>\n#\n# This file is part of Ansible\n#\n# Ansible is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# Ansible is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.\n\nimport distutils.spawn\nimport traceback\nimport os\nimport shutil\nimport subprocess\nfrom ansible import errors\nfrom ansible import utils\nfrom ansible.callbacks import vvv\n\nclass Connection(object):\n    ''' Local chroot based connections '''\n\n    def __init__(self, runner, host, port, *args, **kwargs):\n        self.chroot = host\n\n        if os.geteuid() != 0:\n            raise errors.AnsibleError(\"chroot connection requires running as root\")\n\n        # we're running as root on the local system so do some\n        # trivial checks for ensuring 'host' is actually a chroot'able dir\n        if not os.path.isdir(self.chroot):\n            raise errors.AnsibleError(\"%s is not a directory\" % self.chroot)\n\n        chrootsh = os.path.join(self.chroot, 'bin/sh')\n        if not utils.is_executable(chrootsh):\n            raise errors.AnsibleError(\"%s does not look like a chrootable dir (/bin/sh missing)\" % self.chroot)\n\n        self.chroot_cmd = distutils.spawn.find_executable('chroot')\n        if not self.chroot_cmd:\n            raise errors.AnsibleError(\"chroot command not found in PATH\")\n\n        self.runner = runner\n        self.host = host\n        # port is unused, since this is local\n        self.port = port\n\n    def connect(self, port=None):\n        ''' connect to the chroot; nothing to do here '''\n\n        vvv(\"THIS IS A LOCAL CHROOT DIR\", host=self.chroot)\n\n        return self\n\n    def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False, executable='/bin/sh'):\n        ''' run a command on the chroot '''\n\n        # We enter chroot as root so sudo stuff can be ignored\n\n        if executable:\n            local_cmd = [self.chroot_cmd, self.chroot, executable, '-c', cmd]\n        else:\n            local_cmd = '%s \"%s\" %s' % (self.chroot_cmd, self.chroot, cmd)\n\n        vvv(\"EXEC %s\" % (local_cmd), host=self.chroot)\n        p = subprocess.Popen(local_cmd, shell=isinstance(local_cmd, basestring),\n                             cwd=self.runner.basedir,\n                             stdin=subprocess.PIPE,\n                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\n        stdout, stderr = p.communicate()\n        return (p.returncode, '', stdout, stderr)\n\n    def put_file(self, in_path, out_path):\n        ''' transfer a file from local to chroot '''\n\n        if not out_path.startswith(os.path.sep):\n            out_path = os.path.join(os.path.sep, out_path)\n        normpath = os.path.normpath(out_path)\n        out_path = os.path.join(self.chroot, normpath[1:])\n\n        vvv(\"PUT %s TO %s\" % (in_path, out_path), host=self.chroot)\n        if not os.path.exists(in_path):\n            raise errors.AnsibleFileNotFound(\"file or module does not exist: %s\" % in_path)\n        try:\n            shutil.copyfile(in_path, out_path)\n        except shutil.Error:\n            traceback.print_exc()\n            raise errors.AnsibleError(\"failed to copy: %s and %s are the same\" % (in_path, out_path))\n        except IOError:\n            traceback.print_exc()\n            raise errors.AnsibleError(\"failed to transfer file to %s\" % out_path)\n\n    def fetch_file(self, in_path, out_path):\n        ''' fetch a file from chroot to local '''\n\n        if not in_path.startswith(os.path.sep):\n            in_path = os.path.join(os.path.sep, in_path)\n        normpath = os.path.normpath(in_path)\n        in_path = os.path.join(self.chroot, normpath[1:])\n\n        vvv(\"FETCH %s TO %s\" % (in_path, out_path), host=self.chroot)\n        if not os.path.exists(in_path):\n            raise errors.AnsibleFileNotFound(\"file or module does not exist: %s\" % in_path)\n        try:\n            shutil.copyfile(in_path, out_path)\n        except shutil.Error:\n            traceback.print_exc()\n            raise errors.AnsibleError(\"failed to copy: %s and %s are the same\" % (in_path, out_path))\n        except IOError:\n            traceback.print_exc()\n            raise errors.AnsibleError(\"failed to transfer file to %s\" % out_path)\n\n    def close(self):\n        ''' terminate the connection; nothing to do here '''\n        pass\n", "path": "lib/ansible/runner/connection_plugins/chroot.py"}]}