Skip to content
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

Merged
merged 1 commit into from
Jul 1, 2021
Merged

Add runtime manager class #8

merged 1 commit into from
Jul 1, 2021

Conversation

ssbarnea
Copy link
Member

@ssbarnea ssbarnea commented Jun 25, 2021

Initial feedback should answer:

  • Is Runtime() class ok or you have a better proposal?
  • Does the README example look at simple a possible to use?
  • Runtime construction accepts two optional arguments
    • project_dir, defaulting to cwd
    • isolated bool, which determine if we should make use of our isolated cache for for installing roles or collections

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.

@ssbarnea ssbarnea added the enhancement New feature or request label Jun 25, 2021
@ssbarnea ssbarnea force-pushed the fix/api branch 3 times, most recently from 7173691 to 9f023fb Compare June 30, 2021 08:06
@ssbarnea ssbarnea changed the title WIP: Propose API Add runtime manager class Jun 30, 2021
@ssbarnea ssbarnea marked this pull request as ready for review June 30, 2021 08:08
@ssbarnea ssbarnea requested a review from webknjaz as a code owner June 30, 2021 08:08
@ssbarnea ssbarnea force-pushed the fix/api branch 3 times, most recently from 5337f24 to 8ae2233 Compare June 30, 2021 15:05
@ssbarnea ssbarnea force-pushed the fix/api branch 6 times, most recently from 5c065f7 to ade04fd Compare July 1, 2021 08:48
Adds a Runtime() class that can be used to interact with a specific
version of Ansible and ease access to various commands.
@ssbarnea ssbarnea merged commit f8d030e into main Jul 1, 2021
@ssbarnea ssbarnea deleted the fix/api branch July 1, 2021 09:00
@@ -0,0 +1,89 @@
"""Ansible runtime environment maanger."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/aa/a/

Copy link
Member Author

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 ;)

Copy link
Member

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"])
Copy link
Member

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.

Copy link
Member Author

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 ...

Copy link
Member

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):
Copy link
Member

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.

Copy link
Member

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

Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

@webknjaz webknjaz Jul 7, 2021

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:
"""."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Member Author

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." ;)

Copy link
Member

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:
Copy link
Member

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:
Copy link
Member

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:
Copy link
Member

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
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

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:
Copy link
Member

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:
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants