#!/usr/bin/env bash # Adding package # # @arg $1 string component # @arg $2 string incoming folder # @arg $3 string description # @arg $4 input folder # adding_packages() { # add deb files to repository if they are not already there for f in "${4}${2}"/*.deb; do local package name version arch # read package package=$(dpkg-deb -I "${f}") name=$(echo "${package}" | awk /Package/'{print $2}') version=$(echo "${package}" | awk /Version/'{print $2}') arch=$(echo "${package}" | awk /Architecture/'{print $2}') # add if not already there aptly repo search -architectures="${arch}" -config="${CONFIG}" "${1}" \ 'Name (% '${name}'), $Version (='${version}'), $Architecture (='${arch}')' &> /dev/null if [[ $? -ne 0 ]]; then echo -e "Checking and adding \x1B[92m$name\x1B[0m to repository \x1B[92m$release $3\x1B[0m" aptly repo add -force-replace=true -config="${CONFIG}" "${1}" "${f}" &> /dev/null fi done } fake_package() { fake_package_dir=$2 tmp_dir=$(mktemp -d) mkdir -p "${tmp_dir}/${fake_package_dir}"/DEBIAN/ # set up control file cat <<- END > "${tmp_dir}/${fake_package_dir}"/DEBIAN/control Package: empty Version: $3 Architecture: all Description: Fake pacakge Maintainer: Armbian END dpkg-deb --build "${tmp_dir}/${fake_package_dir}" &> /dev/null aptly repo add -force-replace=true -config="${CONFIG}" "${1}" "${tmp_dir}/${fake_package_dir}" &> /dev/null } # publishing repository # # $1: Input folder # $2: Output folder # $3: Command # $4: GPG password # $5: jammy,sid # publishing() { # read comma delimited distros into array IFS=', ' read -r -a DISTROS <<< "$5" local errors=0 # publish all, update selected local distributions=($(grep -rw config/distributions/*/support -ve 'eos' | cut -d"/" -f3)) #local distributions=("jessy" "xenial" "stretch" "bionic" "focal" "hirsute" "impish" "jammy" "lunar" "kinetic" "buster" "bullseye" "bookworm" "sid") for release in "${distributions[@]}"; do local forceoverwrite="" ADDING_PACKAGES="false" # shellcheck disable=SC2207,2199 [[ " ${DISTROS[@]} " =~ " ${release} " ]] && ADDING_PACKAGES="true" # let's drop from publish if exits if [[ -n $(aptly publish list -config="${CONFIG}" -raw | awk '{print $(NF)}' | grep "${release}") ]]; then aptly publish drop -config="${CONFIG}" "${release}" > /dev/null 2>&1 fi # create local repository if not exist if [[ -z $(aptly repo list -config="${CONFIG}" -raw | awk '{print $(NF)}' | grep "${release}") ]]; then aptly repo create -config="${CONFIG}" -distribution="${release}" \ -component="main,${release}-utils,${release}-desktop" -comment="Armbian main repository" "${release}" > /dev/null 2>&1 fake_package "${release}" test 1234 fi if [[ -z $(aptly repo list -config="${CONFIG}" -raw | awk '{print $(NF)}' | grep "${release}-utils") ]]; then aptly repo create -config="${CONFIG}" -distribution="${release}" \ -component="${release}-utils" -comment="Armbian ${release} utilities" "${release}-utils" > /dev/null 2>&1 fake_package "${release}" test 1234 fi if [[ -z $(aptly repo list -config="${CONFIG}" -raw | awk '{print $(NF)}' | grep "${release}-desktop") ]]; then aptly repo create -config="${CONFIG}" -distribution="${release}" \ -component="${release}-desktop" -comment="Armbian ${release} desktop" "${release}-desktop" > /dev/null 2>&1 fake_package "${release}" test 1234 fi # adding main if find "$1"/ -maxdepth 1 -type f -name "*.deb" 2> /dev/null | grep -q .; then [[ "${ADDING_PACKAGES}" == true ]] && adding_packages "$release" "" "main" "$1" fi local COMPONENTS="main" # adding release-specific main if find "${1}/${release}" -maxdepth 1 -type f -name "*.deb" 2> /dev/null | grep -q .; then [[ "${ADDING_PACKAGES}" == true ]] && adding_packages "${release}" "/${release}" "release packages" "$1" fi # adding release-specific utils if find "${1}/extra/${release}-utils" -maxdepth 1 -type f -name "*.deb" 2> /dev/null | grep -q .; then [[ "${ADDING_PACKAGES}" == true ]] && adding_packages "${release}-utils" "/extra/${release}-utils" "release utils" "$1" fi COMPONENTS="${COMPONENTS} ${release}-utils" # adding release-specific desktop if find "${1}/extra/${release}-desktop" -maxdepth 1 -type f -name "*.deb" 2> /dev/null | grep -q .; then [[ "${ADDING_PACKAGES}" == true ]] && adding_packages "${release}-desktop" "/extra/${release}-desktop" "desktop" "$1" fi COMPONENTS="${COMPONENTS} ${release}-desktop" local mainnum utilnum desknum mainnum=$(aptly repo show -with-packages -config="${CONFIG}" "${release}" | grep "Number of packages" | awk '{print $NF}') utilnum=$(aptly repo show -with-packages -config="${CONFIG}" "${release}-desktop" | grep "Number of packages" | awk '{print $NF}') desknum=$(aptly repo show -with-packages -config="${CONFIG}" "${release}-utils" | grep "Number of packages" | awk '{print $NF}') #if [ $mainnum -gt 0 ] && [ $utilnum -gt 0 ] && [ $desknum -gt 0 ]; then # write repo sync control file mkdir -p ${2}/public/ sudo date +%s > ${2}/public/control # publish echo "Publishing ${release}" aptly publish \ -acquire-by-hash \ -architectures="armhf,arm64,amd64,riscv64,i386,all" \ -passphrase="${4}" \ -origin="Armbian" \ -label="Armbian" \ -config="${CONFIG}" \ -component="${COMPONENTS// /,}" \ -distribution="${release}" repo "${release}" ${COMPONENTS//main/} > /dev/null if [[ $? -ne 0 ]]; then echo "Publishing failed ${release}" errors=$((errors + 1)) exit 0 fi #else # errors=$((errors + 1)) # local err_txt=": All components must be present: main, utils and desktop for first build" #fi done # cleanup aptly db cleanup -config="${CONFIG}" > /dev/null # key mkdir -p "${2}"/public/ cp config/armbian.key "${2}"/public/ # display what we have (aptly repo list -config="${CONFIG}") | grep -E packages # remove debs if no errors found if [[ $errors -eq 0 ]]; then echo "Purging incoming debs" sudo find "${1}" -name "*.deb" -type f -delete else echo "There were some problems $err_txt - leaving incoming directory intact" "err" fi } # # $1: Input folder # $2: Output folder # $3: Command # $4: GPG password # $5: jammy,sid # $6: list of packages to delete repo-manipulate() { # read comma delimited distros into array IFS=', ' read -r -a DISTROS <<< "$5" case $3 in serve) sudo aptly serve -listen=$(ip -f inet addr | grep -Po 'inet \K[\d.]+' | grep -v 127.0.0.1 | head -1):80 -config="${CONFIG}" return 0 ;; html) cat tools/repository/header.html for release in "${DISTROS[@]}"; do echo "

