-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add runtime manager class #8
Conversation
7173691
to
9f023fb
Compare
5337f24
to
8ae2233
Compare
5c065f7
to
ade04fd
Compare
Adds a Runtime() class that can be used to interact with a specific version of Ansible and ease access to various commands.
@@ -0,0 +1,89 @@ | |||
"""Ansible runtime environment maanger.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/aa/a/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is not a mistake is on purpose! See https://en.wikipedia.org/wiki/Manger ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But the wiki page shows a word with just one "a" :)
# runtime.install_collection("community.general") | ||
|
||
# Execute a command | ||
result = runtime.exec(["ansible-doc", "--list"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't call the method exec()
because it creates a misleading impression that it is related to the syscall that replaces the current process with a new one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest a name, I am aware of its bad naming. I considered Runtime.run()
as it will likely be very similar to subprocess.run, but ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I commented below but it should instead just follow check_call()
style.
self.proc = proc | ||
|
||
|
||
class AnsibleCommandError(RuntimeError): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be useful to have a common lib-defined base class for all the exceptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, this should also inherit subprocess.SubprocessError
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I'm not even sure if it should depend on RuntimeError
because its purpose is to indicate unspecific unexpected things happening at runtime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clearly not SubprocessError because we may endup executing code with something else (containers) but I am open to suggestions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you execute things in containers, you still run subprocesses. It's a good abstraction.
def __init__( | ||
self, message: Optional[str] = None, proc: Optional[Any] = None | ||
) -> None: | ||
""".""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Boilerplate to pass linting, is means "TODO: add meaningful description here." ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but why not fill it in right away?
self.config = AnsibleConfig() | ||
|
||
# pylint: disable=no-self-use | ||
def exec(self, args: Union[str, List[str]]) -> CompletedProcess: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather have a check_call()
style thingy. Plus we need to address the naming concern I raised above.
return self._version | ||
|
||
proc = self.exec(["ansible", "--version"]) | ||
if proc.returncode == 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having if .. != 0: raise
could simplify this block.
assert version == runtime.version | ||
|
||
|
||
def test_runtime_version_fail(mocker: MockerFixture) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I normally advocate for using pytest's builtin monkeypatch
for as long as you don't use things uniquely accessible only via unittest.mock.patch
.
) | ||
runtime = Runtime() | ||
with pytest.raises(RuntimeError) as exc: | ||
_ = runtime.version |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_ =
part isn't actually needed here — you could just test accessing the property and that would work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_
was added to keep the linter happy, lost of ugly things goes towards passing our linters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer noqa/disable comments because they communicate the intent more clearly.
autospec=True, | ||
) | ||
runtime = Runtime() | ||
with pytest.raises(RuntimeError) as exc: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this should've been MissingAnsibleError
and the idiom is to always use match=
arg here.
CompletedProcess = subprocess.CompletedProcess | ||
|
||
|
||
class Runtime: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this may need to implement a CM at some point.
Initial feedback should answer:
Runtime()
class ok or you have a better proposal?While current minimal implementation only calls ansible from command line, it will be possible to use the same interface to run ansible execution environments in the future.