You've already forked armbian.github.io
mirror of
https://github.com/armbian/armbian.github.io.git
synced 2026-01-06 11:42:20 -08:00
Add U-Boot package copying support to Armbian kernel copy script
Enhance copy-armbian-kernel script to support copying U-Boot bootloader packages in addition to kernel packages. Key changes: - Add COPY_UBOOT flag (default: true) to enable/disable U-Boot copying - Add UBOOT_SELECT variable for board/branch filtering (e.g., 'odroidm1:current') - Split JQ program into reusable components (JQ_EXPAND, JQ_KERNEL_PAIRS, JQ_UBOOT_TRIPLETS) - Add uboot_selected() function for pattern-based U-Boot selection - Extract copy operations into copy_flat() and copy_recursive() helpers - Track selected kernel pairs to filter U-Boot packages by default
This commit is contained in:
292
scripts/copy-kernel-packages.sh
Executable file
292
scripts/copy-kernel-packages.sh
Executable file
@@ -0,0 +1,292 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# =============================================================================
|
||||
# copy-armbian-kernel-and-uboot-debs.sh
|
||||
#
|
||||
# Copy a minimal, de-duplicated set of Armbian kernel and U-Boot .deb packages
|
||||
# from SRC_DIR to DST_DIR based on image-info.json.
|
||||
#
|
||||
# Kernel packages are unique per (linuxfamily, branch).
|
||||
# U-Boot packages are unique per (board, branch).
|
||||
#
|
||||
# SELECT syntax:
|
||||
# SELECT='linuxfamily_glob[:branch_glob] ...'
|
||||
# Examples:
|
||||
# SELECT='meson64:current imx6:current'
|
||||
# SELECT='meson64:* imx6:current'
|
||||
# SELECT='meson64*' # shorthand for meson64*:*
|
||||
#
|
||||
# UBOOT_SELECT syntax:
|
||||
# UBOOT_SELECT='board_glob[:branch_glob] ...'
|
||||
# Examples:
|
||||
# UBOOT_SELECT='odroidm1:current'
|
||||
# UBOOT_SELECT='bananapim64:*'
|
||||
#
|
||||
# Other flags:
|
||||
# DRY_RUN=true
|
||||
# INCLUDE_LIBC_DEV=true
|
||||
# COPY_UBOOT=false
|
||||
# =============================================================================
|
||||
|
||||
# Default URL for image-info.json
|
||||
DEFAULT_JSON_URL="https://github.armbian.com/image-info.json"
|
||||
JSON_FILE="${1:-image-info.json}"
|
||||
|
||||
SRC_DIR="${SRC_DIR:-./in}"
|
||||
DST_DIR="${DST_DIR:-./out}"
|
||||
|
||||
SELECT="${SELECT:-}"
|
||||
INCLUDE_LIBC_DEV="${INCLUDE_LIBC_DEV:-false}"
|
||||
DRY_RUN="${DRY_RUN:-false}"
|
||||
|
||||
COPY_UBOOT="${COPY_UBOOT:-true}"
|
||||
UBOOT_SELECT="${UBOOT_SELECT:-}"
|
||||
|
||||
die() { echo "ERROR: $*" >&2; exit 1; }
|
||||
|
||||
# Fetch JSON from URL if file doesn't exist
|
||||
if [[ ! -f "$JSON_FILE" ]]; then
|
||||
if [[ "$JSON_FILE" == "http://"* ]] || [[ "$JSON_FILE" == "https://"* ]]; then
|
||||
# JSON parameter is a URL, download it
|
||||
echo "Downloading JSON from: $JSON_FILE"
|
||||
curl -fsSL "$JSON_FILE" -o image-info.json || die "Failed to download JSON from $JSON_FILE"
|
||||
JSON_FILE="image-info.json"
|
||||
else
|
||||
# Try to download from default URL
|
||||
echo "JSON file not found: $JSON_FILE"
|
||||
echo "Attempting to download from: $DEFAULT_JSON_URL"
|
||||
# Ensure target directory exists
|
||||
JSON_DIR=$(dirname "$JSON_FILE")
|
||||
[[ -n "$JSON_DIR" ]] && mkdir -p "$JSON_DIR"
|
||||
curl -fsSL "$DEFAULT_JSON_URL" -o "$JSON_FILE" || die "Failed to download JSON from $DEFAULT_JSON_URL"
|
||||
echo "Downloaded successfully to: $JSON_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
[[ -f "$JSON_FILE" ]] || die "JSON not found: $JSON_FILE"
|
||||
[[ -d "$SRC_DIR" ]] || die "SRC_DIR not found: $SRC_DIR"
|
||||
mkdir -p "$DST_DIR"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Expand JSON to triplets (board, linuxfamily, branch)
|
||||
# -----------------------------------------------------------------------------
|
||||
JQ_EXPAND='
|
||||
def norm_branches:
|
||||
if . == null then []
|
||||
elif (type=="string") then ( gsub("[,\\s]+";" ") | split(" ") | map(select(length>0)) )
|
||||
elif (type=="array") then ( map(tostring) | map(select(length>0)) )
|
||||
else [] end;
|
||||
|
||||
[
|
||||
.[]
|
||||
| {
|
||||
board: (.out.HOST // .in.inventory.BOARD // ""),
|
||||
linuxfamily: (.out.LINUXFAMILY // .in.inventory.BOARDFAMILY // ""),
|
||||
branches: ((.in.inventory.BOARD_POSSIBLE_BRANCHES
|
||||
// .in.inventory.BOARD_TOP_LEVEL_VARS.BOARD_POSSIBLE_BRANCHES)
|
||||
| norm_branches)
|
||||
}
|
||||
| select((.board|length>0) and (.linuxfamily|length>0) and (.branches|length>0))
|
||||
| . as $o
|
||||
| $o.branches[]
|
||||
| { board: $o.board, linuxfamily: $o.linuxfamily, branch: . }
|
||||
]
|
||||
| unique_by([.linuxfamily,.branch,.board])
|
||||
| sort_by(.board, .branch, .linuxfamily)
|
||||
| group_by([.board,.branch]) | map(.[0])
|
||||
'
|
||||
|
||||
# Kernel pairs: dedupe boards for same (linuxfamily,branch)
|
||||
JQ_KERNEL_PAIRS="$JQ_EXPAND"'
|
||||
| sort_by(.linuxfamily, .branch, .board)
|
||||
| group_by([.linuxfamily,.branch]) | map(.[0])
|
||||
| map([.linuxfamily, .branch] | @tsv)
|
||||
| .[]
|
||||
'
|
||||
|
||||
# U-Boot triplets: keep all boards
|
||||
JQ_UBOOT_TRIPLETS="$JQ_EXPAND"'
|
||||
| map([.board, .branch] | @tsv)
|
||||
| .[]
|
||||
'
|
||||
|
||||
mapfile -t KERNEL_PAIRS < <(jq -r "$JQ_KERNEL_PAIRS" "$JSON_FILE" | sort -u)
|
||||
mapfile -t UBOOT_TRIPLETS < <(jq -r "$JQ_UBOOT_TRIPLETS" "$JSON_FILE" | sort -u)
|
||||
|
||||
[[ ${#KERNEL_PAIRS[@]} -gt 0 ]] || die "No kernel pairs found"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Selection helpers (IMPORTANT: local IFS includes space)
|
||||
# -----------------------------------------------------------------------------
|
||||
pair_selected() {
|
||||
local fam="$1" br="$2"
|
||||
local token sf sb
|
||||
local -a tokens=()
|
||||
|
||||
[[ -z "${SELECT:-}" ]] && return 0
|
||||
|
||||
# Split SELECT on spaces/newlines/tabs regardless of global IFS
|
||||
IFS=$' \n\t' read -r -a tokens <<< "${SELECT}"
|
||||
|
||||
for token in "${tokens[@]}"; do
|
||||
[[ -z "$token" ]] && continue
|
||||
|
||||
if [[ "$token" == *:* ]]; then
|
||||
sf="${token%%:*}"
|
||||
sb="${token#*:}"
|
||||
[[ -z "$sf" ]] && sf="*"
|
||||
[[ -z "$sb" ]] && sb="*"
|
||||
else
|
||||
sf="$token"
|
||||
sb="*"
|
||||
fi
|
||||
|
||||
# IMPORTANT: pattern side must be unquoted to enable glob matching (*)
|
||||
if [[ $fam == $sf && $br == $sb ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
uboot_selected() {
|
||||
local board="$1" br="$2"
|
||||
local token sb sbr
|
||||
local -a tokens=()
|
||||
|
||||
[[ -z "${UBOOT_SELECT:-}" ]] && return 0
|
||||
[[ "${UBOOT_SELECT}" == "*" ]] && return 0
|
||||
|
||||
# Split on spaces/newlines/tabs regardless of global IFS
|
||||
IFS=$' \n\t' read -r -a tokens <<< "${UBOOT_SELECT}"
|
||||
|
||||
for token in "${tokens[@]}"; do
|
||||
[[ -z "$token" ]] && continue
|
||||
|
||||
if [[ "$token" == *:* ]]; then
|
||||
sb="${token%%:*}"
|
||||
sbr="${token#*:}"
|
||||
[[ -z "$sb" ]] && sb="*"
|
||||
[[ -z "$sbr" ]] && sbr="*"
|
||||
else
|
||||
sb="$token"
|
||||
sbr="*"
|
||||
fi
|
||||
|
||||
# IMPORTANT: unquoted to enable glob matching
|
||||
if [[ $board == $sb && $br == $sbr ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copy helpers
|
||||
# -----------------------------------------------------------------------------
|
||||
shopt -s nullglob
|
||||
|
||||
copy_flat() {
|
||||
local glob="$1"
|
||||
local files=( $glob )
|
||||
|
||||
[[ ${#files[@]} -eq 0 ]] && { echo " MISSING: $(basename "$glob")"; return 1; }
|
||||
|
||||
for f in "${files[@]}"; do
|
||||
if [[ "$DRY_RUN" == "true" ]]; then
|
||||
echo " WOULD COPY: $(basename "$f")"
|
||||
else
|
||||
cp -a "$f" "$DST_DIR/"
|
||||
echo " COPIED: $(basename "$f")"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
copy_recursive() {
|
||||
local pat="$1"
|
||||
local files=()
|
||||
|
||||
while IFS= read -r -d '' f; do files+=("$f"); done < <(
|
||||
find "$SRC_DIR" -type f -name "$pat" -print0 2>/dev/null || true
|
||||
)
|
||||
|
||||
[[ ${#files[@]} -eq 0 ]] && { echo " MISSING: $pat"; return 1; }
|
||||
|
||||
for f in "${files[@]}"; do
|
||||
if [[ "$DRY_RUN" == "true" ]]; then
|
||||
echo " WOULD COPY: $(basename "$f")"
|
||||
else
|
||||
cp -a "$f" "$DST_DIR/"
|
||||
echo " COPIED: $(basename "$f")"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Main
|
||||
# -----------------------------------------------------------------------------
|
||||
copied=0
|
||||
missing=0
|
||||
selected_pairs=0
|
||||
|
||||
declare -A selected_pairs_set=()
|
||||
|
||||
echo "JSON: $JSON_FILE"
|
||||
echo "SRC_DIR: $SRC_DIR"
|
||||
echo "DST_DIR: $DST_DIR"
|
||||
echo "SELECT: ${SELECT:-<all>}"
|
||||
echo "COPY_UBOOT: $COPY_UBOOT"
|
||||
echo "UBOOT_SELECT: ${UBOOT_SELECT:-<from kernels>}"
|
||||
echo "DRY_RUN: $DRY_RUN"
|
||||
echo
|
||||
|
||||
# Kernels
|
||||
for line in "${KERNEL_PAIRS[@]}"; do
|
||||
fam="${line%%$'\t'*}"
|
||||
br="${line#*$'\t'}"
|
||||
|
||||
pair_selected "$fam" "$br" || continue
|
||||
|
||||
selected_pairs=$((selected_pairs+1))
|
||||
selected_pairs_set["$fam:$br"]=1
|
||||
|
||||
echo "== Pair: linuxfamily=$fam branch=$br =="
|
||||
|
||||
for p in linux-image linux-dtb linux-headers; do
|
||||
copy_flat "$SRC_DIR/${p}-${br}-${fam}_*.deb" && copied=$((copied+1)) || missing=$((missing+1))
|
||||
done
|
||||
|
||||
if [[ "$INCLUDE_LIBC_DEV" == "true" ]]; then
|
||||
copy_flat "$SRC_DIR/linux-libc-dev-${br}-${fam}_*.deb" && copied=$((copied+1)) || missing=$((missing+1))
|
||||
fi
|
||||
|
||||
echo
|
||||
done
|
||||
|
||||
[[ $selected_pairs -gt 0 ]] || die "No kernel pairs selected"
|
||||
|
||||
# U-Boot
|
||||
if [[ "$COPY_UBOOT" == "true" ]]; then
|
||||
echo "== U-Boot packages =="
|
||||
|
||||
for line in "${UBOOT_TRIPLETS[@]}"; do
|
||||
board="${line%%$'\t'*}"
|
||||
br="${line#*$'\t'}"
|
||||
|
||||
uboot_selected "$board" "$br" || continue
|
||||
|
||||
echo "-- board=$board branch=$br --"
|
||||
copy_recursive "linux-u-boot-${board}-${br}_*.deb" \
|
||||
&& copied=$((copied+1)) || missing=$((missing+1))
|
||||
done
|
||||
echo
|
||||
fi
|
||||
|
||||
echo "Done."
|
||||
echo "Selected (linuxfamily,branch) pairs: $selected_pairs"
|
||||
echo "Matched file groups: $copied"
|
||||
echo "Missing patterns: $missing"
|
||||
Reference in New Issue
Block a user