$release

MainUtilsDesktop" echo "" aptly repo show -with-packages -config="${CONFIG}" "${release}" | tail -n +7 | sed 's/.*/&
/' echo "" | sudo tee -a ${filename} aptly repo show -with-packages -config="${CONFIG}" "${release}-utils" | tail -n +7 | sed 's/.*/&
/' echo "" | sudo tee -a ${filename} aptly repo show -with-packages -config="${CONFIG}" "${release}-desktop" | tail -n +7 | sed 's/.*/&
/' echo "" done cat tools/repository/footer.html return 0 ;; delete) for release in "${DISTROS[@]}"; do echo "Deleting $6 from $release" aptly -config="${CONFIG}" repo remove "${release}" "$6" echo "Deleting $6 from $release-utils" aptly -config="${CONFIG}" repo remove "${release}-utils" "$6" echo "Deleting $6 from $release-desktop" aptly -config="${CONFIG}" repo remove "${release}-desktop" "$6" done return 0 ;; show) for release in "${DISTROS[@]}"; do echo "Displaying repository contents for $release" aptly repo show -with-packages -config="${CONFIG}" "${release}" | tail -n +7 echo "Displaying repository contents for $release-utils" aptly repo show -with-packages -config="${CONFIG}" "${release}-utils" | tail -n +7 echo "Displaying repository contents for $release-desktop" aptly repo show -with-packages -config="${CONFIG}" "${release}-desktop" | tail -n +7 done return 0 ;; unique) # which package should be removed from all repositories IFS=$'\n' while true; do LIST=() for release in "${DISTROS[@]}"; do LIST+=($(aptly repo show -with-packages -config="${CONFIG}" "${release}" | tail -n +7)) LIST+=($(aptly repo show -with-packages -config="${CONFIG}" "${release}-utils" | tail -n +7)) LIST+=($(aptly repo show -with-packages -config="${CONFIG}" "${release}-desktop" | tail -n +7)) done LIST=($(echo "${LIST[@]}" | tr ' ' '\n' | sort -u)) new_list=() # create a human readable menu for ((n = 0; n < $((${#LIST[@]})); n++)); do new_list+=("${LIST[$n]}") new_list+=("") done LIST=("${new_list[@]}") LIST_LENGTH=$((${#LIST[@]} / 2)) exec 3>&1 TARGET_VERSION=$(dialog --cancel-label "Cancel" --backtitle "BACKTITLE" --no-collapse --title \ "Remove packages from repositories" --clear --menu "Delete" $((9 + LIST_LENGTH)) 82 65 "${LIST[@]}" 2>&1 1>&3) exitstatus=$? exec 3>&- if [[ $exitstatus -eq 0 ]]; then for release in "${DISTROS[@]}"; do aptly repo remove -config="${CONFIG}" "${release}" "$TARGET_VERSION" aptly repo remove -config="${CONFIG}" "${release}-utils" "$TARGET_VERSION" aptly repo remove -config="${CONFIG}" "${release}-desktop" "$TARGET_VERSION" done else return 1 fi aptly db cleanup -config="${CONFIG}" > /dev/null 2>&1 # remove empty folders find $2/public -type d -empty -print -exec rm -rf {} \; done ;; update) publishing "$1" "$2" "$3" "$4" "$5" ;; *) echo -e "Unknown command" return 1 ;; esac } # defaults input="output/debs-beta" output="output/repository" command="show" releases="jammy,lunar,buster,bullseye,bookworm,sid" help() { echo "Armbian wrapper for Aptly v1.0 (c) Igor Pecovnik, igor@armbian.com License: (MIT) Usage: $0 [ -short | --long ] -h --help displays this -i --input [input folder] -o --output [output folder] -p --password [GPG password] -r --repository [jammy,sid,bullseye,...] -l --list [\"Name (% linux*)|armbian-config\"] -c --command [show] displays packages in each repository [html] displays packages in each repository in html form [serve] serve repository - useful for local diagnostics [unique] manually select which package should be removed from all repositories [update] search for packages in input folder [delete] delete package from -l LIST of packages " exit 2 } SHORT=i:,l:,o:,c:,p:,r:,h LONG=input:,list:,output:,command:,password:,releases:,help OPTS=$(getopt -a -n repo --options $SHORT --longoptions $LONG -- "$@") VALID_ARGUMENTS=$# # Returns the count of arguments that are in short or long options eval set -- "$OPTS" while : do case "$1" in -i | --input ) input="$2" shift 2 ;; -o | --output ) output="$2" shift 2 ;; -c | --command ) command="$2" shift 2 ;; -p | --password ) password="$2" shift 2 ;; -r | --releases ) releases="$2" shift 2 ;; -l | --list ) list="$2" shift 2 ;; -h | --help) help ;; --) shift; break ;; *) echo "Unexpected option: $1" help ;; esac done # redefine output folder in Aptly TempDir="$(mktemp -d || exit 1)" sed 's|"rootDir": ".*"|"rootDir": "'$output'"|g' tools/repository/aptly.conf > "${TempDir}"/aptly.conf CONFIG="${TempDir}/aptly.conf" # main repo-manipulate "$input" "$output" "$command" "$password" "$releases" "$list" RETURN=$? exit $RETURN