We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
3.6.0 login to podman fails '/usr/bin/env /bin/podman' No such file
<!--- Verify first that your issue is not already reported on GitHub -->
<!--- Do not report bugs before reproducing them with the code of the main branch! -->
<!--- Please also check https://molecule.readthedocs.io/en/latest/faq.html --->
<!--- Please use https://groups.google.com/forum/#!forum/molecule-users for usage questions -->

# Issue Type

- Bug report

# Molecule and Ansible details

```
ansible --version
```
```
ansible [core 2.11.4] 
  config file = /home/indermue/src/ansible-mysql/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/ansible
  ansible collection location = /home/indermue/src/ansible-mysql/collections:/root/python-venv/ansible-4.2.0/lib/python3.8/site-packages:/var/lib/awx/projects/ansible-mysql-manual/collections:/opt/my-tower-venv/ansible-4.2.0/lib/python3.8/site-packages
  executable location = /root/python-venv/ansible-4.4.0/bin/ansible
  python version = 3.8.8 (default, Aug 11 2021, 06:52:42) [GCC 8.5.0 20210514 (Red Hat 8.5.0-3)]
  jinja version = 3.0.1
  libyaml = True
```

```
molecule --version
```
```
molecule 3.6.0 using python 3.8
    ansible:2.11.4
    delegated:3.6.0 from molecule
    podman:1.1.0 from molecule_podman requiring collections: containers.podman>=1.7.0 ansible.posix>=1.3.0
```

Molecule installation method (one of):

- pip

Ansible installation method (one of):

- pip

# Desired Behavior

`molecule login -h node -s scenario` should open bash from within the podman container.

# Actual Behaviour

Molecule fails to execute with the following error:

