Files
rk1/media/scripts/package-media.sh
T

135 lines
5.3 KiB
Bash
Raw Normal View History

2026-08-17 18:42:29 +00:00
#!/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}"