xref: /spdk/test/packaging/rpm/rpm.sh (revision 14e26b9d0410a98689caffcba7bfacac8d85c74d)
1#!/usr/bin/env bash
2#  SPDX-License-Identifier: BSD-3-Clause
3#  Copyright (C) 2022 Intel Corporation
4#  All rights reserved.
5#
6
7testdir=$(readlink -f "$(dirname "$0")")
8rootdir=$(readlink -f "$testdir/../../../")
9source "$rootdir/test/common/autotest_common.sh"
10
11builddir=$SPDK_TEST_STORAGE/test-rpm
12
13# Make sure linker will not attempt to look under DPDK's repo dir to get the libs
14unset -v LD_LIBRARY_PATH
15
16# Export some common settings
17BUILDDIR=$builddir
18DEPS=no
19arch=$(uname -m)
20
21export MAKEFLAGS BUILDDIR DEPS
22
23cleanup() {
24	rm -rf "$builddir"
25	rm -rf "$(rpm --eval "%{_topdir}")"
26	rm -rf /tmp/spdk-test_gen_spec
27	sudo rpm -e $(rpm -qa | grep -E 'spdk|dpdk') || true
28}
29
30gen_dpdk_spec() (
31	cat <<- DPDK_SPEC
32		%define source_date_epoch_from_changelog %{nil}
33
34		Name:           dpdk-devel
35		Version:        $1
36		Release:        $2
37		Summary:        TESTME
38		Source:         dpdk.tar.gz
39		License:        TESTME
40
41		%description
42		TESTME
43
44		%files
45		/usr/local/lib/*
46	DPDK_SPEC
47)
48
49build_dpdk_rpm() (
50	local dpdkdir=$1 version=${2%.*} spec=$builddir/dpdk.spec
51	local dpdkbuildroot=$builddir/dpdk/usr/local/lib dep
52	local srcdir=$builddir/source
53	local rpmdir=$builddir/rpms
54	local release=1
55
56	mkdir -p "$srcdir" "$rpmdir"
57
58	# Dummy package to satisfy rpmbuild
59	: > "$srcdir/dpdk.tar.gz"
60
61	gen_dpdk_spec "$version" "$release" > "$spec"
62
63	# Prepare our buildroot to pack just the libraries without actually building
64	# anything. To do so, we need to copy what we need into a separate location
65	# to not fiddle with rpmbuild's view on what should be packed and what
66	# shouldn't.
67	mkdir -p "$dpdkbuildroot"
68
69	[[ -e $dpdkdir/lib ]]
70	cp -a "$dpdkdir/lib/"* "$dpdkbuildroot/"
71
72	# Check isa-l and IPSec dependencies - dedicated to the vs-dpdk test
73	for dep in isa-l/build/lib intel-ipsec-mb; do
74		[[ -e $dpdkdir/../$dep ]] || continue
75		find "$dpdkdir/../$dep" \
76			-name '*.so*' \
77			-exec cp -at "$dpdkbuildroot/" {} +
78	done
79
80	rpmbuild \
81		--buildroot="$builddir/dpdk" \
82		-D "_rpmdir $rpmdir" \
83		-D "_sourcedir $srcdir" \
84		--noclean \
85		--nodebuginfo \
86		-ba "$spec"
87
88	# Put our dummy package in place
89	sudo rpm -i "$rpmdir/$arch/dpdk-devel-$version-$release.$arch.rpm"
90
91	# Run actual test
92	MV_RUNPATH=$dpdkdir build_rpm --with-shared --with-dpdk="$dpdkdir"
93
94	sudo rpm -e dpdk-devel
95)
96
97install_uninstall_rpms() {
98	local rpms
99
100	rpms=("${1:-$builddir/rpm/}/$arch/"*.rpm)
101
102	# Clean repo first to make sure linker won't follow $SPDK_APP's RUNPATH
103	make -C "$rootdir" clean $MAKEFLAGS
104
105	sudo rpm -i "${rpms[@]}"
106	# Check if we can find one of the apps in the PATH now and verify if it doesn't miss
107	# any libs.
108	LIST_LIBS=yes "$rootdir/rpmbuild/rpm-deps.sh" "${SPDK_APP[@]##*/}"
109	rm "${rpms[@]}"
110	rpms=("${rpms[@]##*/}") rpms=("${rpms[@]%.rpm}")
111	sudo rpm -e "${rpms[@]}"
112}
113
114build_rpm() {
115	# Separate run to see the final .spec in use
116	GEN_SPEC=yes "$rootdir/rpmbuild/rpm.sh" "$@"
117	# Actual build
118	"$rootdir/rpmbuild/rpm.sh" "$@" || return $?
119	# FIXME: Remove the MV_RUNPATH HACK when the patchelf is available. See: 9cb9f24152f
120	if [[ -n $MV_RUNPATH ]]; then
121		mv "$MV_RUNPATH"{,.hidden}
122	fi
123	install_uninstall_rpms
124	if [[ -n $MV_RUNPATH ]]; then
125		mv "$MV_RUNPATH"{.hidden,}
126	fi
127}
128
129build_shared_rpm() {
130	build_rpm --with-shared
131}
132
133build_rpm_with_rpmed_dpdk() {
134	local es=0 dpdk_rpms=()
135
136	dpdk_rpms=(/var/spdk/dependencies/autotest/dpdk/dpdk?(-devel).rpm)
137	if ((${#dpdk_rpms[@]} == 2)); then # dpdk, dpdk-devel
138		echo "INFO: Installing DPDK from local package: $(rpm -q --queryformat="%{VERSION}" "${dpdk_rpms[0]}")" >&2
139		sudo rpm -i "${dpdk_rpms[@]}"
140	else
141		echo "WARNING: No local packages found, trying to install DPDK from the remote" >&2
142		sudo dnf install -y dpdk-devel
143	fi
144	build_rpm --with-shared --with-dpdk || es=$?
145
146	if ((es == 11)); then
147		echo "ERROR: Failed to resolve required build dependencies. Please review the build log." >&2
148	fi
149
150	sudo rpm -e dpdk{,-devel} || true
151
152	return "$es"
153}
154
155build_rpm_from_gen_spec() {
156	local version=test_gen_spec
157	local sourcedir rpmdir rpmbuilddir
158
159	GEN_SPEC=yes \
160		USE_DEFAULT_DIRS=yes \
161		SPDK_VERSION="$version" \
162		"$rootdir/rpmbuild/rpm.sh" --with-shared > "$builddir/gen-spdk.spec"
163
164	# Default locations should be in use.
165	sourcedir=$(rpm --eval "%{_sourcedir}")
166	rpmdir=$(rpm --eval "%{_rpmdir}")
167	rpmbuilddir=$(rpm --eval "%{_builddir}")
168
169	mkdir -p "$sourcedir" "$rpmdir" "$rpmbuilddir"
170
171	# Prepare the source at the default location - default %prep step requires
172	# extra dir inside the source package.
173	cp -r "$rootdir" "/tmp/spdk-$version"
174	tar -czf "$sourcedir/spdk-$version.tar.gz" -C /tmp "spdk-$version"
175
176	# See rpm.sh for details on the PYTHONPATH HACK
177	PYTHONPATH="$(python3 -c "import sys; print('%s' % ':'.join(sys.path)[1:])")" \
178		rpmbuild -ba "$builddir/gen-spdk.spec"
179	# Clean builddir to make sure linker won't follow $SPDK_APP's RUNPATH
180	rm -rf "$rpmbuilddir"
181	install_uninstall_rpms "$rpmdir"
182}
183
184build_shared_native_dpdk_rpm() {
185	[[ -e /tmp/spdk-ld-path ]] # autobuild dependency
186	source /tmp/spdk-ld-path
187
188	build_dpdk_rpm \
189		"$SPDK_RUN_EXTERNAL_DPDK" \
190		"$(< $SPDK_RUN_EXTERNAL_DPDK/../VERSION)"
191}
192
193trap 'cleanup' EXIT
194
195run_test "build_shared_rpm" build_shared_rpm
196run_test "build_rpm_from_gen_spec" build_rpm_from_gen_spec
197
198if ((RUN_NIGHTLY == 1)); then
199	run_test "build_shared_rpm_with_rpmed_dpdk" build_rpm_with_rpmed_dpdk
200fi
201
202if [[ -n $SPDK_TEST_NATIVE_DPDK ]]; then
203	run_test "build_shared_native_dpdk_rpm" build_shared_native_dpdk_rpm
204fi
205