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
43 changes: 29 additions & 14 deletions test/functional/tests/misc/test_deb_packaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@
built_sets = {}

main_package = "open-cas-linux"
modules_package = "open-cas-linux-modules"
modules_package = "open-cas-linux-dkms"
# DKMS registers the sources under the project name, not the package name
dkms_module = main_package
# What the DKMS package was called, and registered in DKMS as, up to 26.03
legacy_modules_package = "open-cas-linux-modules"
cas_services = ["open-cas.service", "open-cas-shutdown.service"]

# A version that is newer than whatever the sources are at. CAS majors follow
Expand Down Expand Up @@ -182,7 +186,7 @@ def dkms_status():

def dkms_installed_kernels(version: str):
"""Kernels DKMS reports the given version of the CAS modules installed for."""
output = TestRun.executor.run(f"dkms status -m {modules_package} -v {version} 2>/dev/null")
output = TestRun.executor.run(f"dkms status -m {dkms_module} -v {version} 2>/dev/null")
return sorted(
match.group(1)
for match in re.finditer(r"^[^,]+,\s*([^,]+),[^:]*:\s*installed", output.stdout, re.M)
Expand Down Expand Up @@ -243,13 +247,13 @@ def check_modules_for_all_kernels(version: str):

other_versions = [
line for line in dkms_status().splitlines()
if line.startswith(f"{modules_package}/") and f"/{version}," not in line
if line.startswith(f"{dkms_module}/") and f"/{version}," not in line
]
if other_versions:
TestRun.fail(f"Other CAS versions are still registered in DKMS:\n{other_versions}")

stale_sources = TestRun.executor.run(
f"ls -d /usr/src/{modules_package}-* | grep -v -- '-{version}$'"
f"ls -d /usr/src/{dkms_module}-* | grep -v -- '-{version}$'"
).stdout.strip()
if stale_sources:
TestRun.fail(f"Sources of other CAS versions are left behind:\n{stale_sources}")
Expand All @@ -271,11 +275,11 @@ def check_nothing_left_behind(purged: bool):
if leftover_modules:
TestRun.fail(f"CAS modules left on disk:\n{leftover_modules}")

if f"{modules_package}/" in dkms_status():
if f"{dkms_module}/" in dkms_status():
TestRun.fail(f"CAS modules still registered in DKMS:\n{dkms_status()}")

leftover_paths = TestRun.executor.run(
f"ls -d /usr/src/{modules_package}-* /var/lib/dkms/{modules_package} "
f"ls -d /usr/src/{dkms_module}-* /var/lib/dkms/{dkms_module} "
f"/usr/lib/opencas /var/lib/opencas 2>/dev/null"
).stdout.strip()
if leftover_paths:
Expand Down Expand Up @@ -314,12 +318,14 @@ def purge_cas():
f"dpkg-query --show --showformat='${{Package}}\\n' '{main_package}*' 2>/dev/null | "
f"xargs --no-run-if-empty dpkg --purge --force-depends --force-remove-reinstreq"
)
TestRun.executor.run(
f"dkms status -m {modules_package} 2>/dev/null | cut -d, -f1 | cut -d: -f1 | sort -u | "
f"while IFS=/ read -r m v; do [ -n \"$v\" ] && dkms remove -m \"$m\" -v \"$v\" --all; done"
)
remove(f"/var/lib/dkms/{modules_package}", recursive=True, force=True, ignore_errors=True)
TestRun.executor.run(f"rm -rf /usr/src/{modules_package}-* /usr/lib/opencas /var/lib/opencas")
for module in (dkms_module, legacy_modules_package):
TestRun.executor.run(
f"dkms status -m {module} 2>/dev/null | cut -d, -f1 | cut -d: -f1 | sort -u | "
f"while IFS=/ read -r m v; do [ -n \"$v\" ] && dkms remove -m \"$m\" -v \"$v\" --all; done"
)
remove(f"/var/lib/dkms/{module}", recursive=True, force=True, ignore_errors=True)
# the glob covers the sources of both module names
TestRun.executor.run(f"rm -rf /usr/src/{dkms_module}-* /usr/lib/opencas /var/lib/opencas")
TestRun.executor.run(
r"find /lib/modules \( -name 'cas_*.ko*' -o -path '*block/opencas*' \) -delete"
)
Expand Down Expand Up @@ -413,6 +419,15 @@ def test_deb_packaging_build():
f"Modules package does not depend on dkms: {package_field(modules, 'Depends')}"
)

# the package the DKMS sources were shipped in before has to be taken
# out, or its copy of the modules would stay registered in DKMS
for field in ["Conflicts", "Replaces"]:
if legacy_modules_package not in package_field(modules, field):
TestRun.fail(
f"Modules package should list {legacy_modules_package} in {field}: "
f"{package_field(modules, field) or 'none'}"
)

