Initial RK1 media-center image project
This commit is contained in:
Executable
+164
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
readonly PROJECT_USERPATCHES="${SCRIPT_DIR}/userpatches"
|
||||
readonly SOURCE_LOCK="${PROJECT_USERPATCHES}/source-lock.env"
|
||||
readonly FRAMEWORK_OVERRIDES="${SCRIPT_DIR}/framework-overrides"
|
||||
|
||||
die() {
|
||||
echo "build-image.sh: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: build-image.sh --ssh-public-key PATH [OPTIONS]
|
||||
|
||||
Build the source-locked Armbian Debian Trixie image for Turing RK1.
|
||||
|
||||
Options:
|
||||
--ssh-public-key PATH Required OpenSSH public-key/authorized_keys file.
|
||||
--work-dir PATH Managed framework/cache directory (default: .work).
|
||||
--prepare-only Clone/stage inputs, but do not invoke Armbian.
|
||||
--config-dump Stage inputs and run Armbian's non-building config dump.
|
||||
-h, --help Show this help.
|
||||
|
||||
The default action performs the full image build. It may ask for sudo through
|
||||
Armbian's normal native-build launcher. No image is flashed by this command.
|
||||
EOF
|
||||
}
|
||||
|
||||
validate_public_keys() {
|
||||
local key_file="${1}"
|
||||
[[ -f "${key_file}" ]] || die "public-key file does not exist: ${key_file}"
|
||||
[[ -s "${key_file}" ]] || die "public-key file is empty: ${key_file}"
|
||||
command -v ssh-keygen >/dev/null || die "ssh-keygen is required to validate the public key"
|
||||
|
||||
awk '
|
||||
/^[[:space:]]*($|#)/ { next }
|
||||
$1 !~ /^(ssh-ed25519|ssh-rsa|ecdsa-sha2-nistp(256|384|521)|[email protected]|[email protected])$/ { exit 1 }
|
||||
{ count++ }
|
||||
END { if (count < 1) exit 1 }
|
||||
' "${key_file}" || die "use plain OpenSSH public keys without authorized_keys options"
|
||||
ssh-keygen -l -f "${key_file}" >/dev/null || die "ssh-keygen rejected the supplied public-key file"
|
||||
}
|
||||
|
||||
prepare_framework() {
|
||||
local work_root="${1}"
|
||||
local framework_dir="${work_root}/armbian-build"
|
||||
local origin
|
||||
|
||||
install -d -m 0755 "${work_root}"
|
||||
work_root="$(cd -- "${work_root}" && pwd -P)"
|
||||
framework_dir="${work_root}/armbian-build"
|
||||
[[ "${work_root}" != "/" ]] || die "refusing to use / as the work directory"
|
||||
|
||||
if [[ ! -e "${framework_dir}" ]]; then
|
||||
git init "${framework_dir}" >/dev/null
|
||||
git -C "${framework_dir}" remote add origin "${RK1_MEDIA_ARMBIAN_BUILD_URL}"
|
||||
install -m 0600 /dev/null "${framework_dir}/.rk1-media-build-root"
|
||||
fi
|
||||
|
||||
[[ -d "${framework_dir}/.git" ]] || die "work path is not a Git checkout: ${framework_dir}"
|
||||
[[ -f "${framework_dir}/.rk1-media-build-root" ]] || die "work checkout is not managed by this script: ${framework_dir}"
|
||||
origin="$(git -C "${framework_dir}" remote get-url origin)"
|
||||
[[ "${origin}" == "${RK1_MEDIA_ARMBIAN_BUILD_URL}" ]] || die "unexpected Armbian origin: ${origin}"
|
||||
|
||||
if git -C "${framework_dir}" rev-parse --verify HEAD >/dev/null 2>&1; then
|
||||
git -C "${framework_dir}" diff --quiet || die "tracked modifications exist in ${framework_dir}"
|
||||
git -C "${framework_dir}" diff --cached --quiet || die "staged modifications exist in ${framework_dir}"
|
||||
fi
|
||||
|
||||
if ! git -C "${framework_dir}" cat-file -e "${RK1_MEDIA_ARMBIAN_BUILD_COMMIT}^{commit}" 2>/dev/null; then
|
||||
git -C "${framework_dir}" fetch --depth=1 origin "${RK1_MEDIA_ARMBIAN_BUILD_COMMIT}"
|
||||
fi
|
||||
git -C "${framework_dir}" checkout --detach "${RK1_MEDIA_ARMBIAN_BUILD_COMMIT}" >/dev/null
|
||||
|
||||
printf '%s\n' "${framework_dir}"
|
||||
}
|
||||
|
||||
stage_userpatches() {
|
||||
local framework_dir="${1}"
|
||||
local public_key="${2}"
|
||||
local destination="${framework_dir}/userpatches"
|
||||
|
||||
[[ -f "${framework_dir}/.rk1-media-build-root" ]] || die "refusing to stage into an unmanaged checkout"
|
||||
[[ "${destination}" == "${framework_dir}/userpatches" ]] || die "internal userpatch path check failed"
|
||||
[[ ! -L "${destination}" ]] || die "refusing to replace a symlinked userpatches directory"
|
||||
if [[ -e "${destination}" ]]; then
|
||||
[[ -f "${destination}/.rk1-media-managed" ]] || die "existing userpatches are not managed by this script"
|
||||
rm -rf -- "${destination}"
|
||||
fi
|
||||
|
||||
install -d -m 0755 "${destination}"
|
||||
cp -a "${PROJECT_USERPATCHES}/." "${destination}/"
|
||||
install -m 0600 /dev/null "${destination}/.rk1-media-managed"
|
||||
install -d -m 0700 "${destination}/overlay/build-input"
|
||||
install -m 0600 "${public_key}" "${destination}/overlay/build-input/authorized_keys"
|
||||
install -m 0644 "${SOURCE_LOCK}" "${destination}/overlay/build-input/source-lock.env"
|
||||
|
||||
# Armbian supports immutable resolutions for otherwise moving branch inputs
|
||||
# through config/sources/git_sources.json. This pins its firmware artifact.
|
||||
cp -a "${FRAMEWORK_OVERRIDES}/." "${framework_dir}/"
|
||||
}
|
||||
|
||||
main() {
|
||||
local public_key=""
|
||||
local work_dir="${SCRIPT_DIR}/.work"
|
||||
local mode="build"
|
||||
local framework_dir
|
||||
|
||||
while (($#)); do
|
||||
case "${1}" in
|
||||
--ssh-public-key)
|
||||
(($# >= 2)) || die "--ssh-public-key requires a path"
|
||||
public_key="${2}"
|
||||
shift 2
|
||||
;;
|
||||
--work-dir)
|
||||
(($# >= 2)) || die "--work-dir requires a path"
|
||||
work_dir="${2}"
|
||||
shift 2
|
||||
;;
|
||||
--prepare-only)
|
||||
mode="prepare"
|
||||
shift
|
||||
;;
|
||||
--config-dump)
|
||||
mode="config-dump"
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*) die "unknown option: ${1}" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -n "${public_key}" ]] || die "--ssh-public-key is required; the image never enables password login"
|
||||
[[ -r "${SOURCE_LOCK}" ]] || die "source lock is missing: ${SOURCE_LOCK}"
|
||||
# shellcheck source=userpatches/source-lock.env
|
||||
source "${SOURCE_LOCK}"
|
||||
validate_public_keys "${public_key}"
|
||||
framework_dir="$(prepare_framework "${work_dir}")"
|
||||
stage_userpatches "${framework_dir}" "${public_key}"
|
||||
|
||||
echo "Prepared Armbian ${RK1_MEDIA_ARMBIAN_BUILD_COMMIT} in ${framework_dir}"
|
||||
case "${mode}" in
|
||||
prepare)
|
||||
echo "Configuration staged; no build was started."
|
||||
;;
|
||||
config-dump)
|
||||
(cd "${framework_dir}" && CONFIG_DEFS_ONLY=yes ./compile.sh rk1-media config-dump)
|
||||
;;
|
||||
build)
|
||||
(cd "${framework_dir}" && ./compile.sh rk1-media build)
|
||||
echo "Images and checksums: ${framework_dir}/output/images"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user