365 lines
12 KiB
Bash
Executable File
365 lines
12 KiB
Bash
Executable File
#!/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 "<thead><tr><td colspan=3><h2>$release</h2></tr><tr><th>Main</th><th>Utils</th><th>Desktop</th></tr></thead>"
|
|
echo "<tbody><tr><td width=33% valing=top>"
|
|
aptly repo show -with-packages -config="${CONFIG}" "${release}" | tail -n +7 | sed 's/.*/&<br>/'
|
|
echo "</td><td width=33% valign=top>" | sudo tee -a ${filename}
|
|
aptly repo show -with-packages -config="${CONFIG}" "${release}-utils" | tail -n +7 | sed 's/.*/&<br>/'
|
|
echo "</td><td width=33% valign=top>" | sudo tee -a ${filename}
|
|
aptly repo show -with-packages -config="${CONFIG}" "${release}-desktop" | tail -n +7 | sed 's/.*/&<br>/'
|
|
echo "</td></tr></tbody>"
|
|
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) <https://mit-license.org/>
|
|
|
|
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
|