mirror of https://github.com/ansible/ansible.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.3 KiB
Python
91 lines
2.3 KiB
Python
"""Open a shell prompt inside an ansible-test environment."""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import typing as t
|
|
|
|
from ...util import (
|
|
ApplicationError,
|
|
display,
|
|
)
|
|
|
|
from ...config import (
|
|
ShellConfig,
|
|
)
|
|
|
|
from ...executor import (
|
|
Delegate,
|
|
)
|
|
|
|
from ...connections import (
|
|
Connection,
|
|
LocalConnection,
|
|
SshConnection,
|
|
)
|
|
|
|
from ...host_profiles import (
|
|
ControllerProfile,
|
|
PosixProfile,
|
|
SshTargetHostProfile,
|
|
)
|
|
|
|
from ...provisioning import (
|
|
prepare_profiles,
|
|
)
|
|
|
|
from ...host_configs import (
|
|
ControllerConfig,
|
|
OriginConfig,
|
|
)
|
|
|
|
|
|
def command_shell(args): # type: (ShellConfig) -> None
|
|
"""Entry point for the `shell` command."""
|
|
if args.raw and isinstance(args.targets[0], ControllerConfig):
|
|
raise ApplicationError('The --raw option has no effect on the controller.')
|
|
|
|
host_state = prepare_profiles(args, skip_setup=args.raw) # shell
|
|
|
|
if args.delegate:
|
|
raise Delegate(host_state=host_state)
|
|
|
|
if args.raw and not isinstance(args.controller, OriginConfig):
|
|
display.warning('The --raw option will only be applied to the target.')
|
|
|
|
target_profile = t.cast(SshTargetHostProfile, host_state.target_profiles[0])
|
|
|
|
if isinstance(target_profile, ControllerProfile):
|
|
# run the shell locally unless a target was requested
|
|
con = LocalConnection(args) # type: Connection
|
|
else:
|
|
# a target was requested, connect to it over SSH
|
|
con = target_profile.get_controller_target_connections()[0]
|
|
|
|
if isinstance(con, SshConnection) and args.raw:
|
|
cmd = [] # type: t.List[str]
|
|
elif isinstance(target_profile, PosixProfile):
|
|
cmd = []
|
|
|
|
if args.raw:
|
|
shell = 'sh' # shell required for non-ssh connection
|
|
else:
|
|
shell = 'bash'
|
|
|
|
python = target_profile.python # make sure the python interpreter has been initialized before opening a shell
|
|
display.info(f'Target Python {python.version} is at: {python.path}')
|
|
|
|
optional_vars = (
|
|
'TERM', # keep backspace working
|
|
)
|
|
|
|
env = {name: os.environ[name] for name in optional_vars if name in os.environ}
|
|
|
|
if env:
|
|
cmd = ['/usr/bin/env'] + [f'{name}={value}' for name, value in env.items()]
|
|
|
|
cmd += [shell, '-i']
|
|
else:
|
|
cmd = []
|
|
|
|
con.run(cmd)
|