```
INFO     Inventory /home/indermue/src/ansible-mysql/molecule/mariadb/inventory/static.yml linked to /root/.cache/molecule/ansible-mysql/mariadb/inventory/hosts
INFO     Inventory /home/indermue/src/ansible-mysql/molecule/mariadb/inventory/group_vars linked to /root/.cache/molecule/ansible-mysql/mariadb/inventory/group_vars
INFO     Inventory /home/indermue/src/ansible-mysql/molecule/mariadb/inventory/host_vars linked to /root/.cache/molecule/ansible-mysql/mariadb/inventory/host_vars
INFO     Running mariadb > login 
Traceback (most recent call last):
  File "/root/python-venv/ansible-4.4.0/bin/molecule", line 8, in <module>
    sys.exit(main())
  File "/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/click/core.py", line 1137, in __call__
    return self.main(*args, **kwargs)
  File "/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/click/core.py", line 1062, in main
    rv = self.invoke(ctx)
  File "/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/click/core.py", line 1668, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/click/core.py", line 763, in invoke
    return __callback(*args, **kwargs)
  File "/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/click/decorators.py", line 26, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/molecule/command/login.py", line 166, in login
    base.execute_subcommand(scenario.config, subcommand)
  File "/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/molecule/command/base.py", line 149, in execute_subcommand
    return command(config).execute()
  File "/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/molecule/logger.py", line 188, in wrapper
    rt = func(*args, **kwargs)
  File "/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/molecule/command/login.py", line 101, in execute
    self._get_login(hostname)
  File "/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/molecule/command/login.py", line 146, in _get_login
    app.runtime.exec(cmd)
  File "/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/ansible_compat/runtime.py", line 138, in exec
    result = run_func(
  File "/usr/lib64/python3.8/subprocess.py", line 493, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib64/python3.8/subprocess.py", line 858, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib64/python3.8/subprocess.py", line 1706, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: '/usr/bin/env /bin/podman exec -e COLUMNS=254 -e LINES=60 -e TERM=bash -e TERM=xterm -ti mariadb_104 bash'  
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/molecule/command/login.py`
Content:
```
1 #  Copyright (c) 2015-2018 Cisco Systems, Inc.
2 #
3 #  Permission is hereby granted, free of charge, to any person obtaining a copy
4 #  of this software and associated documentation files (the "Software"), to
5 #  deal in the Software without restriction, including without limitation the
6 #  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 #  sell copies of the Software, and to permit persons to whom the Software is
8 #  furnished to do so, subject to the following conditions:
9 #
10 #  The above copyright notice and this permission notice shall be included in
11 #  all copies or substantial portions of the Software.
12 #
13 #  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 #  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 #  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 #  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 #  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 #  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19 #  DEALINGS IN THE SOFTWARE.
20 """Login Command Module."""
21 
22 import logging
23 import os
24 
25 import click
26 
27 from molecule import scenarios, util
28 from molecule.app import app
29 from molecule.command import base
30 
31 LOG = logging.getLogger(__name__)
32 
33 
34 class Login(base.Base):
35     """
36     Login Command Class.
37 
38     .. program:: molecule login
39 
40     .. option:: molecule login
41 
42         Target the default scenario.
43 
44     .. program:: molecule login --scenario-name foo
45 
46     .. option:: molecule login --scenario-name foo
47 
48         Targeting a specific scenario.
49 
50     .. program:: molecule login --host hostname
51 
52     .. option:: molecule login --host hostname
53 
54         Targeting a specific running host.
55 
56     .. program:: molecule login --host hostname --scenario-name foo
57 
58     .. option:: molecule login --host hostname --scenario-name foo
59 
60         Targeting a specific running host and scenario.
61 
62     .. program:: molecule --debug login
63 
64     .. option:: molecule --debug login
65 
66         Executing with `debug`.
67 
68     .. program:: molecule --base-config base.yml login
69 
70     .. option:: molecule --base-config base.yml login
71 
72         Executing with a `base-config`.
73 
74     .. program:: molecule --env-file foo.yml login
75 
76     .. option:: molecule --env-file foo.yml login
77 
78         Load an env file to read variables from when rendering
79         molecule.yml.
80     """
81 
82     def __init__(self, c):
83         """Construct Login."""
84         super(Login, self).__init__(c)
85         self._pt = None
86 
87     def execute(self):
88         """
89         Execute the actions necessary to perform a `molecule login` and \
90         returns None.
91 
92         :return: None
93         """
94         c = self._config
95         if (not c.state.created) and c.driver.managed:
96             msg = "Instances not created.  Please create instances first."
97             util.sysexit_with_message(msg)
98 
99         hosts = [d["name"] for d in self._config.platforms.instances]
100         hostname = self._get_hostname(hosts)
101         self._get_login(hostname)
102 
103     def _get_hostname(self, hosts):
104         hostname = self._config.command_args.get("host")
105         host_list = "\n".join(sorted(hosts))
106         if hostname is None:
107             if len(hosts) == 1:
108                 hostname = hosts[0]
109             else:
110                 msg = (
111                     f"There are {len(hosts)} running hosts. Please specify "
112                     "which with --host.\n\n"
113                     f"Available hosts:\n{host_list}"
114                 )
115                 util.sysexit_with_message(msg)
116         match = [x for x in hosts if x.startswith(hostname)]
117         if len(match) == 0:
118             msg = (
119                 f"There are no hosts that match '{hostname}'.  You "
120                 "can only login to valid hosts."
121             )
122             util.sysexit_with_message(msg)
123         elif len(match) != 1:
124             # If there are multiple matches, but one of them is an exact string
125             # match, assume this is the one they're looking for and use it.
126             if hostname in match:
127                 match = [hostname]
128             else:
129                 msg = (
130                     f"There are {len(match)} hosts that match '{hostname}'. You "
131                     "can only login to one at a time.\n\n"
132                     f"Available hosts:\n{host_list}"
133                 )
134                 util.sysexit_with_message(msg)
135 
136         return match[0]
137 
138     def _get_login(self, hostname):  # pragma: no cover
139         lines, columns = os.popen("stty size", "r").read().split()
140         login_options = self._config.driver.login_options(hostname)
141         login_options["columns"] = columns
142         login_options["lines"] = lines
143         login_cmd = self._config.driver.login_cmd_template.format(**login_options)
144 
145         cmd = f"/usr/bin/env {login_cmd}"
146         app.runtime.exec(cmd)
147 
148 
149 @base.click_command_ex()
150 @click.pass_context
151 @click.option("--host", "-h", help="Host to access.")
152 @click.option(
153     "--scenario-name",
154     "-s",
155     default=base.MOLECULE_DEFAULT_SCENARIO_NAME,
156     help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
157 )
158 def login(ctx, host, scenario_name):  # pragma: no cover
159     """Log in to one instance."""
160     args = ctx.obj.get("args")
161     subcommand = base._get_subcommand(__name__)
162     command_args = {"subcommand": subcommand, "host": host}
163 
164     s = scenarios.Scenarios(base.get_configs(args, command_args), scenario_name)
165     for scenario in s.all:
166         base.execute_subcommand(scenario.config, subcommand)
167
```
--- 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/src/molecule/command/login.py b/src/molecule/command/login.py
--- a/src/molecule/command/login.py
+++ b/src/molecule/command/login.py
@@ -21,11 +21,12 @@
 
 import logging
 import os
