#!/bin/sh set -e # garbage collect a package database # flags to skip phases # -C clear all phases # -n dry run # -a all phases # default is failed packages, orphaned elf, vacuum # # only affect files with the status in the list status= # phases # -cC remove command history by date remove_command_history= # -dD remove dry run remove_dry_run=1 # -eE remove orphaned elf remove_orphaned_elf=1 # -fF remove failed remove_failed=1 # -hH fix file content hash remove_incomplete_packages=0 fix_hash=0 # -hH remove install history by date remove_history= # -lL remove old logs, given by date remove_logs= # -nN remove acked notes remove_acked_notes=0 # -pP remove history for missing packages clean_missing_package_history=0 # -hH remove all file content that is not scripts or configs remove_packagefile_content=1 remove_script_content=1 remove_config_content=1 # -rR remove removed packages, unless preserved remove_removed_packages=0 # -vV compactify the database file vacuum=0 # remove orphaned rows in files table packagefiles, notes, scripts, ... unreferenced_file_content=1 # remove outdated packages, unless preserved remove_old_packages=1 db=${ZPMDB:-/var/lib/zpm/local.db} retain_old=${ZPM_KEEP_PACKAGES:-2} while getopts 'f:PcCk:' opt; do case $opt in f) db="$OPTARG" ;; P) remove_old_packages=0 ;; c) vacuum=1 ;; C) unreferenced_file_content=0 ;; k) retain_old="$OPTARG" ;; esac done retain_old=$((retain_old + 0)) if [ $retain_old -le 0 ]; then retain_old=0 fi if [ -z "$db" ]; then echo must specify database file exit 1 fi ZPMDB=$db export ZPMDB # check for incorrect hash file content # remove orphaned elf info # remove failed packages for pkg in $(zpm list -s failed); do zpm rmpackage -m 'gc removed failed' "$pkg" echo removed $pkg done for pkg in $(zpm list -s dryrun); do zpm rmpackage -m 'gc removed dryrun' "$pkg" echo removed $pkg done # remove incomplete packages # TODO use temporary gc delete log trigger? if [ $remove_incomplete_packages -ne 0 ]; then for pkg in $(zpm list -F 'hash is null'); do zpm rmpackage -m 'gc removed incomplete' $pkg echo removed $pkg done fi # remove old version packages, unless preserved # remove removed packages, unless preserved if [ $remove_old_packages -ne 0 ]; then zpm shell $ZPMDB "select printf('%s-%s-%s',package,version,release) from package_age where age > $retain_old" | while read pkg; do zpm rmpackage -m 'gc removed old package' $pkg echo removed $pkg done fi # remove orphaned rows in files table # references in packagefiles, notes, scripts, possibly others if [ $remove_orphaned_files -ne 0 ]; then count=$(zpm shell $ZPMDB 'delete from files where hash in (select hash from filerefs where refcount = 0);select changes()') if [ $count -gt 0 ]; then zpm log -v -i -a 'gc' -t $ZPMDB "removed $count unreferenced content" fi fi # remove old logs, given by date # remove acked notes if [ $remove_acked_notes -ne 0 ]; then zpm shell $ZPMDB 'delete from notes where ack != 0' fi # remove install history by date # remove history for missing packages if [ $clean_missing_package_history -ne 0 ]; then # delete from zpmlog where ? true fi # remove command history by date # compactify the database file if [ $vacuum -ne 0 ]; then osize=$(zpm stat -f '%s' $ZPMDB) zpm shell $ZPMDB vacuum nsize=$(zpm stat -f '%s' $ZPMDB) zpm log -v -i -a 'gc compacted' -t $ZPMDB "$osize -> $nsize" printf 'original size %s\n' $osize printf 'new size %s\n' $nsize fi