X-Git-Url: https://pd.if.org/git/?p=zpackage;a=blobdiff_plain;f=bin%2Fzpm-gc;fp=bin%2Fzpm-gc;h=fdf8088b8c1abafa3f695b7b3ef30a0f7f23f996;hp=0000000000000000000000000000000000000000;hb=0419c62f964b259df1c1816f5870ef62eb97ed7c;hpb=0c2216d1e0dc8565a6bf61c9572e47bb1ae1c1fb diff --git a/bin/zpm-gc b/bin/zpm-gc new file mode 100755 index 0000000..fdf8088 --- /dev/null +++ b/bin/zpm-gc @@ -0,0 +1,160 @@ +#!/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 + +# removes old packages +zpm shell local.db.rehash "select package||'-'||version||'-'||release from package_age where age > 2 and status = 'updated'"|xargs -n1 zpm rmpackage -S installed -f local.db.rehash + +select +EL.file, PF.path, +PF.package || '-' || PF.version || '-' || PF.release as pkgid +from elfneeded EL +left join files F on F.hash = EL.file +left join packagefiles PF on PF.hash = EL.file +where F.hash is null +and EL.file is not null +and PF.path is not null +; + + +# remove failed packages +for pkg in $(zpm list -s failed); do + zpm rmpackage -m 'gc removed failed' "$pkg" + echo removed failed $pkg +done + +for pkg in $(zpm list -s dryrun); do + zpm rmpackage -m 'gc removed dryrun' "$pkg" + echo removed dryrun $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 incomplete $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 old package $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