+import shlex
+import subprocess
 
 import click
 
 from molecule import scenarios, util
-from molecule.app import app
 from molecule.command import base
 
 LOG = logging.getLogger(__name__)
@@ -142,8 +143,8 @@
         login_options["lines"] = lines
         login_cmd = self._config.driver.login_cmd_template.format(**login_options)
 
-        cmd = f"/usr/bin/env {login_cmd}"
-        app.runtime.exec(cmd)
+        cmd = shlex.split(f"/usr/bin/env {login_cmd}")
+        subprocess.run(cmd)
 
 
 @base.click_command_ex()

{"golden_diff": "diff --git a/src/molecule/command/login.py b/src/molecule/command/login.py\n--- a/src/molecule/command/login.py\n+++ b/src/molecule/command/login.py\n@@ -21,11 +21,12 @@\n \n import logging\n import os\n+import shlex\n+import subprocess\n \n import click\n \n from molecule import scenarios, util\n-from molecule.app import app\n from molecule.command import base\n \n LOG = logging.getLogger(__name__)\n@@ -142,8 +143,8 @@\n         login_options[\"lines\"] = lines\n         login_cmd = self._config.driver.login_cmd_template.format(**login_options)\n \n-        cmd = f\"/usr/bin/env {login_cmd}\"\n-        app.runtime.exec(cmd)\n+        cmd = shlex.split(f\"/usr/bin/env {login_cmd}\")\n+        subprocess.run(cmd)\n \n \n @base.click_command_ex()\n", "issue": "3.6.0 login to podman fails '/usr/bin/env /bin/podman' No such file\n<!--- Verify first that your issue is not already reported on GitHub -->\r\n<!--- Do not report bugs before reproducing them with the code of the main branch! -->\r\n<!--- Please also check https://molecule.readthedocs.io/en/latest/faq.html --->\r\n<!--- Please use https://groups.google.com/forum/#!forum/molecule-users for usage questions -->\r\n\r\n# Issue Type\r\n\r\n- Bug report\r\n\r\n# Molecule and Ansible details\r\n\r\n```\r\nansible --version\r\n```\r\n```\r\nansible [core 2.11.4] \r\n  config file = /home/indermue/src/ansible-mysql/ansible.cfg\r\n  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']\r\n  ansible python module location = /root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/ansible\r\n  ansible collection location = /home/indermue/src/ansible-mysql/collections:/root/python-venv/ansible-4.2.0/lib/python3.8/site-packages:/var/lib/awx/projects/ansible-mysql-manual/collections:/opt/my-tower-venv/ansible-4.2.0/lib/python3.8/site-packages\r\n  executable location = /root/python-venv/ansible-4.4.0/bin/ansible\r\n  python version = 3.8.8 (default, Aug 11 2021, 06:52:42) [GCC 8.5.0 20210514 (Red Hat 8.5.0-3)]\r\n  jinja version = 3.0.1\r\n  libyaml = True\r\n```\r\n\r\n```\r\nmolecule --version\r\n```\r\n```\r\nmolecule 3.6.0 using python 3.8\r\n    ansible:2.11.4\r\n    delegated:3.6.0 from molecule\r\n    podman:1.1.0 from molecule_podman requiring collections: containers.podman>=1.7.0 ansible.posix>=1.3.0\r\n```\r\n\r\nMolecule installation method (one of):\r\n\r\n- pip\r\n\r\nAnsible installation method (one of):\r\n\r\n- pip\r\n\r\n# Desired Behavior\r\n\r\n`molecule login -h node -s scenario` should open bash from within the podman container.\r\n\r\n# Actual Behaviour\r\n\r\nMolecule fails to execute with the following error:\r\n\r\n```\r\nINFO     Inventory /home/indermue/src/ansible-mysql/molecule/mariadb/inventory/static.yml linked to /root/.cache/molecule/ansible-mysql/mariadb/inventory/hosts\r\nINFO     Inventory /home/indermue/src/ansible-mysql/molecule/mariadb/inventory/group_vars linked to /root/.cache/molecule/ansible-mysql/mariadb/inventory/group_vars\r\nINFO     Inventory /home/indermue/src/ansible-mysql/molecule/mariadb/inventory/host_vars linked to /root/.cache/molecule/ansible-mysql/mariadb/inventory/host_vars\r\nINFO     Running mariadb > login \r\nTraceback (most recent call last):\r\n  File \"/root/python-venv/ansible-4.4.0/bin/molecule\", line 8, in <module>\r\n    sys.exit(main())\r\n  File \"/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/click/core.py\", line 1137, in __call__\r\n    return self.main(*args, **kwargs)\r\n  File \"/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/click/core.py\", line 1062, in main\r\n    rv = self.invoke(ctx)\r\n  File \"/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/click/core.py\", line 1668, in invoke\r\n    return _process_result(sub_ctx.command.invoke(sub_ctx))\r\n  File \"/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/click/core.py\", line 1404, in invoke\r\n    return ctx.invoke(self.callback, **ctx.params)\r\n  File \"/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/click/core.py\", line 763, in invoke\r\n    return __callback(*args, **kwargs)\r\n  File \"/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/click/decorators.py\", line 26, in new_func\r\n    return f(get_current_context(), *args, **kwargs)\r\n  File \"/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/molecule/command/login.py\", line 166, in login\r\n    base.execute_subcommand(scenario.config, subcommand)\r\n  File \"/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/molecule/command/base.py\", line 149, in execute_subcommand\r\n    return command(config).execute()\r\n  File \"/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/molecule/logger.py\", line 188, in wrapper\r\n    rt = func(*args, **kwargs)\r\n  File \"/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/molecule/command/login.py\", line 101, in execute\r\n    self._get_login(hostname)\r\n  File \"/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/molecule/command/login.py\", line 146, in _get_login\r\n    app.runtime.exec(cmd)\r\n  File \"/root/python-venv/ansible-4.4.0/lib/python3.8/site-packages/ansible_compat/runtime.py\", line 138, in exec\r\n    result = run_func(\r\n  File \"/usr/lib64/python3.8/subprocess.py\", line 493, in run\r\n    with Popen(*popenargs, **kwargs) as process:\r\n  File \"/usr/lib64/python3.8/subprocess.py\", line 858, in __init__\r\n    self._execute_child(args, executable, preexec_fn, close_fds,\r\n  File \"/usr/lib64/python3.8/subprocess.py\", line 1706, in _execute_child\r\n    raise child_exception_type(errno_num, err_msg, err_filename)\r\nFileNotFoundError: [Errno 2] No such file or directory: '/usr/bin/env /bin/podman exec -e COLUMNS=254 -e LINES=60 -e TERM=bash -e TERM=xterm -ti mariadb_104 bash'  \r\n```\r\n\n", "before_files": [{"content": "#  Copyright (c) 2015-2018 Cisco Systems, Inc.\n#\n#  Permission is hereby granted, free of charge, to any person obtaining a copy\n#  of this software and associated documentation files (the \"Software\"), to\n#  deal in the Software without restriction, including without limitation the\n#  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n#  sell copies of the Software, and to permit persons to whom the Software is\n#  furnished to do so, subject to the following conditions:\n#\n#  The above copyright notice and this permission notice shall be included in\n#  all copies or substantial portions of the Software.\n#\n#  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n#  DEALINGS IN THE SOFTWARE.\n\"\"\"Login Command Module.\"\"\"\n\nimport logging\nimport os\n\nimport click\n\nfrom molecule import scenarios, util\nfrom molecule.app import app\nfrom molecule.command import base\n\nLOG = logging.getLogger(__name__)\n\n\nclass Login(base.Base):\n    \"\"\"\n    Login Command Class.\n\n    .. program:: molecule login\n\n    .. option:: molecule login\n\n        Target the default scenario.\n\n    .. program:: molecule login --scenario-name foo\n\n    .. option:: molecule login --scenario-name foo\n\n        Targeting a specific scenario.\n\n    .. program:: molecule login --host hostname\n\n    .. option:: molecule login --host hostname\n\n        Targeting a specific running host.\n\n    .. program:: molecule login --host hostname --scenario-name foo\n\n    .. option:: molecule login --host hostname --scenario-name foo\n\n        Targeting a specific running host and scenario.\n\n    .. program:: molecule --debug login\n\n    .. option:: molecule --debug login\n\n        Executing with `debug`.\n\n    .. program:: molecule --base-config base.yml login\n\n    .. option:: molecule --base-config base.yml login\n\n        Executing with a `base-config`.\n\n    .. program:: molecule --env-file foo.yml login\n\n    .. option:: molecule --env-file foo.yml login\n\n        Load an env file to read variables from when rendering\n        molecule.yml.\n    \"\"\"\n\n    def __init__(self, c):\n        \"\"\"Construct Login.\"\"\"\n        super(Login, self).__init__(c)\n        self._pt = None\n\n    def execute(self):\n        \"\"\"\n        Execute the actions necessary to perform a `molecule login` and \\\n        returns None.\n\n        :return: None\n        \"\"\"\n        c = self._config\n        if (not c.state.created) and c.driver.managed:\n            msg = \"Instances not created.  Please create instances first.\"\n            util.sysexit_with_message(msg)\n\n        hosts = [d[\"name\"] for d in self._config.platforms.instances]\n        hostname = self._get_hostname(hosts)\n        self._get_login(hostname)\n\n    def _get_hostname(self, hosts):\n        hostname = self._config.command_args.get(\"host\")\n        host_list = \"\\n\".join(sorted(hosts))\n        if hostname is None:\n            if len(hosts) == 1:\n                hostname = hosts[0]\n            else:\n                msg = (\n                    f\"There are {len(hosts)} running hosts. Please specify \"\n                    \"which with --host.\\n\\n\"\n                    f\"Available hosts:\\n{host_list}\"\n                )\n                util.sysexit_with_message(msg)\n        match = [x for x in hosts if x.startswith(hostname)]\n        if len(match) == 0:\n            msg = (\n                f\"There are no hosts that match '{hostname}'.  You \"\n                \"can only login to valid hosts.\"\n            )\n            util.sysexit_with_message(msg)\n        elif len(match) != 1:\n            # If there are multiple matches, but one of them is an exact string\n            # match, assume this is the one they're looking for and use it.\n            if hostname in match:\n                match = [hostname]\n            else:\n                msg = (\n                    f\"There are {len(match)} hosts that match '{hostname}'. You \"\n                    \"can only login to one at a time.\\n\\n\"\n                    f\"Available hosts:\\n{host_list}\"\n                )\n                util.sysexit_with_message(msg)\n\n        return match[0]\n\n    def _get_login(self, hostname):  # pragma: no cover\n        lines, columns = os.popen(\"stty size\", \"r\").read().split()\n        login_options = self._config.driver.login_options(hostname)\n        login_options[\"columns\"] = columns\n        login_options[\"lines\"] = lines\n        login_cmd = self._config.driver.login_cmd_template.format(**login_options)\n\n        cmd = f\"/usr/bin/env {login_cmd}\"\n        app.runtime.exec(cmd)\n\n\n@base.click_command_ex()\n@click.pass_context\n@click.option(\"--host\", \"-h\", help=\"Host to access.\")\n@click.option(\n    \"--scenario-name\",\n    \"-s\",\n    default=base.MOLECULE_DEFAULT_SCENARIO_NAME,\n    help=f\"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})\",\n)\ndef login(ctx, host, scenario_name):  # pragma: no cover\n    \"\"\"Log in to one instance.\"\"\"\n    args = ctx.obj.get(\"args\")\n    subcommand = base._get_subcommand(__name__)\n    command_args = {\"subcommand\": subcommand, \"host\": host}\n\n    s = scenarios.Scenarios(base.get_configs(args, command_args), scenario_name)\n    for scenario in s.all:\n        base.execute_subcommand(scenario.config, subcommand)\n", "path": "src/molecule/command/login.py"}], "after_files": [{"content": "#  Copyright (c) 2015-2018 Cisco Systems, Inc.\n#\n#  Permission is hereby granted, free of charge, to any person obtaining a copy\n#  of this software and associated documentation files (the \"Software\"), to\n#  deal in the Software without restriction, including without limitation the\n#  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n#  sell copies of the Software, and to permit persons to whom the Software is\n#  furnished to do so, subject to the following conditions:\n#\n#  The above copyright notice and this permission notice shall be included in\n#  all copies or substantial portions of the Software.\n#\n#  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n#  DEALINGS IN THE SOFTWARE.\n\"\"\"Login Command Module.\"\"\"\n\nimport logging\nimport os\nimport shlex\nimport subprocess\n\nimport click\n\nfrom molecule import scenarios, util\nfrom molecule.command import base\n\nLOG = logging.getLogger(__name__)\n\n\nclass Login(base.Base):\n    \"\"\"\n    Login Command Class.\n\n    .. program:: molecule login\n\n    .. option:: molecule login\n\n        Target the default scenario.\n\n    .. program:: molecule login --scenario-name foo\n\n    .. option:: molecule login --scenario-name foo\n\n        Targeting a specific scenario.\n\n    .. program:: molecule login --host hostname\n\n    .. option:: molecule login --host hostname\n\n        Targeting a specific running host.\n\n    .. program:: molecule login --host hostname --scenario-name foo\n\n    .. option:: molecule login --host hostname --scenario-name foo\n\n        Targeting a specific running host and scenario.\n\n    .. program:: molecule --debug login\n\n    .. option:: molecule --debug login\n\n        Executing with `debug`.\n\n    .. program:: molecule --base-config base.yml login\n\n    .. option:: molecule --base-config base.yml login\n\n        Executing with a `base-config`.\n\n    .. program:: molecule --env-file foo.yml login\n\n    .. option:: molecule --env-file foo.yml login\n\n        Load an env file to read variables from when rendering\n        molecule.yml.\n    \"\"\"\n\n    def __init__(self, c):\n        \"\"\"Construct Login.\"\"\"\n        super(Login, self).__init__(c)\n        self._pt = None\n\n    def execute(self):\n        \"\"\"\n        Execute the actions necessary to perform a `molecule login` and \\\n        returns None.\n\n        :return: None\n        \"\"\"\n        c = self._config\n        if (not c.state.created) and c.driver.managed:\n            msg = \"Instances not created.  Please create instances first.\"\n            util.sysexit_with_message(msg)\n\n        hosts = [d[\"name\"] for d in self._config.platforms.instances]\n        hostname = self._get_hostname(hosts)\n        self._get_login(hostname)\n\n    def _get_hostname(self, hosts):\n        hostname = self._config.command_args.get(\"host\")\n        host_list = \"\\n\".join(sorted(hosts))\n        if hostname is None:\n            if len(hosts) == 1:\n                hostname = hosts[0]\n            else:\n                msg = (\n                    f\"There are {len(hosts)} running hosts. Please specify \"\n                    \"which with --host.\\n\\n\"\n                    f\"Available hosts:\\n{host_list}\"\n                )\n                util.sysexit_with_message(msg)\n        match = [x for x in hosts if x.startswith(hostname)]\n        if len(match) == 0:\n            msg = (\n                f\"There are no hosts that match '{hostname}'.  You \"\n                \"can only login to valid hosts.\"\n            )\n            util.sysexit_with_message(msg)\n        elif len(match) != 1:\n            # If there are multiple matches, but one of them is an exact string\n            # match, assume this is the one they're looking for and use it.\n            if hostname in match:\n                match = [hostname]\n            else:\n                msg = (\n                    f\"There are {len(match)} hosts that match '{hostname}'. You \"\n                    \"can only login to one at a time.\\n\\n\"\n                    f\"Available hosts:\\n{host_list}\"\n                )\n                util.sysexit_with_message(msg)\n\n        return match[0]\n\n    def _get_login(self, hostname):  # pragma: no cover\n        lines, columns = os.popen(\"stty size\", \"r\").read().split()\n        login_options = self._config.driver.login_options(hostname)\n        login_options[\"columns\"] = columns\n        login_options[\"lines\"] = lines\n        login_cmd = self._config.driver.login_cmd_template.format(**login_options)\n\n        cmd = shlex.split(f\"/usr/bin/env {login_cmd}\")\n        subprocess.run(cmd)\n\n\n@base.click_command_ex()\n@click.pass_context\n@click.option(\"--host\", \"-h\", help=\"Host to access.\")\n@click.option(\n    \"--scenario-name\",\n    \"-s\",\n    default=base.MOLECULE_DEFAULT_SCENARIO_NAME,\n    help=f\"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})\",\n)\ndef login(ctx, host, scenario_name):  # pragma: no cover\n    \"\"\"Log in to one instance.\"\"\"\n    args = ctx.obj.get(\"args\")\n    subcommand = base._get_subcommand(__name__)\n    command_args = {\"subcommand\": subcommand, \"host\": host}\n\n    s = scenarios.Scenarios(base.get_configs(args, command_args), scenario_name)\n    for scenario in s.all:\n        base.execute_subcommand(scenario.config, subcommand)\n", "path": "src/molecule/command/login.py"}]}