ansible-test - More flexible become support.

pull/78088/head
Matt Clay 2 years ago
parent 717f178870
commit 5666c6d6a3

@ -0,0 +1,2 @@
minor_changes:
- ansible-test - Become support for remote instance provisioning is no longer tied to a fixed list of platforms.

@ -1,13 +1,13 @@
freebsd/12.3 python=3.8 python_dir=/usr/local/bin provider=aws arch=x86_64 freebsd/12.3 python=3.8 python_dir=/usr/local/bin become=su provider=aws arch=x86_64
freebsd/13.0 python=3.7,3.8,3.9 python_dir=/usr/local/bin provider=aws arch=x86_64 freebsd/13.0 python=3.7,3.8,3.9 python_dir=/usr/local/bin become=su provider=aws arch=x86_64
freebsd/13.1 python=3.8,3.7,3.9,3.10 python_dir=/usr/local/bin provider=aws arch=x86_64 freebsd/13.1 python=3.8,3.7,3.9,3.10 python_dir=/usr/local/bin become=su provider=aws arch=x86_64
freebsd python_dir=/usr/local/bin provider=aws arch=x86_64 freebsd python_dir=/usr/local/bin become=su provider=aws arch=x86_64
macos/12.0 python=3.10 python_dir=/usr/local/bin provider=parallels arch=x86_64 macos/12.0 python=3.10 python_dir=/usr/local/bin become=sudo provider=parallels arch=x86_64
macos python_dir=/usr/local/bin provider=parallels arch=x86_64 macos python_dir=/usr/local/bin become=sudo provider=parallels arch=x86_64
rhel/7.9 python=2.7 provider=aws arch=x86_64 rhel/7.9 python=2.7 become=sudo provider=aws arch=x86_64
rhel/8.5 python=3.6,3.8,3.9 provider=aws arch=x86_64 rhel/8.5 python=3.6,3.8,3.9 become=sudo provider=aws arch=x86_64
rhel/8.6 python=3.6,3.8,3.9 provider=aws arch=x86_64 rhel/8.6 python=3.6,3.8,3.9 become=sudo provider=aws arch=x86_64
rhel/9.0 python=3.9 provider=aws arch=x86_64 rhel/9.0 python=3.9 become=sudo provider=aws arch=x86_64
rhel provider=aws arch=x86_64 rhel become=sudo provider=aws arch=x86_64
ubuntu/22.04 python=3.10 provider=aws arch=x86_64 ubuntu/22.04 python=3.10 become=sudo provider=aws arch=x86_64
ubuntu provider=aws arch=x86_64 ubuntu become=sudo provider=aws arch=x86_64

@ -5,6 +5,10 @@ import abc
import shlex import shlex
import typing as t import typing as t
from .util import (
get_subclasses,
)
class Become(metaclass=abc.ABCMeta): class Become(metaclass=abc.ABCMeta):
"""Base class for become implementations.""" """Base class for become implementations."""
@ -50,3 +54,6 @@ class Sudo(Become):
become.extend(['sh', '-c', ' '.join(shlex.quote(c) for c in command)]) become.extend(['sh', '-c', ' '.join(shlex.quote(c) for c in command)])
return become return become
SUPPORTED_BECOME_METHODS = {cls.__name__.lower(): cls for cls in get_subclasses(Become)}