with TestRun.step("Check the tools package contents"):
tools_files = package_files(tools)
for expected in ["/usr/sbin/casadm", "/usr/sbin/casctl", "/etc/opencas/opencas.conf"]:
Expand All @@ -423,7 +438,7 @@ def test_deb_packaging_build():

with TestRun.step("Check the modules package contents"):
modules_files = package_files(modules)
sources_dir = f"/usr/src/{modules_package}-{version}"
sources_dir = f"/usr/src/{dkms_module}-{version}"

outside = [f for f in modules_files
if f.startswith("/usr/src/") and f != "/usr/src/"
Expand Down Expand Up @@ -769,7 +784,7 @@ def test_deb_packaging_dkms_builds_for_new_kernel():
with TestRun.step(f"Remove the modules of {kernel} from DKMS"):
TestRun.executor.run("rmmod cas_cache; rmmod cas_bd")
TestRun.executor.run_expect_success(
f"dkms remove -m {modules_package} -v {version} -k {kernel}"
f"dkms remove -m {dkms_module} -v {version} -k {kernel}"
)
if kernel in dkms_installed_kernels(version) or module_version_on_disk(kernel):
TestRun.fail(f"Modules for {kernel} are still installed:\n{dkms_status()}")
Expand Down
22 changes: 12 additions & 10 deletions test/functional/tests/misc/test_rpm_packaging_modes.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
packaging_inputs = ["version", "Makefile", "tools/pckgen.sh", "tools/pckgen.d/rpm/CAS_NAME.spec"]

main_package = "open-cas-linux"
dkms_modules_package = "open-cas-linux-modules"
dkms_modules_package = "open-cas-linux-dkms"
prebuilt_modules_package_glob = "open-cas-linux-modules_k*"
# DKMS registers the sources under the project name, not the package name
dkms_module = main_package

# A version that is newer than whatever the sources are at. CAS majors follow
# the release month (03, 06, 09, 12), so 13 stays ahead of any release of the
Expand Down Expand Up @@ -152,18 +154,18 @@ def packages_of(variant: str, kind: str = "all"):
packages = [p for p in build_variant(variant) if "debug" not in os.path.basename(p)]

if kind == "modules":
return [p for p in packages if "-modules" in os.path.basename(p)]
return [p for p in packages if modules_package_re.match(os.path.basename(p))]
if kind == "main":
return [p for p in packages if "-modules" not in os.path.basename(p)]
return [p for p in packages if not modules_package_re.match(os.path.basename(p))]
return packages


# The prebuilt modules package is named after the kernel it was built for, so
# its name starts with the DKMS package's name - anchor on what follows to tell
# the three packages apart instead of matching substrings.
# All three package names start with the tools package's name - anchor on
# what follows to tell them apart instead of matching substrings.
tools_package_re = re.compile(rf"^{main_package}-\d")
dkms_modules_re = re.compile(rf"^{dkms_modules_package}-\d")
prebuilt_modules_re = re.compile(rf"^{dkms_modules_package}_k")
prebuilt_modules_re = re.compile(rf"^{prebuilt_modules_package_glob[:-1]}")
modules_package_re = re.compile(rf"{dkms_modules_re.pattern}|{prebuilt_modules_re.pattern}")


def installed_cas_packages():
Expand Down Expand Up @@ -251,8 +253,8 @@ def purge_cas():
"dkms status 2>/dev/null | cut -d, -f1 | tr -d ' ' | while IFS=/ read -r m v; do "
"[ -n \"$m\" ] && dkms remove -m \"$m\" -v \"$v\" --all; done"
)
remove(f"/var/lib/dkms/{dkms_modules_package}", recursive=True, force=True, ignore_errors=True)
TestRun.executor.run(f"rm -rf /usr/src/{dkms_modules_package}-*")
remove(f"/var/lib/dkms/{dkms_module}", recursive=True, force=True, ignore_errors=True)
TestRun.executor.run(f"rm -rf /usr/src/{dkms_module}-*")
TestRun.executor.run(
r"find /lib/modules \( -name 'cas_*.ko*' -o -path '*block/opencas*' \) -delete"
)
Expand Down Expand Up @@ -682,7 +684,7 @@ def test_rpm_packaging_migration_keeps_modules_when_dkms_build_fails():
).stdout.strip()

