Skip to content

Commit 1c6579d

Browse files
ci: support testing from brew builds and compose repositories
Port brew-build and compose-repository install support from fido-device-onboard/go-fdo-server#239 into the shared test/{ci,rpm,bootc}/utils.sh, so test/rpm and test/bootc can install go-fdo-client/go-fdo-server from a brew build (CLIENT_RPM_URL/SERVER_RPM_URL) or a compose snapshot (COMPOSE_BASE_URL/COMPOSE_STREAMS), on top of the existing COPR/Packit/local-build paths. Also carries over the upstream follow-up fixes: parse_brew_url() sets its output vars directly to survive subshell calls, trailing slashes are stripped from COMPOSE_BASE_URL, and test/bootc waits for firewalld's D-Bus interface before starting the libvirt network (firewalld >= 2.4.1 no longer blocks on it at startup). parse_brew_url() is added to test/ci/utils.sh since both test/rpm/utils.sh and test/bootc/utils.sh source down to it; it isn't used by ci/utils.sh's own git-source-based install functions. No behavior change for PACKIT_COPR_RPMS-driven or local-build runs. Ports: fido-device-onboard/go-fdo-server#239 Assisted-by: Claude (claude-sonnet-5) Signed-off-by: Mario Cattamo <mcattamo@redhat.com>
1 parent 434b1ba commit 1c6579d

3 files changed

Lines changed: 237 additions & 22 deletions

File tree

test/bootc/utils.sh

Lines changed: 121 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,101 @@ case "${ID}-${VERSION_ID}" in
3131
base_image_url="quay.io/centos-bootc/centos-bootc:stream${VERSION_ID}"
3232
boot_args="uefi,firmware.feature0.name=secure-boot,firmware.feature0.enabled=no"
3333
;;
34+
rhel-10*)
35+
os_variant="rhel10-unknown"
36+
base_image_url="${BOOTC_BASE_IMAGE:-registry.redhat.io/rhel10/rhel-bootc:${VERSION_ID}}"
37+
boot_args="uefi,firmware.feature0.name=secure-boot,firmware.feature0.enabled=no"
38+
;;
3439
*)
3540
log_error "Unsupported distro: ${ID}-${VERSION_ID}"
3641
exit 1
3742
;;
3843
esac
3944

