diff -r 333964c621f1 -r cb59d6afeb61 openpkg/rpmdb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/openpkg/rpmdb Tue Jan 06 23:40:39 2009 +0100 @@ -0,0 +1,430 @@ +#!@l_prefix@/lib/openpkg/bash +## +## rpmdb -- OpenPKG RPM Database Administration Utility +## Copyright (c) 2000-2007 OpenPKG Foundation e.V. +## Copyright (c) 2000-2007 Ralf S. Engelschall +## +## Permission to use, copy, modify, and distribute this software for +## any purpose with or without fee is hereby granted, provided that +## the above copyright notice and this permission notice appear in all +## copies. +## +## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED +## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR +## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +## SUCH DAMAGE. +## + +# program information +progname="rpmdb" + +# configuration defaults +help="" +prefix="@l_prefix@" +dbpath="" +rpm="" +musr="@l_musr@" +mgrp="@l_mgrp@" +mode="" +force=no +verbose=2 + +## +## PARSE COMMAND LINE +## + +# iterate over argument line +for opt +do + case $opt in + -*=*) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;; + *) arg='' ;; + esac + case $opt in + -h|--help ) help="Usage" ;; + -B|--build ) mode=build ;; + -R|--rebuild ) mode=rebuild ;; + -C|--cleanup ) mode=cleanup ;; + -F|--fixate ) mode=fixate ;; + -L|--list ) mode=list ;; + -f|--force ) force=yes ;; + -q|--quiet ) verbose=0 ;; + -v|--verbose ) verbose=`expr $verbose + 1` ;; + --prefix=* ) prefix=$arg ;; + --dbpath=* ) dbpath=$arg ;; + --rpm=* ) rpm=$arg ;; + --musr=* ) musr=$arg ;; + --mgrp=* ) mgrp=$arg ;; + * ) help="Invalid option \`$opt'"; break ;; + esac +done + +# makre sure exactly one run-time mode is specified +if [ ".$mode" = . ]; then + help="No or invalid run-time mode specified" +fi + +# error or usage message +if [ ".$help" != . ]; then + if [ ".$help" != ".Usage" ]; then + echo "$progname:ERROR: $help" 1>&2 + fi + cat 1>&2 <&2 + exit 1 +} + +warning () { + echo "$progname:WARNING: $*" 1>&2 +} + +verbose () { + local level=$1 + shift + if [ $level -le $verbose ]; then + local lead="" + case "$level" in + 1 ) lead="" ;; + 2 ) lead="" ;; + 3 ) lead=" " ;; + * ) lead=" " ;; + esac + echo "$progname: $lead$*" 1>&2 + fi +} + +rpm () { + local opts="--dbpath `echo $dbpath | sed -e 's;/*$;;' -e 's;$;/;'`" + if [ ".$force" = .yes ]; then + opts="$opts --define '__dbi_private yes'" + fi + verbose 3 "run: $rpm $opts $@" + eval "$rpm $opts \"\$@\"" +} + +rpmdb_load () { + $prefix/lib/openpkg/rpmdb_load ${1+"$@"} +} + +rpmdb_dump () { + $prefix/lib/openpkg/rpmdb_dump ${1+"$@"} +} + +## +## RPM DATABASE OPERATIONS +## + +db_wait () { + # wait until RPM has released the database in case we are called + # asynchronously to RPM (especially important when upgrading from + # RPM 4.0 where concurrent access is still not possible) + verbose 2 "waiting for RPM database to be available" + local i=0 + while [ $i -lt 10 ]; do + if $prefix/libexec/openpkg/rpm -q openpkg >/dev/null 2>&1; then + break + fi + sleep 1 + i=`expr $i + 1` + done + if [ $i -eq 10 ]; then + exit 1 + else + exit 0 + fi +} + +db_remove () { + # remove all known files + verbose 2 "removing (possibly existing) old RPM database DB files" + for dbfile in $dbfiles; do + eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` + verbose 3 "removing database file: $dbpath/$dbfile ($dbtype)" + rm -f $dbpath/$dbfile + done +} + +db_init () { + # perform official "initdb" operation + # (is mostly a no-operation in RPM 4.2, but anyway) + verbose 2 "creating new RPM database (built-in RPM procedure)" + rpm --initdb + + # perform some real RPM work, so more database files + # magically spring into existence + verbose 2 "operating on new RPM database" + rpm --import $prefix/etc/openpkg/openpkg.org.pgp || true + rpm -e gpg-pubkey-63c4cb9f-3c591eda --allmatches || true + + # perform official "rebuilddb" operation in the hope it + # creates even more database files now that we have some content + verbose 2 "rebuilding new RPM database (built-in RPM procedure)" + rpm --rebuilddb +} + +db_unbreak () { + # cleanup DB region files + verbose 2 "cleaning up RPM database DB region files" + for dbfile in $dbfiles; do + eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` + if [ ".$dbtype" = .region ]; then + verbose 3 "cleaning up DB file: $dbpath/$dbfile ($dbtype)" + rm -f $dbpath/$dbfile || true + touch $dbpath/$dbfile || true + fi + done +} + +db_extend () { + # make sure all RPM database DB files are present + verbose 2 "making sure RPM database contains all possible DB files" + for dbfile in $dbfiles; do + eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` + if [ ! -f $dbpath/$dbfile ]; then + verbose 3 "creating DB file: $dbpath/$dbfile ($dbtype)" + if [ ".$dbtype" = .hash -o ".$dbtype" = .btree ]; then + ( echo "VERSION=3" + echo "format=bytevalue" + echo "type=$dbtype" + echo "db_pagesize=16384" + echo "HEADER=END" + echo "DATA=END" + ) | rpmdb_load $dbpath/$dbfile || true + else + touch $dbpath/$dbfile || true + fi + fi + done +} + +db_reload () { + # rebuilding new from old RPM database DB files by dumping and + # reloading their entire content + verbose 2 "dumping and reloading RPM database DB file contents" + for dbfile in $dbfiles; do + eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` + verbose 3 "dumping and reloading DB file: $dbpath/$dbfile ($dbtype)" + if [ -f $dbpath/$dbfile ]; then + if [ ".$dbtype" = .hash -o ".$dbtype" = .btree ]; then + rpmdb_dump $dbpath/$dbfile |\ + rpmdb_load $dbpath/$dbfile.new + rm -f $dbpath/$dbfile + mv $dbpath/$dbfile.new $dbpath/$dbfile + else + rm -f $dbpath/$dbfile || true + touch $dbpath/$dbfile || true + fi + fi + done +} + +db_rebuild () { + # perform official "rebuilddb" operation + verbose 2 "rebuilding RPM database (built-in RPM procedure)" + rpm --rebuilddb +} + +db_operate () { + # perform some read/write operation on RPM database + # (we have no package available, but removing and reimporting + # the OpenPKG OpenPGP keys is a harmless thing and always possible) + verbose 2 "performing read/write operation on RPM database" + for spec in \ + openpkg.org.pgp:gpg-pubkey-63c4cb9f-3c591eda \ + openpkg.com.pgp:gpg-pubkey-61b7ae34-4544a6af \ + openpkg.net.pgp:gpg-pubkey-52197903-4544a74d \ + ; do + eval `echo "$spec" | sed -e 's/^\(.*\):\(.*\)$/file="\1"; package="\2"/'` + rpm -q $package >/dev/null 2>&1 && rpm -e $package --allmatches || true + rpm -q $package >/dev/null 2>&1 || rpm --import $prefix/etc/openpkg/$file || true + done + rpm -qa >/dev/null 2>&1 +} + +db_fixate () { + # fix ownership and permissions of (especially newly created) + # RPM database files to make sure they are consistent + verbose 2 "making sure RPM database files have consistent attributes" + for dbfile in $dbfiles; do + eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` + verbose 3 "fixating DB file: $dbpath/$dbfile ($dbtype)" + chown $musr:$mgrp $dbpath/$dbfile 2>/dev/null || true + chmod 644 $dbpath/$dbfile 2>/dev/null || true + done +} + +db_list () { + # list all database files + for dbfile in $dbfiles; do + eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` + if [ $verbose -eq 0 ]; then + echo "$dbfile" + elif [ $verbose -eq 1 ]; then + echo "$dbpath/$dbfile" + elif [ $verbose -ge 2 ]; then + echo "$dbpath/$dbfile ($dbtype)" + fi + done +} + +## +## ENVIRONMENT CONSISTENCY CHECKS +## + +# sanity check OpenPKG instance +if [ ".$prefix" = . ]; then + error "OpenPKG instance directory is empty" +fi +if [ ! -d $prefix ]; then + error "OpenPKG instance directory \"$prefix\" not found" +fi +if [ ! -x $prefix/bin/openpkg ]; then + error "OpenPKG instance directory \"$prefix\" not valid" +fi + +# sanity check OpenPKG RPM database +if [ ".$dbpath" = . ]; then + error "OpenPKG RPM database directory is empty" +fi +if [ ! -d $dbpath ]; then + error "OpenPKG RPM database directory \"$dbpath\" not found" +fi +if [ ! -w $dbpath ]; then + error "OpenPKG RPM database directory \"$dbpath\" not writable" +fi + +## +## DISPATCH INTO COMMANDS +## + +case "$mode" in + build ) + verbose 1 "BUILDING NEW RPM DATABASE FROM SCRATCH ($dbpath)" + db_remove + db_init + db_extend + db_rebuild + db_fixate + db_operate + ;; + + rebuild ) + verbose 1 "REBUILDING NEW FROM OLD RPM DATABASE ($dbpath)" + db_unbreak + db_extend + db_reload + db_rebuild + db_fixate + db_operate + ;; + + cleanup ) + verbose 1 "CLEANING UP EXISTING RPM DATABASE ($dbpath)" + db_unbreak + db_extend + db_rebuild + db_fixate + db_operate + ;; + + fixate ) + verbose 1 "FIXATING EXISTING RPM DATABASE ($dbpath)" + db_extend + db_fixate + db_operate + ;; + + list ) + db_list + ;; +esac + +exit 0 +