@ -18,6 +18,10 @@ from ...host_configs import (
OriginConfig, OriginConfig,
) )
from ...become import (
SUPPORTED_BECOME_METHODS,
)
from ..argparsing.parsers import ( from ..argparsing.parsers import (
AnyParser, AnyParser,
BooleanParser, BooleanParser,
@ -129,6 +133,7 @@ class PosixRemoteKeyValueParser(KeyValueParser):
def get_parsers(self, state): # type: (ParserState) -> t.Dict[str, Parser] def get_parsers(self, state): # type: (ParserState) -> t.Dict[str, Parser]
"""Return a dictionary of key names and value parsers.""" """Return a dictionary of key names and value parsers."""
return dict( return dict(
become=ChoicesParser(list(SUPPORTED_BECOME_METHODS)),
provider=ChoicesParser(REMOTE_PROVIDERS), provider=ChoicesParser(REMOTE_PROVIDERS),
arch=ChoicesParser(REMOTE_ARCHITECTURES), arch=ChoicesParser(REMOTE_ARCHITECTURES),
python=PythonParser(versions=self.versions, allow_venv=False, allow_default=self.allow_default), python=PythonParser(versions=self.versions, allow_venv=False, allow_default=self.allow_default),
@ -141,6 +146,7 @@ class PosixRemoteKeyValueParser(KeyValueParser):
section_name = 'remote options' section_name = 'remote options'
state.sections[f'{"controller" if self.controller else "target"} {section_name} (comma separated):'] = '\n'.join([ state.sections[f'{"controller" if self.controller else "target"} {section_name} (comma separated):'] = '\n'.join([
f' become={ChoicesParser(list(SUPPORTED_BECOME_METHODS)).document(state)}',
f' provider={ChoicesParser(REMOTE_PROVIDERS).document(state)}', f' provider={ChoicesParser(REMOTE_PROVIDERS).document(state)}',
f' arch={ChoicesParser(REMOTE_ARCHITECTURES).document(state)}', f' arch={ChoicesParser(REMOTE_ARCHITECTURES).document(state)}',
f' python={python_parser.document(state)}', f' python={python_parser.document(state)}',

@ -21,6 +21,10 @@ from .data import (
data_context, data_context,
) )
from .become import (
SUPPORTED_BECOME_METHODS,
)
@dataclasses.dataclass(frozen=True) @dataclasses.dataclass(frozen=True)
class CompletionConfig(metaclass=abc.ABCMeta): class CompletionConfig(metaclass=abc.ABCMeta):
@ -166,12 +170,16 @@ class NetworkRemoteCompletionConfig(RemoteCompletionConfig):
@dataclasses.dataclass(frozen=True) @dataclasses.dataclass(frozen=True)
class PosixRemoteCompletionConfig(RemoteCompletionConfig, PythonCompletionConfig): class PosixRemoteCompletionConfig(RemoteCompletionConfig, PythonCompletionConfig):
"""Configuration for remote POSIX platforms.""" """Configuration for remote POSIX platforms."""
become: t.Optional[str] = None
placeholder: bool = False placeholder: bool = False
def __post_init__(self): def __post_init__(self):
if not self.placeholder: if not self.placeholder:
super().__post_init__() super().__post_init__()
if self.become and self.become not in SUPPORTED_BECOME_METHODS:
raise Exception(f'POSIX remote completion entry "{self.name}" setting "become" must be omitted or one of: {", ".join(SUPPORTED_BECOME_METHODS)}')
if not self.supported_pythons: if not self.supported_pythons:
if self.version and not self.placeholder: if self.version and not self.placeholder:
raise Exception(f'POSIX remote completion entry "{self.name}" must provide a "python" setting.') raise Exception(f'POSIX remote completion entry "{self.name}" must provide a "python" setting.')

@ -333,6 +333,8 @@ class DockerConfig(ControllerHostConfig, PosixConfig):
@dataclasses.dataclass @dataclasses.dataclass
class PosixRemoteConfig(RemoteConfig, ControllerHostConfig, PosixConfig): class PosixRemoteConfig(RemoteConfig, ControllerHostConfig, PosixConfig):
"""Configuration for a POSIX remote host.""" """Configuration for a POSIX remote host."""
become: t.Optional[str] = None
def get_defaults(self, context): # type: (HostContext) -> PosixRemoteCompletionConfig def get_defaults(self, context): # type: (HostContext) -> PosixRemoteCompletionConfig
"""Return the default settings.""" """Return the default settings."""
return filter_completion(remote_completion()).get(self.name) or remote_completion().get(self.platform) or PosixRemoteCompletionConfig( return filter_completion(remote_completion()).get(self.name) or remote_completion().get(self.platform) or PosixRemoteCompletionConfig(
@ -350,6 +352,14 @@ class PosixRemoteConfig(RemoteConfig, ControllerHostConfig, PosixConfig):
return [ControllerConfig(python=NativePythonConfig(version=version, path=path)) for version, path in pythons.items()] return [ControllerConfig(python=NativePythonConfig(version=version, path=path)) for version, path in pythons.items()]
def apply_defaults(self, context, defaults): # type: (HostContext, CompletionConfig) -> None
"""Apply default settings."""
assert isinstance(defaults, PosixRemoteCompletionConfig)
super().apply_defaults(context, defaults)
self.become = self.become or defaults.become
@property @property
def have_root(self): # type: () -> bool def have_root(self): # type: () -> bool
"""True if root is available, otherwise False.""" """True if root is available, otherwise False."""

@ -99,7 +99,7 @@ from .connections import (
from .become import ( from .become import (
Become, Become,
Su, SUPPORTED_BECOME_METHODS,
Sudo, Sudo,
) )
@ -573,16 +573,11 @@ class PosixRemoteProfile(ControllerHostProfile[PosixRemoteConfig], RemoteProfile
if settings.user == 'root': if settings.user == 'root':
become = None # type: t.Optional[Become] become = None # type: t.Optional[Become]
elif self.config.platform == 'freebsd': elif self.config.become:
become = Su() become = SUPPORTED_BECOME_METHODS[self.config.become]()
elif self.config.platform == 'macos':
become = Sudo()
elif self.config.platform == 'rhel':
become = Sudo()
elif self.config.platform == 'ubuntu':
become = Sudo()
else: else:
raise NotImplementedError(f'Become support has not been implemented for platform "{self.config.platform}" and user "{settings.user}" is not root.') display.warning(f'Defaulting to "sudo" for platform "{self.config.platform}" become support.', unique=True)
become = Sudo()
return SshConnection(self.args, settings, become) return SshConnection(self.args, settings, become)

Loading…
Cancel
Save