4045
build_bootc_container() {
41-
tee Containerfile >/dev/null <<EOF
46+
# For any RHEL host, generate a repo file pointing at the nightly compose so
47+
# that the container image can reach RHEL packages. The file is generated at
48+
# runtime (rather than kept as a static template) so it works for any RHEL
49+
# minor version (10.2, 10.3, …) without code changes.
50+
local rhel_repo_file=""
51+
if [[ "${ID}" == "rhel" ]] && [ -n "${DOWNLOAD_NODE:-}" ]; then
52+
local major_ver="${VERSION_ID%%.*}" # e.g. "10" from "10.2"
53+
rhel_repo_file="files/rhel-${VERSION_ID}.repo"
54+
mkdir -p files
55+
cat > "${rhel_repo_file}" << EOF
56+
[RHEL-${VERSION_ID}-NIGHTLY-BaseOS]
57+
name=baseos
58+
baseurl=http://${DOWNLOAD_NODE}/rhel-${major_ver}/nightly/RHEL-${major_ver}/latest-RHEL-${VERSION_ID}/compose/BaseOS/\$basearch/os
59+
enabled=1
60+
# Nightly compose builds are not GPG-signed; gpgcheck=0 is intentional.
61+
gpgcheck=0
62+
sslverify=0
63+
[RHEL-${VERSION_ID}-NIGHTLY-AppStream]
64+
name=appstream
65+
baseurl=http://${DOWNLOAD_NODE}/rhel-${major_ver}/nightly/RHEL-${major_ver}/latest-RHEL-${VERSION_ID}/compose/AppStream/\$basearch/os/
66+
enabled=1
67+
# Nightly compose builds are not GPG-signed; gpgcheck=0 is intentional.
68+
gpgcheck=0
69+
sslverify=0
70+
EOF
71+
fi
72+
73+
if [ -n "${CLIENT_RPM_URL:-}" ]; then
74+
# Install go-fdo-client from a specific brew build base path.
75+
# CLIENT_RPM_URL should point to the version/release directory of the package in brew.
76+
parse_brew_url "${CLIENT_RPM_URL}"
77+
tee Containerfile >/dev/null <<EOF
78+
FROM ${base_image_url}
79+
# --nogpgcheck and sslverify=false are intentional: internal brew servers
80+
# use self-signed certificates and builds may not be GPG-signed.
81+
RUN dnf install -y --nogpgcheck --setopt=sslverify=false \
82+
"${_brew_url}/${_brew_arch}/go-fdo-client-${_brew_ver}-${_brew_rel}.${_brew_arch}.rpm"
83+
EOF
84+
elif [ -n "${COMPOSE_BASE_URL:-}" ]; then
85+
# Install go-fdo-client from a compose repository.
86+
# Generate per-stream repo files, copy them into the image, install, then remove them.
87+
local compose_streams="${COMPOSE_STREAMS:-BaseOS AppStream}"
88+
local arch
89+
arch=$(uname -m)
90+
local compose_base_url="${COMPOSE_BASE_URL%/}" # strip trailing slash to avoid double slashes in baseurl
91+
mkdir -p files
92+
local repo_args=""
93+
for stream in ${compose_streams}; do
94+
local repo_name="compose-${ID}-${VERSION_ID}-${stream}"
95+
local repo_file="files/${repo_name}.repo"
96+
cat > "${repo_file}" <<EOF
97+
[${repo_name}]
98+
name=${repo_name}
99+
baseurl=${compose_base_url}/${stream}/${arch}/os/
100+
enabled=1
101+
gpgcheck=0
102+
sslverify=0
103+
EOF
104+
repo_args+="COPY ${repo_file} /etc/yum.repos.d/${repo_name}.repo"$'\n'
105+
done
106+
tee Containerfile >/dev/null <<EOF
107+
FROM ${base_image_url}
108+
${repo_args}RUN dnf install -y --disablerepo='*' --enablerepo='compose-*' go-fdo-client && \
109+
rm -f /etc/yum.repos.d/compose-*.repo
110+
EOF
111+
else
112+
tee Containerfile >/dev/null <<EOF
42113
FROM ${base_image_url}
43114
RUN dnf=\$(readlink \$(command -v dnf)); [ "\${dnf}" = "dnf5" ] || dnf=dnf ; \
44115
rpm -q --whatprovides \${dnf}'-command(copr)' &> /dev/null || \${dnf} install -y \${dnf}'-command(copr)'; \
45116
\${dnf} copr enable -y '@fedora-iot/fedora-iot'; \
46117
\${dnf} install -y go-fdo-client; \
47118
\${dnf} copr disable -y @fedora-iot/fedora-iot
48119
EOF
120+
fi
121+
122+
# Append the RHEL repo file into the container image when it was generated.
123+
if [ -n "${rhel_repo_file}" ]; then
124+
tee -a Containerfile >/dev/null << EOF
125+
COPY ${rhel_repo_file} /etc/yum.repos.d/rhel-${VERSION_ID}.repo
126+
EOF
127+
fi
128+
49129
podman build --retry=5 --retry-delay=10s -t "fdo-bootc:latest" -f Containerfile .
50130
}
51131

@@ -99,19 +179,34 @@ echo "admin ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/admin' "${new_ks_file}"
99179
}
100180

