135 lines
5.3 KiB
Bash
Executable File
135 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -Eeuo pipefail
|
|
umask 022
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
# shellcheck source=lib.sh
|
|
. "${SCRIPT_DIR}/lib.sh"
|
|
|
|
STAGE_DIR=""
|
|
OUTPUT_DIR="${RKMEDIA_ROOT}/out"
|
|
PACKAGE_VERSION="$(tr -d '[:space:]' < "${RKMEDIA_ROOT}/VERSION")"
|
|
DEPENDS_FROM_DEB=""
|
|
|
|
usage() {
|
|
printf 'Usage: package-media.sh --stage DIRECTORY [--output-dir DIRECTORY] [--version VERSION] [--depends-from-deb FILE]\n'
|
|
}
|
|
|
|
while (($#)); do
|
|
case "$1" in
|
|
--stage) [[ $# -ge 2 ]] || die "--stage requires a directory"; STAGE_DIR="$2"; shift 2 ;;
|
|
--output-dir) [[ $# -ge 2 ]] || die "--output-dir requires a directory"; OUTPUT_DIR="$2"; shift 2 ;;
|
|
--version) [[ $# -ge 2 ]] || die "--version requires a value"; PACKAGE_VERSION="$2"; shift 2 ;;
|
|
--depends-from-deb) [[ $# -ge 2 ]] || die "--depends-from-deb requires a file"; DEPENDS_FROM_DEB="$2"; shift 2 ;;
|
|
-h|--help) usage; exit 0 ;;
|
|
*) die "unknown argument: $1" ;;
|
|
esac
|
|
done
|
|
|
|
[[ -n "${STAGE_DIR}" ]] || die "--stage is required"
|
|
[[ "${PACKAGE_VERSION}" =~ ^[0-9A-Za-z.+:~-]+$ ]] || die "invalid Debian package version: ${PACKAGE_VERSION}"
|
|
for command_name in dpkg-deb dpkg-shlibdeps file jq md5sum sed sha256sum; do
|
|
need_command "${command_name}"
|
|
done
|
|
|
|
STAGE_DIR="$(absolute_path "${STAGE_DIR}")"
|
|
OUTPUT_DIR="$(absolute_path "${OUTPUT_DIR}")"
|
|
[[ -x "${STAGE_DIR}/opt/rkmedia/bin/ffmpeg" ]] || die "stage does not contain the RKMedia runtime"
|
|
mkdir -p -- "${OUTPUT_DIR}"
|
|
|
|
PACKAGE_ROOT="${OUTPUT_DIR}/package-root"
|
|
reset_child_dir "${OUTPUT_DIR}" "${PACKAGE_ROOT}"
|
|
cp -a -- "${STAGE_DIR}/." "${PACKAGE_ROOT}/"
|
|
mkdir -p -- "${PACKAGE_ROOT}/DEBIAN" "${PACKAGE_ROOT}/usr/share/doc/rk1-media-stack"
|
|
|
|
cp -- "${RKMEDIA_ROOT}/packaging/postinst" "${PACKAGE_ROOT}/DEBIAN/postinst"
|
|
cp -- "${RKMEDIA_ROOT}/packaging/prerm" "${PACKAGE_ROOT}/DEBIAN/prerm"
|
|
cp -- "${RKMEDIA_ROOT}/packaging/postrm" "${PACKAGE_ROOT}/DEBIAN/postrm"
|
|
chmod 0755 "${PACKAGE_ROOT}/DEBIAN/postinst" "${PACKAGE_ROOT}/DEBIAN/prerm" "${PACKAGE_ROOT}/DEBIAN/postrm"
|
|
printf '/etc/rkmedia/kodi.env\n' > "${PACKAGE_ROOT}/DEBIAN/conffiles"
|
|
|
|
# A collaborative workspace or permissive host umask must never make core
|
|
# target directories such as /etc, /usr, or /opt group-writable via dpkg.
|
|
find "${PACKAGE_ROOT}" -type d -exec chmod 0755 {} +
|
|
find "${PACKAGE_ROOT}" -type f ! -perm /0111 -exec chmod 0644 {} +
|
|
find "${PACKAGE_ROOT}" -type f -perm /0111 -exec chmod 0755 {} +
|
|
if find "${PACKAGE_ROOT}" \( -type d -o -type f \) -perm /0022 -print -quit \
|
|
| grep -q .; then
|
|
die "package contains a group/world-writable path"
|
|
fi
|
|
|
|
if [[ -n "${DEPENDS_FROM_DEB}" ]]; then
|
|
DEPENDS_FROM_DEB="$(absolute_path "${DEPENDS_FROM_DEB}")"
|
|
[[ -f "${DEPENDS_FROM_DEB}" ]] || die "dependency source package not found: ${DEPENDS_FROM_DEB}"
|
|
shlib_depends="$(dpkg-deb --field "${DEPENDS_FROM_DEB}" Depends)"
|
|
[[ -n "${shlib_depends}" ]] || die "upstream package has an empty Depends field"
|
|
else
|
|
analysis_root="${OUTPUT_DIR}/shlibdeps"
|
|
reset_child_dir "${OUTPUT_DIR}" "${analysis_root}"
|
|
mkdir -p -- "${analysis_root}/debian"
|
|
cat > "${analysis_root}/debian/control" <<'EOF'
|
|
Source: rk1-media-stack
|
|
Section: video
|
|
Priority: optional
|
|
|
|
Package: rk1-media-stack
|
|
Architecture: arm64
|
|
Description: temporary metadata for dpkg-shlibdeps
|
|
EOF
|
|
|
|
elf_files=()
|
|
while IFS= read -r -d '' candidate; do
|
|
if file --brief "${candidate}" | grep -q '^ELF '; then
|
|
elf_files+=("${candidate}")
|
|
fi
|
|
done < <(find "${PACKAGE_ROOT}/opt/rkmedia" -type f -print0)
|
|
((${#elf_files[@]} > 0)) || die "no ELF files found in media stage"
|
|
|
|
pushd "${analysis_root}" >/dev/null
|
|
shlib_output="$(dpkg-shlibdeps --ignore-missing-info -O \
|
|
-l"${PACKAGE_ROOT}/opt/rkmedia/lib" "${elf_files[@]}")"
|
|
popd >/dev/null
|
|
shlib_depends="${shlib_output#shlibs:Depends=}"
|
|
[[ -n "${shlib_depends}" && "${shlib_depends}" != "${shlib_output}" ]] \
|
|
|| die "dpkg-shlibdeps did not produce runtime dependencies"
|
|
fi
|
|
|
|
depends="adduser, systemd, udev, ${shlib_depends}"
|
|
installed_size="$(du -sk "${PACKAGE_ROOT}" | awk '{print $1}')"
|
|
if [[ -f "${PACKAGE_ROOT}/usr/share/doc/rk1-media-stack/upstream-deb.lock.json" ]]; then
|
|
provenance_file="${PACKAGE_ROOT}/usr/share/doc/rk1-media-stack/upstream-deb.lock.json"
|
|
else
|
|
provenance_file="${PACKAGE_ROOT}/usr/share/doc/rk1-media-stack/sources.lock.json"
|
|
fi
|
|
lock_sha256="$(sha256sum "${provenance_file}" | awk '{print $1}')"
|
|
|
|
sed \
|
|
-e "s/@VERSION@/${PACKAGE_VERSION}/g" \
|
|
-e "s/@INSTALLED_SIZE@/${installed_size}/g" \
|
|
-e "s/@LOCK_SHA256@/${lock_sha256}/g" \
|
|
-e "s/@DEPENDS@/${depends}/g" \
|
|
"${RKMEDIA_ROOT}/packaging/control.in" > "${PACKAGE_ROOT}/DEBIAN/control"
|
|
|
|
pushd "${PACKAGE_ROOT}" >/dev/null
|
|
find etc opt usr -type f -print0 \
|
|
| sort -z \
|
|
| xargs -0 md5sum > DEBIAN/md5sums
|
|
popd >/dev/null
|
|
|
|
if find "${PACKAGE_ROOT}" \( -type d -o -type f \) -perm /0022 -print -quit \
|
|
| grep -q .; then
|
|
die "package contains a group/world-writable path after metadata generation"
|
|
fi
|
|
|
|
output_deb="${OUTPUT_DIR}/rk1-media-stack_${PACKAGE_VERSION}_arm64.deb"
|
|
rm -f -- "${output_deb}"
|
|
SOURCE_DATE_EPOCH="$(jq -er '.source_date_epoch' "${RKMEDIA_ROOT}/sources.lock.json")" \
|
|
dpkg-deb --root-owner-group --build "${PACKAGE_ROOT}" "${output_deb}"
|
|
(
|
|
cd "${OUTPUT_DIR}"
|
|
sha256sum "$(basename -- "${output_deb}")" \
|
|
>"$(basename -- "${output_deb}").sha256"
|
|
)
|
|
dpkg-deb --info "${output_deb}" >/dev/null
|
|
log "created ${output_deb}"
|