aetherscale

[unmaintained] code for a cloud provider tutorial
Log | Files | Refs | README | LICENSE

commit 8a78602e851415f794bab4545e8e6d65547c67f9
parent 00c33bcbddf89f8ce81a5ea210d7400f50cae02b
Author: Stefan Koch <programming@stefan-koch.name>
Date:   Sat, 19 Dec 2020 11:11:57 +0100

check for binary dependencies before startup

Diffstat:
Aaetherscale/dependencies.py | 37+++++++++++++++++++++++++++++++++++++
Maetherscale/server.py | 16+++++++++++++---
Atests/test_dependencies.py | 26++++++++++++++++++++++++++
3 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/aetherscale/dependencies.py b/aetherscale/dependencies.py @@ -0,0 +1,37 @@ +import shutil +from typing import List + + +BINARY_DEPENDENCIES = { + 'systemctl': + 'systemd is required by aetherscale. For support of other ' + 'service managers a new ServiceManager subclass is required. ' + 'Feel free to open an issue at Github.', + 'guestmount': + 'libguestfs is required by aetherscale. You can install it:\n\n' + ' On Ubuntu: apt install libguestfs-tools\n' + ' On Arch Linux: pacman -S libguestfs', + 'qemu-img': + 'QEMU is required by aetherscale. You can install it:\n\n' + ' On Ubuntu: apt install qemu-utils qemu-kvm\n' + ' On Arch Linux: pacman -S qemu-headless', + 'vde_switch': + 'VDE2 is required by aetherscale. You can install it:\n\n' + ' On Ubuntu: apt install vde2\n' + ' On Arch Linux: pacman -S vde2' +} + + +def find_missing_dependencies(dependency_commands: List[str]) -> List[str]: + return [cmd for cmd in dependency_commands if not shutil.which(cmd)] + + +def build_dependency_help_text(missing_dependencies: List[str]) -> str: + full_help = [] + for dependency in missing_dependencies: + try: + full_help.append(BINARY_DEPENDENCIES[dependency]) + except KeyError: + full_help.append(f'{dependency} is required by aetherscale.') + + return '\n\n'.join(full_help) diff --git a/aetherscale/server.py b/aetherscale/server.py @@ -1,8 +1,18 @@ -from . import __version__ -from .computing import run +import sys + +from aetherscale import __version__ +from aetherscale.computing import run +from aetherscale import dependencies def main(): print(f'Executing aetherscale version {__version__}.') - run() + missing_deps = dependencies.find_missing_dependencies( + dependencies.BINARY_DEPENDENCIES.keys()) + + if len(missing_deps) > 0: + help_text = dependencies.build_dependency_help_text(missing_deps) + print(help_text, file=sys.stderr) + else: + run() diff --git a/tests/test_dependencies.py b/tests/test_dependencies.py @@ -0,0 +1,26 @@ +from aetherscale.dependencies \ + import find_missing_dependencies, build_dependency_help_text + + +def test_existing_binary(): + missing = find_missing_dependencies(['sh']) + assert len(missing) == 0 + + +def test_missing_binary(): + missing = find_missing_dependencies(['9c4f52e32803b906214f6059a8e2850f']) + assert len(missing) == 1 + + +def test_build_help(): + help_text = build_dependency_help_text(['systemctl']) + assert help_text != '' + + +def test_unknown_missing_dependency(): + """if the dependency is not known, it should still be listed with a generic + help text""" + + missing_command = '9c4f52e32803b906214f6059a8e2850f' + help_text = build_dependency_help_text([missing_command]) + assert missing_command in help_text