101181
install_server() {
102-
if [ ! -v "PACKIT_COPR_RPMS" ]; then
182+
if [ -v "PACKIT_COPR_RPMS" ]; then
183+
echo " - Expected RPMs: ${PACKIT_COPR_RPMS}"
184+
elif [ -n "${SERVER_RPM_URL:-}" ]; then
185+
# Install from a specific brew build base path.
186+
# SERVER_RPM_URL should point to the version/release directory of the package in brew.
187+
parse_brew_url "${SERVER_RPM_URL}"
188+
# --nogpgcheck and sslverify=false are intentional: internal brew servers
189+
# use self-signed certificates and builds may not be GPG-signed.
190+
sudo dnf install -y --nogpgcheck --setopt=sslverify=false \
191+
"${_brew_url}/${_brew_arch}/go-fdo-server-${_brew_ver}-${_brew_rel}.${_brew_arch}.rpm" \
192+
"${_brew_url}/noarch/go-fdo-server-manufacturer-${_brew_ver}-${_brew_rel}.noarch.rpm" \
193+
"${_brew_url}/noarch/go-fdo-server-owner-${_brew_ver}-${_brew_rel}.noarch.rpm" \
194+
"${_brew_url}/noarch/go-fdo-server-rendezvous-${_brew_ver}-${_brew_rel}.noarch.rpm"
195+
elif [ -n "${COMPOSE_BASE_URL:-}" ]; then
196+
install_from_compose ${go_fdo_server_rpms}
197+
else
103198
sudo dnf install -y golang make
104199
commit="$(git rev-parse --short HEAD)"
105200
rpm -q go-fdo-server | grep -q "go-fdo-server.*git${commit}.*" || {
106201
make rpm
107202
sudo dnf install -y rpmbuild/rpms/{noarch,"$(uname -m)"}/*git"${commit}"*.rpm
108203
}
109-
else
110-
echo " - Expected RPMs: ${PACKIT_COPR_RPMS}"
111204
fi
112-
# Make sure the RPMS are installed
113-
installed_rpms=$(rpm -q --qf "%{nvr}.%{arch} " go-fdo-server{,-{manufacturer,owner,rendezvous}})
114-
echo " - Installed RPMs: ${installed_rpms}"
205+
installed_rpms=$(rpm -q --qf "%{nvr}.%{arch} " ${go_fdo_server_rpms})
206+
log_info "Installed Go FDO Server RPMs:"
207+
for i in ${installed_rpms}; do
208+
echo "$i"
209+
done
115210
}
116211

117212
install_client() {
@@ -140,6 +235,25 @@ configure_service_firewalld() {
140235
sudo dnf install -y firewalld
141236
fi
142237
sudo systemctl start firewalld
238+
239+
# firewalld 2.4.1+ no longer blocks on D-Bus at startup; poll until ready
240+
# so the later libvirt network (zone=trusted) start doesn't race it.
241+
log_info "Waiting for firewalld D-Bus interface to be ready"
242+
local fw_timeout=30
243+
local fw_elapsed=0
244+
until sudo firewall-cmd --state >/dev/null 2>&1; do
245+
sleep 1
246+
fw_elapsed=$((fw_elapsed + 1))
247+
if ! systemctl is-active --quiet firewalld; then
248+
echo "firewalld systemd unit is not active" >&2
249+
sudo systemctl status firewalld --no-pager >&2 || true
250+
return 1
251+
fi
252+
if [[ ${fw_elapsed} -ge ${fw_timeout} ]]; then
253+
echo "firewalld did not become ready after ${fw_timeout} seconds" >&2
254+
return 1
255+
fi
256+
done
143257
}
144258

145259
configure_service_libvirtd() {

test/ci/utils.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,20 @@ stop_services() {
404404
done
405405
}
406406

407+
# Parse a brew build base URL into its components.
408+
# The URL must point to the version/release directory of the package in brew.
409+
# Sets _brew_url, _brew_ver, _brew_rel and _brew_arch. Must be called directly
410+
# (not via command substitution) so the assignments aren't lost in a subshell:
411+
# parse_brew_url "${SOME_RPM_URL}"
412+
# echo "${_brew_url} ${_brew_ver} ${_brew_rel} ${_brew_arch}"
413+
parse_brew_url() {
414+
local url="${1%/}" # strip any trailing slash to prevent empty basename
415+
_brew_url="${url}"
416+
_brew_ver=$(basename "$(dirname "${url}")")
417+
_brew_rel=$(basename "${url}")
418+
_brew_arch=$(uname -m)
419+
}
420+
407421
fetch_client_repo() {
408422
[ -d "${client_src_dir}" ] || git clone --single-branch https://github.com/fido-device-onboard/go-fdo-client "${client_src_dir}"
409423
if [ -v "CLIENT_REF" ]; then

test/rpm/utils.sh

Lines changed: 102 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ configure_service_owner() {
202202
sudo chown -R ${rpm_owner_user}:${rpm_server_group} ${rpm_owner_home_dir}
203203
}
204204

205+
go_fdo_server_rpms="go-fdo-server go-fdo-server-manufacturer go-fdo-server-owner go-fdo-server-rendezvous"
206+
go_fdo_client_rpms="go-fdo-client"
207+
205208
install_from_copr() {
206209
rpm -q --whatprovides 'dnf-command(copr)' &>/dev/null || sudo dnf install -y 'dnf-command(copr)'
207210
dnf copr list | grep 'fedora-iot/fedora-iot' || sudo dnf copr enable -y @fedora-iot/fedora-iot
@@ -211,10 +214,80 @@ install_from_copr() {
211214
sudo dnf copr disable -y @fedora-iot/fedora-iot
212215
}
213216

217+
# Install RPM packages from a compose repository.
218+
#
219+
# The compose base URL is read from COMPOSE_BASE_URL. For Fedora and CentOS a
220+
# reasonable default is computed from /etc/os-release; for RHEL the variable is
221+
# mandatory. COMPOSE_STREAMS optionally overrides the space-separated list of
222+
# stream names (repo sub-directories) to enable.
223+
install_from_compose() {
224+
# shellcheck source=/dev/null
225+
source /etc/os-release
226+
local compose_host compose_id compose_base_url compose_streams
227+
case "${ID}-${VERSION_ID}" in
228+
fedora-rawhide)
229+
compose_host="http://kojipkgs.fedoraproject.org"
230+
compose_id="latest-Fedora-${VERSION_ID^}"
231+
compose_streams="${COMPOSE_STREAMS:-Everything}"
232+
compose_base_url="${COMPOSE_BASE_URL:-${compose_host}/compose/${VERSION_ID}/${compose_id}/compose}"
233+
;;
234+
fedora-*)
235+
compose_host="http://kojipkgs.fedoraproject.org"
236+
compose_streams="${COMPOSE_STREAMS:-Everything}"
237+
compose_base_url="${COMPOSE_BASE_URL:-${compose_host}/compose/updates/f${VERSION_ID}-updates/compose}"
238+
;;
239+
centos-*)
240+
compose_host="https://composes.stream.centos.org"
241+
compose_id="latest-CentOS-Stream"
242+
compose_streams="${COMPOSE_STREAMS:-BaseOS AppStream}"
243+
compose_base_url="${COMPOSE_BASE_URL:-${compose_host}/stream-${VERSION_ID}/production/${compose_id}/compose}"
244+
;;
245+
rhel-*)
246+
compose_base_url="${COMPOSE_BASE_URL:-}"
247+
[ -n "${compose_base_url}" ] || log_error "COMPOSE_BASE_URL must be set for RHEL (e.g. 'http://download.host/.../latest-RHEL-Compose/compose/')"
248+
compose_streams="${COMPOSE_STREAMS:-BaseOS AppStream}"
249+
[ -n "${compose_streams}" ] || log_error "COMPOSE_STREAMS must be set for RHEL (default='BaseOS AppStream')"
250+
;;
251+
*)
252+
log_error "install_from_compose: unsupported OS '${ID}-${VERSION_ID}'"
253+
;;
254+
esac
255+
256+
local arch
257+
arch=$(uname -m)
258+
compose_base_url="${compose_base_url%/}" # strip trailing slash to avoid double slashes in baseurl
259+
for stream in ${compose_streams}; do
260+
local repo_name="compose-${ID}-${VERSION_ID}-${stream}"
261+
sudo tee "/etc/yum.repos.d/${repo_name}.repo" >/dev/null <<EOF
262+
[${repo_name}]
263+
name=${repo_name}
264+
baseurl=${compose_base_url}/${stream}/${arch}/os/
265+
enabled=1
266+
gpgcheck=0
267+
sslverify=0
268+
EOF
269+
done
270+
sudo dnf install --disablerepo=* --enablerepo="compose-*" -y "$@"
271+
sudo rm -f /etc/yum.repos.d/compose-*.repo
272+
}
273+
214274
install_client() {
215-
# If PACKIT_COPR_RPMS is not defined it means we are running the test
216-
# locally so we will install the client from the copr repo
217-
[ -v "PACKIT_COPR_RPMS" ] || rpm -q go-fdo-client &>/dev/null || install_from_copr go-fdo-client
275+
if [ -v "PACKIT_COPR_RPMS" ]; then
276+
: # pre-installed by CI
277+
elif [ -n "${CLIENT_RPM_URL:-}" ]; then
278+
# Install from a specific brew build base path.
279+
# CLIENT_RPM_URL should point to the version/release directory of the package in brew.
280+
parse_brew_url "${CLIENT_RPM_URL}"
281+
# --nogpgcheck and sslverify=false are intentional: internal brew servers
282+
# use self-signed certificates and builds may not be GPG-signed.
283+
sudo dnf install -y --nogpgcheck --setopt=sslverify=false \
284+
"${_brew_url}/${_brew_arch}/go-fdo-client-${_brew_ver}-${_brew_rel}.${_brew_arch}.rpm"
285+
elif [ -n "${COMPOSE_BASE_URL:-}" ]; then
286+
install_from_compose ${go_fdo_client_rpms}
287+
else
288+
# If running locally install the client from the COPR repo
289+
rpm -q go-fdo-client &>/dev/null || install_from_copr go-fdo-client
290+
fi
218291
log_info "Installed Client RPM:"
219292
echo "$(rpm -q go-fdo-client)"
220293
}
@@ -223,8 +296,9 @@ uninstall_client() {
223296
# When running a test locally we remove the client package
224297
# after a successful execution.
225298
[ -v "PACKIT_COPR_RPMS" ] || {
226-
sudo dnf remove -y go-fdo-client
227-
sudo dnf copr remove -y @fedora-iot/fedora-iot
299+
sudo dnf remove -y ${go_fdo_client_rpms}
300+
# Only remove the COPR repo when it was used for installation
301+
[ -n "${CLIENT_RPM_URL:-}" ] || [ -n "${COMPOSE_BASE_URL:-}" ] || sudo dnf copr remove -y @fedora-iot/fedora-iot
228302
}
229303
}
230304

@@ -240,30 +314,43 @@ run_go_fdo_client() {
240314
}
241315

242316
install_server() {
243-
# If PACKIT_COPR_RPMS is not defined it means we are running the test
244-
# locally so we will build and install the RPMs from the *committed* code
245-
if [ ! -v "PACKIT_COPR_RPMS" ]; then
317+
if [ -v "PACKIT_COPR_RPMS" ]; then
318+
log_info "Expected Server RPMs:"
319+
for i in ${PACKIT_COPR_RPMS}; do
320+
echo "$i"
321+
done | sort
322+
elif [ -n "${SERVER_RPM_URL:-}" ]; then
323+
# Install from a specific brew build base path.
324+
# SERVER_RPM_URL should point to the version/release directory of the package in brew.
325+
parse_brew_url "${SERVER_RPM_URL}"
326+
# --nogpgcheck and sslverify=false are intentional: internal brew servers
327+
# use self-signed certificates and builds may not be GPG-signed.
328+
sudo dnf install -y --nogpgcheck --setopt=sslverify=false \
329+
"${_brew_url}/${_brew_arch}/go-fdo-server-${_brew_ver}-${_brew_rel}.${_brew_arch}.rpm" \
330+
"${_brew_url}/noarch/go-fdo-server-manufacturer-${_brew_ver}-${_brew_rel}.noarch.rpm" \
331+
"${_brew_url}/noarch/go-fdo-server-owner-${_brew_ver}-${_brew_rel}.noarch.rpm" \
332+
"${_brew_url}/noarch/go-fdo-server-rendezvous-${_brew_ver}-${_brew_rel}.noarch.rpm"
333+
elif [ -n "${COMPOSE_BASE_URL:-}" ]; then
334+
install_from_compose ${go_fdo_server_rpms}
335+
else
336+
# If PACKIT_COPR_RPMS is not defined it means we are running the test
337+
# locally so we will build and install the RPMs from the *committed* code
246338
commit="$(git rev-parse --short HEAD)"
247339
rpm -q go-fdo-server | grep -q "go-fdo-server.*git${commit}.*" || {
248340
make rpm
249341
sudo dnf install -y rpmbuild/rpms/{noarch,"$(uname -m)"}/*git"${commit}"*.rpm
250342
}
251-
else
252-
log_info "Expected Server RPMs:"
253-
for i in ${PACKIT_COPR_RPMS}; do
254-
echo "$i"
255-
done | sort
256343
fi
257344
# Make sure the RPMS are installed
258-
installed_rpms=$(rpm -q --qf "%{nvr}.%{arch} " go-fdo-server{,-{manufacturer,owner,rendezvous}})
345+
installed_rpms=$(rpm -q --qf "%{nvr}.%{arch} " ${go_fdo_server_rpms})
259346
log_info "Installed Server RPMs:"
260347
for i in ${installed_rpms}; do
261348
echo "$i"
262349
done | sort
263350
}
264351

265352
uninstall_server() {
266-
[ -v "PACKIT_COPR_RPMS" ] || sudo dnf remove -y go-fdo-server{,-manufacturer,-owner,-rendezvous}
353+
[ -v "PACKIT_COPR_RPMS" ] || sudo dnf remove -y ${go_fdo_server_rpms}
267354
}
268355

269356
start_service_manufacturer() {

0 commit comments

Comments
 (0)