Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ jobs:
run: ./venv/bin/ceph-devstack -v start
- name: Check Status
run: podman ps -a
- name: Check ssh access to testnode container
run: sleep 10 && podman exec teuthology ssh -oBatchMode=yes -v "cm@$(podman inspect --format '{{ slice .ID 0 12 }}' testnode_0)" whoami
- name: Dump testnode journal
if: failure()
run: podman exec testnode_0 journalctl
- name: Wait
run: ./venv/bin/ceph-devstack wait teuthology
- name: Dump logs
Expand Down
7 changes: 6 additions & 1 deletion ceph_devstack/host.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
import logging
import os
import pathlib
Expand Down Expand Up @@ -44,7 +45,7 @@ async def arun(
cwd: Optional[pathlib.Path] = None,
env: Optional[Dict] = None,
stream_output: bool = False,
):
) -> asyncio.subprocess.Process:
return await self.cmd(
args, cwd=cwd, env=env, stream_output=stream_output
).arun()
Expand Down Expand Up @@ -107,6 +108,10 @@ async def get_sysctl_value(self, name: str) -> int:
out = await proc.stdout.read()
return int(out.decode().strip())

async def apparmor_enabled(self) -> bool:
proc = await host.arun(["aa-enabled", "-q"])
return await proc.wait() == 0


class LocalHost(Host):
pass
Expand Down
20 changes: 19 additions & 1 deletion ceph_devstack/requirements.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import shlex
import sys

from pathlib import Path
Expand Down Expand Up @@ -35,7 +36,7 @@ async def evaluate(self) -> bool:

async def suggest(self):
if hasattr(self, "suggest_msg"):
logger.error(f"{self.suggest_msg}. Try: {' '.join(self.fix_cmd)}")
logger.error(f"{self.suggest_msg}. Try: {shlex.join(self.fix_cmd)}")

async def fix(self) -> bool:
assert self.fix_cmd, "Attempted to fix without a fix command"
Expand Down Expand Up @@ -217,6 +218,19 @@ class FuseOverlayfsPresence(FixableRequirement):
fix_cmd = ["sudo", "dnf", "install", "-y", "fuse-overlayfs"]


class AppArmorProfile(FixableRequirement):
_profile_path = "/etc/apparmor.d/local/unix-chkpwd"
_profile_content = '"capability dac_override,"'
check_cmd = ["test", "-f", _profile_path]
suggest_msg = "Did not find required apparmor profile"
fix_cmd = [
"sudo",
"bash",
"-c",
f"echo -e {_profile_content} > {_profile_path} && systemctl reload apparmor",
]


async def check_requirements():
if not await PodmanPlatform().evaluate():
return False
Expand Down Expand Up @@ -248,6 +262,10 @@ async def check_requirements():
result = result and await SELinuxBoolean("container_manage_cgroup").evaluate()
result = result and await SELinuxBoolean("container_use_devices").evaluate()

# AppArmor
if await host.apparmor_enabled():
result = result and await AppArmorProfile().evaluate()

# podman DNS plugin
if not await PodmanVersion("5.0").evaluate():
result = result and await PodmanDNSPlugin().evaluate()
Expand Down
Loading