Время от времени, после обновления основной системы, обновляются библиотеки и некоторые пакеты, собранные вручную ломаются. Ниже представлена небольшая задумка автоматической проверки таких пакетов после обновления.
Для начала сделаем скрипт, который будет пробегаться по пакетам, которых нет в репозиториях и применять к ним некоторый набор действий, который позволит понять, что пакет поломан.
Сам критерий простой: ldd на ELF файле и удостовериться, что нет вхождений ’not found'.
Кроме того, мы можем достаточно быстро проверить факт того, что пакет вообще был выброшен, если его нет ни в репозиториях, ни в AUR. К таким пакетам так же будут отнесены все пакеты, поставленные вручную локально.
Итак, для начала скрипт проверки ( aur-check):
#!/usr/bin/env bash
# Ref to the /etc/makepkg.conf PACKAGER
PACKAGE_USER="Alexander Drozdov"
set -e
export LANG=C
packages=$(pacman -Qmq)
orphaned=""
declare -A broken
declare -A distro
aur_info_cower() {
cower -iq --timeout=30 -- $packages | grep '^Name' | awk '{print $3}'
}
aur_info_auracle() {
auracle info -F '{name}' -- $packages
}
aur_info_yay_pacaur() {
$1 -Siq --aur -- $packages | grep '^Name' | awk '{print $3}'
}
aur_info_yay() {
aur_info_yay_pacaur yay
}
aur_info_pacaur() {
aur_info_yay_pacaur pacaur
}
aur_info_detect_backend() {
set +e
which auracle > /dev/null 2>&1 && aur_info_backend="auracle" && return
which cower > /dev/null 2>&1 && aur_info_backend="cower" && return
which yay > /dev/null 2>&1 && aur_info_backend="yay" && return
which pacaur > /dev/null 2>&1 && aur_info_backend="pacaur" && return
set -e
}
check_orphaned() {
list1=$(mktemp -p /tmp -u XXXXXXXX)
list2=$(mktemp -p /tmp -u XXXXXXXX)
trap "rm -f $list1 $list2" RETURN QUIT
pacman -Qmq > $list1
eval "aur_info_${aur_info_backend}" > $list2
orphaned=$(diff -u $list1 $list2 | grep '^-' | grep -v '^---' | sed 's|^-||')
}
# detect tool to ask AUR package info
aur_info_detect_backend
# Check for orphaned packages
[ -n "$aur_info_backend" ] && check_orphaned
# Check integrity
for pkg in $packages
do
echo " => $pkg"
# Check that package previously maintained by Distro
dist_check=$(pacman -Qi $pkg | grep '^Packager' | grep -v "$PACKAGE_USER\|Unknown Packager")
if [ -n "$dist_check" ]; then
distro[$pkg]=1
fi
# Basic check for package breaks, mostly call ldd for libs and binaries
files=$(pacman -Qlq $pkg)
for file in $files
do
# Check only executables and skip directories.
# Also, skip packages from /opt/ prefix, most of them is a
# binary distributed and need a LD_PRELOAD_PATH to be configured
# right
if [ -x "$file" -a "${file:0:5}" != "/opt/" ]; then
is_elf=$(file $file | grep ELF || true)
if [ -n "$is_elf" ]; then
# Apply check
tmp=$(mktemp /tmp/XXXXXXXXXXXXXXXXXX)
ldd "$file" > "$tmp" 2>&1 || true
is_broken=$(cat "$tmp" | grep '=> not found' || true)
if [ -n "$is_broken" ]; then
broken[$pkg]=1
echo " $file:"
cat "$tmp" | grep '=> not found' | ts ' '
fi
rm -f "$tmp"
fi
fi
done
done
if [ -n "$orphaned" ]; then
echo "Orphaned packages summary:"
for pkg in $orphaned
do
echo " $pkg"
done
fi
if [ ${#distro[@]} -gt 0 ]; then
echo "Previously maintained by the Distro summary:"
for pkg in ${!distro[*]}
do
echo " $pkg"
done
fi
if [ ${#broken[@]} -gt 0 ]; then
echo "Broken packages summary:"
for pkg in ${!broken[*]}
do
echo " $pkg"
done
fi
Поместите его в /usr/local/bin/
.
Будет определённое неудобство при недоступности сети, при проверке брошенных пакетов (запрос к AUR). Я думаю исправить это в будущем.
А теперь HOOK для libaplm
(
99-99-aur.hook):
# /usr/share/libalpm/hooks/99-99-aur.hook
# /etc/pacman.d/hooks/99-99-aur.hook
[Trigger]
Operation = Upgrade
Type = Package
Target = *
[Action]
Description = "Check non-repo packages integrity"
Depends = auracle
When = PostTransaction
Exec = /usr/local/bin/aur-check
Обратите внимание, я настроил запуск проверки только на операции обновления пакетов, так как установка дополнительного пакета не должна ломать существующие, а удаление должно корректно отследиться через механизм зависимостей. А если этого не произошло, то стоит обратить внимание разработчика пакета на эти нюансы.
Сам HOOK нужно положить в /etc/pacman.d/hooks/
(/usr/share/libalpm/hooks/
предназначен для установки хуков через пакетный менеджер).
Сам скрипт и хук оформил в виде GitHub Gist: AUR basic integrity check