removed = TestRun.executor.run(
f'dkms status -m {dkms_modules_package} -v {version} -k "$(uname -r)" '
f'dkms status -m {dkms_module} -v {version} -k "$(uname -r)" '
f'2>/dev/null | grep -q ": installed"'
).exit_code == 0

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PACKAGE_NAME="<CAS_NAME>-modules"
PACKAGE_NAME="<CAS_NAME>"
PACKAGE_VERSION="#MODULE_VERSION#"
BUILT_MODULE_NAME[0]="cas_cache"
BUILT_MODULE_LOCATION[0]="modules/cas_cache/"
Expand Down
11 changes: 11 additions & 0 deletions tools/pckgen.d/deb/debian/CAS_NAME-dkms.install
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
./.metadata/* usr/src/<CAS_NAME>-<CAS_VERSION>/.metadata/
./modules/* usr/src/<CAS_NAME>-<CAS_VERSION>/modules/
./ocf/* usr/src/<CAS_NAME>-<CAS_VERSION>/ocf/
./utils/* usr/src/<CAS_NAME>-<CAS_VERSION>/utils/
./tools/cas_version_gen.sh usr/src/<CAS_NAME>-<CAS_VERSION>/tools/
./tools/helpers.mk usr/src/<CAS_NAME>-<CAS_VERSION>/tools/
./configure.d/* usr/src/<CAS_NAME>-<CAS_VERSION>/configure.d/
./configure usr/src/<CAS_NAME>-<CAS_VERSION>/
./Makefile usr/src/<CAS_NAME>-<CAS_VERSION>/
./LICENSE.md usr/src/<CAS_NAME>-<CAS_VERSION>/
./version usr/src/<CAS_NAME>-<CAS_VERSION>/
11 changes: 0 additions & 11 deletions tools/pckgen.d/deb/debian/CAS_NAME-modules.install

This file was deleted.

9 changes: 7 additions & 2 deletions tools/pckgen.d/deb/debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Vcs-Git: <CAS_GIT>
Package: <CAS_NAME>
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, python3, python3-yaml,
<CAS_NAME>-modules (= <CAS_VERSION>-1)
<CAS_NAME>-dkms (= <CAS_VERSION>-1)
Description: Open Cache Acceleration Software
Open Cache Acceleration Software (Open CAS) is an open source project
encompassing block caching software libraries, adapters, tools and more.
Expand All @@ -19,9 +19,14 @@ Description: Open Cache Acceleration Software
This package contains tools and utilities for managing CAS and monitor
running cache instances (no kernel modules).

Package: <CAS_NAME>-modules
Package: <CAS_NAME>-dkms
Architecture: all
Depends: ${misc:Depends}, dkms
# Releases up to 26.03 shipped the same DKMS modules as <CAS_NAME>-modules.
# Left installed next to this package it would keep its own copy of the
# modules registered in DKMS, so it has to go rather than just be upgraded.
Conflicts: <CAS_NAME>-modules
Replaces: <CAS_NAME>-modules
Description: Open Cache Acceleration Software kernel modules (DKMS)
Open Cache Acceleration Software (Open CAS) is an open source project
encompassing block caching software libraries, adapters, tools and more.
Expand Down
30 changes: 15 additions & 15 deletions tools/pckgen.d/rpm/CAS_NAME.spec
Original file line number Diff line number Diff line change
Expand Up @@ -91,21 +91,21 @@ Provides: <CAS_NAME>-modules-%{version}
# swap) and not something the solver does on its own during an upgrade. rpm
# applies this in both directions, so naming the DKMS package here is enough -
# the prebuilt package cannot be named, its name carries the kernel version.
Conflicts: <CAS_NAME>-modules
Conflicts: <CAS_NAME>-dkms
%description modules_%{kver_filename}
Open Cache Acceleration Software (Open CAS) is an open source project
encompassing block caching software libraries, adapters, tools and more.
The main goal of this cache acceleration software is to accelerate a
backend block device(s) by utilizing a higher performance device(s).
This package contains only CAS kernel modules.
%else
%package modules
%package dkms
Summary: Open Cache Acceleration Software kernel modules (DKMS source)
Group: System
BuildArch: noarch
Requires: dkms
Provides: <CAS_NAME>-modules-%{version}
%description modules
%description dkms
Open Cache Acceleration Software (Open CAS) is an open source project
encompassing block caching software libraries, adapters, tools and more.
The main goal of this cache acceleration software is to accelerate a
Expand Down Expand Up @@ -157,7 +157,7 @@ rm -rf modules/.tmp_versions 2>/dev/null || :
(cd tools/; ./cas_version_gen.sh)

# Install DKMS source tree.
DKMS_TREE=%{name}-modules-%{version}
DKMS_TREE=%{name}-%{version}
DKMS_ROOT="$RPM_BUILD_ROOT/usr/src/$DKMS_TREE"
install -d -m 755 "$DKMS_ROOT" "$DKMS_ROOT/.metadata" "$DKMS_ROOT/tools"
cp -a .metadata/* "$DKMS_ROOT/.metadata/" 2>/dev/null || :
Expand All @@ -177,7 +177,7 @@ cp -a configure Makefile LICENSE.md version "$DKMS_ROOT/"
# probes the running kernel and generates a header for the wrong kernel API,
# which 'make' then refuses to build against.
cat > "$DKMS_ROOT/dkms.conf" <<'EOF'
PACKAGE_NAME="<CAS_NAME>-modules"
PACKAGE_NAME="<CAS_NAME>"
PACKAGE_VERSION="<CAS_VERSION>"
BUILT_MODULE_NAME[0]="cas_cache"
BUILT_MODULE_LOCATION[0]="modules/cas_cache/"
Expand Down Expand Up @@ -254,7 +254,7 @@ if [ $1 -eq 0 ]; then
depmod
fi
%else
%posttrans modules
%posttrans dkms
# In %posttrans rather than %post: when this replaces the prebuilt package in
# one transaction, that package is erased between the two, and dkms refuses to
# overwrite a module already installed at the same version - so in %post its
Expand All @@ -263,15 +263,15 @@ fi
# --rpm_safe_upgrade keeps the add+remove pair safe across RPM upgrades
# (dkms(8); also on %preun remove). || : — dkms add returns 3 on re-add
# (reinstall), not a real failure.
dkms add -m %{name}-modules -v %{version} --rpm_safe_upgrade || :
dkms add -m %{name} -v %{version} --rpm_safe_upgrade || :
# Build for the running kernel. No || : — fail visibly if kernel-devel is
# missing (dkms returns 0 for "already installed", so reinstalls still work).
dkms install -m %{name}-modules -v %{version} -k "$(uname -r)" || exit 1
dkms install -m %{name} -v %{version} -k "$(uname -r)" || exit 1
# Best-effort build for other installed kernels (skip those without
# kernel-devel) so a fallback kernel isn't left without modules.
for kver in $(ls /lib/modules 2>/dev/null | grep -vxF "$(uname -r)"); do
[ -d "/lib/modules/$kver/build" ] || continue
dkms install -m %{name}-modules -v %{version} -k "$kver" || :
dkms install -m %{name} -v %{version} -k "$kver" || :
done

# kmod->dkms upgrade orphans the old open-cas-linux-modules_k<kernelver>
Expand All @@ -288,7 +288,7 @@ done
if [ -n "$(rpm -qa "open-cas-linux-modules_k*" 2>/dev/null)" ]; then
( setsid sh -c '
while pgrep -x dnf >/dev/null 2>&1 || pgrep -x zypper >/dev/null 2>&1 || pgrep -x yum >/dev/null 2>&1; do sleep 3; done
dkms status -m %{name}-modules -v %{version} -k "$(uname -r)" 2>/dev/null | grep -q ": installed" || exit 0
dkms status -m %{name} -v %{version} -k "$(uname -r)" 2>/dev/null | grep -q ": installed" || exit 0
rpm -e --nodeps --noscripts $(rpm -qa "open-cas-linux-modules_k*") >/dev/null 2>&1 || :
# --noscripts skipped the old %postun (weak-modules --remove-modules),
# so clean up after it: drop its dangling weak-updates/block/opencas
Expand All @@ -302,11 +302,11 @@ if [ -n "$(rpm -qa "open-cas-linux-modules_k*" 2>/dev/null)" ]; then
' </dev/null >/dev/null 2>&1 ) &
fi

%preun modules
%preun dkms
# Drop dkms's archived old-kmod .ko (original_module) before `dkms remove`
# so it doesn't restore them as orphans (the old kmod package is gone).
rm -rf /var/lib/dkms/%{name}-modules/original_module 2>/dev/null || :
dkms remove -m %{name}-modules -v %{version} --all --rpm_safe_upgrade || :
rm -rf /var/lib/dkms/%{name}/original_module 2>/dev/null || :
dkms remove -m %{name} -v %{version} --all --rpm_safe_upgrade || :
# dkms weak-links the built modules into kABI-compatible kernels it did not
# build for (/lib/modules/<kver>/weak-updates/), and `dkms remove` drops the
# built modules while leaving those symlinks behind. Dangling ones break
Expand Down Expand Up @@ -356,9 +356,9 @@ done
%license LICENSE.md
/lib/modules/%{kver}
%else
%files modules
%files dkms
%defattr(-, root, root, 755)
/usr/src/%{name}-modules-%{version}/
/usr/src/%{name}-%{version}/
%endif


Expand Down
Loading