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
32 changes: 28 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1340,6 +1340,10 @@ jobs:

has_cmd() { command -v "$1" >/dev/null 2>&1; }

is_ablestack_host() {
[[ "${PRETTY_NAME:-}" == *"ABLESTACK"* ]]
}

resolve_first_cmd() {
local cmd=
for cmd in "$@"; do
Expand All @@ -1352,6 +1356,10 @@ jobs:
}

rpm_pkg_manager_cmd() {
if is_ablestack_host && has_cmd aspm; then
command -v aspm
return 0
fi
resolve_first_cmd dnf aspm || {
echo "[ERROR] Neither dnf nor ABLESTACK aspm was found." >&2
return 127
Expand All @@ -1365,6 +1373,10 @@ jobs:
}

rpm_query_cmd() {
if is_ablestack_host && has_cmd aspkg; then
command -v aspkg
return 0
fi
resolve_first_cmd rpm aspkg || {
echo "[ERROR] Neither rpm nor ABLESTACK aspkg was found." >&2
return 127
Expand Down Expand Up @@ -1644,8 +1656,8 @@ jobs:
run: |
set -e
bash -n release/install-linux.sh
grep -q 'resolve_first_cmd dnf aspm' release/install-linux.sh
grep -q 'resolve_first_cmd rpm aspkg' release/install-linux.sh
grep -q 'is_ablestack_host && has_cmd aspm' release/install-linux.sh
grep -q 'is_ablestack_host && has_cmd aspkg' release/install-linux.sh

- name: Create uninstall-linux.sh
run: |
Expand All @@ -1672,6 +1684,10 @@ jobs:

has_cmd() { command -v "$1" >/dev/null 2>&1; }

is_ablestack_host() {
[[ "${PRETTY_NAME:-}" == *"ABLESTACK"* ]]
}

resolve_first_cmd() {
local cmd=
for cmd in "$@"; do
Expand All @@ -1684,6 +1700,10 @@ jobs:
}

rpm_pkg_manager_cmd() {
if is_ablestack_host && has_cmd aspm; then
command -v aspm
return 0
fi
resolve_first_cmd dnf aspm || {
echo "[ERROR] Neither dnf nor ABLESTACK aspm was found." >&2
return 127
Expand All @@ -1697,6 +1717,10 @@ jobs:
}

rpm_query_cmd() {
if is_ablestack_host && has_cmd aspkg; then
command -v aspkg
return 0
fi
resolve_first_cmd rpm aspkg || {
echo "[ERROR] Neither rpm nor ABLESTACK aspkg was found." >&2
return 127
Expand Down Expand Up @@ -1777,8 +1801,8 @@ jobs:
run: |
set -e
bash -n release/uninstall-linux.sh
grep -q 'resolve_first_cmd dnf aspm' release/uninstall-linux.sh
grep -q 'resolve_first_cmd rpm aspkg' release/uninstall-linux.sh
grep -q 'is_ablestack_host && has_cmd aspm' release/uninstall-linux.sh
grep -q 'is_ablestack_host && has_cmd aspkg' release/uninstall-linux.sh

- name: Generate release notes (changelog)
run: |
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ jobs:
run: |
echo "Running CI build (basic validation)"
make all

- name: ISO package manager selection smoke
run: |
tests/iso_pkg_manager_selection_smoke.sh
19 changes: 19 additions & 0 deletions docs/ablestack_iso_pkg_manager_selection_design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# ABLESTACK ISO package manager selection design

## Background

Newer ABLESTACK hosts may keep `dnf`, `yum`, or `rpm` commands on disk while blocking their direct use. Operators are expected to use `aspm` for package transactions and `aspkg` for RPM queries. The ISO installer already wrapped package operations, but it selected commands only by existence and preferred `dnf` before `aspm`.

That means an ABLESTACK host can print `dnf, yum usage is blocked` before the installer ever reaches the bundled V2K/N2K add-on install steps.

## Policy

- On ABLESTACK hosts, prefer `aspm` for RPM package manager operations when it exists.
- On ABLESTACK hosts, prefer `aspkg` for RPM query operations when it exists.
- On non-ABLESTACK RPM hosts, keep the existing native `dnf` and `rpm` preference.
- Keep the existing `dnf`/`rpm` fallback for ordinary Rocky, RHEL, CentOS, AlmaLinux, and Fedora systems.
- Apply the same command selection policy to both `install-linux.sh` and `uninstall-linux.sh`.

## Validation

The smoke test extracts the generated installer and uninstaller script bodies from the release workflow, then injects fake commands where `dnf` and `rpm` exist but are blocked. It verifies that ABLESTACK `PRETTY_NAME` selects `aspm` and `aspkg`, while a regular Rocky `PRETTY_NAME` still selects `dnf` and `rpm`.
84 changes: 84 additions & 0 deletions tests/iso_pkg_manager_selection_smoke.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
WORKFLOW="${ROOT_DIR}/.github/workflows/build.yml"
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "${TMP_DIR}"' EXIT

extract_generated_script() {
local target="$1"
local output="$2"
awk -v target="${target}" '
index($0, "cat <<'\''EOF'\'' > " target) { capture = 1; next }
capture && $0 == " EOF" { exit }
capture {
sub(/^ /, "")
print
}
' "${WORKFLOW}" > "${output}"
}

extract_function_prefix() {
local script="$1"
local output="$2"
awk '
/^case .*DISTRO.* in/ { exit }
{ print }
' "${script}" > "${output}"
}

write_fake_cmd() {
local path="$1"
local body="$2"
printf '#!/usr/bin/env bash\n%s\n' "${body}" > "${path}"
chmod +x "${path}"
}

assert_selection() {
local prefix="$1"
local pretty_name="$2"
local expected_manager="$3"
local expected_query="$4"

(
# shellcheck disable=SC1090
source "${prefix}" >/dev/null
PRETTY_NAME="${pretty_name}"

manager_cmd="$(rpm_pkg_manager_cmd)"
query_cmd="$(rpm_query_cmd)"

[[ "$(basename "${manager_cmd}")" == "${expected_manager}" ]] || {
echo "expected package manager ${expected_manager}, got ${manager_cmd}" >&2
exit 1
}
[[ "$(basename "${query_cmd}")" == "${expected_query}" ]] || {
echo "expected query command ${expected_query}, got ${query_cmd}" >&2
exit 1
}
)
}

mkdir -p "${TMP_DIR}/bin"
write_fake_cmd "${TMP_DIR}/bin/dnf" 'echo "dnf, yum usage is blocked" >&2; exit 64'
write_fake_cmd "${TMP_DIR}/bin/rpm" 'echo "rpm usage is blocked" >&2; exit 64'
write_fake_cmd "${TMP_DIR}/bin/aspm" 'exit 0'
write_fake_cmd "${TMP_DIR}/bin/aspkg" 'exit 0'

extract_generated_script "release/install-linux.sh" "${TMP_DIR}/install-linux.sh"
extract_generated_script "release/uninstall-linux.sh" "${TMP_DIR}/uninstall-linux.sh"
bash -n "${TMP_DIR}/install-linux.sh"
bash -n "${TMP_DIR}/uninstall-linux.sh"
extract_function_prefix "${TMP_DIR}/install-linux.sh" "${TMP_DIR}/install-prefix.sh"
extract_function_prefix "${TMP_DIR}/uninstall-linux.sh" "${TMP_DIR}/uninstall-prefix.sh"

PATH="${TMP_DIR}/bin:${PATH}"
export PATH

assert_selection "${TMP_DIR}/install-prefix.sh" "ABLESTACK Host 9" aspm aspkg
assert_selection "${TMP_DIR}/uninstall-prefix.sh" "ABLESTACK Host 9" aspm aspkg
assert_selection "${TMP_DIR}/install-prefix.sh" "Rocky Linux 9.6" dnf rpm
assert_selection "${TMP_DIR}/uninstall-prefix.sh" "Rocky Linux 9.6" dnf rpm

echo "[OK] ISO package manager selection smoke test passed"
Loading