diff --git a/ceph_devstack/resources/ceph/__init__.py b/ceph_devstack/resources/ceph/__init__.py index b7b4cde..95a8754 100644 --- a/ceph_devstack/resources/ceph/__init__.py +++ b/ceph_devstack/resources/ceph/__init__.py @@ -6,7 +6,7 @@ from collections import OrderedDict from subprocess import CalledProcessError -from ceph_devstack import config, logger, PROJECT_ROOT +from ceph_devstack import config, logger from ceph_devstack.host import host from ceph_devstack.resources.misc import Secret, Network from ceph_devstack.resources.ceph.containers import ( @@ -18,6 +18,12 @@ Teuthology, Archive, ) +from ceph_devstack.resources.ceph.requirements import ( + HasSudo, + LoopControlDeviceExists, + LoopControlDeviceWriteable, + SELinuxModule, +) class SSHKeyPair(Secret): @@ -105,57 +111,15 @@ async def get_testnode_count(self) -> int: async def check_requirements(self): result = True - if has_sudo := host.run(["sudo", "true"]).returncode == 0: - has_sudo = True - else: - has_sudo = False - result = False - logger.error("sudo access is required") - - loop_control = "/dev/loop-control" - if not host.path_exists(loop_control): - result = False - logger.error(f"{loop_control} does not exist!") - elif host.run(["test", "-w", loop_control]).wait() != 0: - result = False - group = ( - host.run(["stat", "--printf", "%G", loop_control]) - .communicate()[0] - .decode() - ) - user = host.run(["whoami"]).communicate()[0].strip().decode() - if host.type == "local": - logger.error( - f"Cannot write to {loop_control}. " - f"Try: sudo usermod -a -G {group} {user}" - ) - logger.warning( - "Note that group modifications require a logout to take effect." - ) - else: - logger.error( - f"Cannot write to {loop_control}. " - f"Try: sudo chgrp {user} {loop_control}" - ) + result = has_sudo = await HasSudo().evaluate() + result = result and await LoopControlDeviceExists().evaluate() + result = result and await LoopControlDeviceWriteable().evaluate() # Check for SELinux being enabled and Enforcing; then check for the # presence of our module. If necessary, inform the user and instruct # them how to build and install. if has_sudo and await host.selinux_enforcing(): - proc = await host.arun(["sudo", "semodule", "-l"]) - assert proc.stdout is not None - await proc.wait() - out = (await proc.stdout.read()).decode() - if "ceph_devstack" not in out.split("\n"): - result = False - logger.error( - "SELinux is in Enforcing mode. To run nested rootless podman " - "containers, it is necessary to install ceph-devstack's SELinux " - "module. Try: (sudo dnf install policycoreutils-devel " - f"selinux-policy-devel && cd {PROJECT_ROOT} && make -f " - "/usr/share/selinux/devel/Makefile ceph_devstack.pp && sudo " - "semodule -i ceph_devstack.pp)" - ) + result = result and await SELinuxModule().evaluate() for name, obj in config["containers"].items(): if (repo := obj.get("repo")) and not host.path_exists(repo):