openpkg/rpmdb

changeset 13
cb59d6afeb61
child 428
f880f219c566
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/openpkg/rpmdb	Tue Jan 06 23:40:39 2009 +0100
     1.3 @@ -0,0 +1,430 @@
     1.4 +#!@l_prefix@/lib/openpkg/bash
     1.5 +##
     1.6 +##  rpmdb -- OpenPKG RPM Database Administration Utility
     1.7 +##  Copyright (c) 2000-2007 OpenPKG Foundation e.V. <http://openpkg.net/>
     1.8 +##  Copyright (c) 2000-2007 Ralf S. Engelschall <http://engelschall.com/>
     1.9 +##
    1.10 +##  Permission to use, copy, modify, and distribute this software for
    1.11 +##  any purpose with or without fee is hereby granted, provided that
    1.12 +##  the above copyright notice and this permission notice appear in all
    1.13 +##  copies.
    1.14 +##
    1.15 +##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
    1.16 +##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    1.17 +##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    1.18 +##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
    1.19 +##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.20 +##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    1.21 +##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
    1.22 +##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    1.23 +##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    1.24 +##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    1.25 +##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    1.26 +##  SUCH DAMAGE.
    1.27 +##
    1.28 +
    1.29 +#   program information
    1.30 +progname="rpmdb"
    1.31 +
    1.32 +#   configuration defaults
    1.33 +help=""
    1.34 +prefix="@l_prefix@"
    1.35 +dbpath=""
    1.36 +rpm=""
    1.37 +musr="@l_musr@"
    1.38 +mgrp="@l_mgrp@"
    1.39 +mode=""
    1.40 +force=no
    1.41 +verbose=2
    1.42 +
    1.43 +##
    1.44 +##  PARSE COMMAND LINE
    1.45 +##
    1.46 +
    1.47 +#   iterate over argument line
    1.48 +for opt
    1.49 +do
    1.50 +    case $opt in
    1.51 +        -*=*) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;;
    1.52 +           *) arg='' ;;
    1.53 +    esac
    1.54 +    case $opt in
    1.55 +        -h|--help      ) help="Usage"  ;;
    1.56 +        -B|--build     ) mode=build    ;;
    1.57 +        -R|--rebuild   ) mode=rebuild  ;;
    1.58 +        -C|--cleanup   ) mode=cleanup  ;;
    1.59 +        -F|--fixate    ) mode=fixate   ;;
    1.60 +        -L|--list      ) mode=list     ;;
    1.61 +        -f|--force     ) force=yes     ;;
    1.62 +        -q|--quiet     ) verbose=0     ;;
    1.63 +        -v|--verbose   ) verbose=`expr $verbose + 1` ;;
    1.64 +        --prefix=*     ) prefix=$arg   ;;
    1.65 +        --dbpath=*     ) dbpath=$arg   ;;
    1.66 +        --rpm=*        ) rpm=$arg      ;;
    1.67 +        --musr=*       ) musr=$arg     ;;
    1.68 +        --mgrp=*       ) mgrp=$arg     ;;
    1.69 +        *              ) help="Invalid option \`$opt'"; break ;;
    1.70 +    esac
    1.71 +done
    1.72 +
    1.73 +#   makre sure exactly one run-time mode is specified
    1.74 +if [ ".$mode" = . ]; then
    1.75 +    help="No or invalid run-time mode specified"
    1.76 +fi
    1.77 +
    1.78 +#   error or usage message
    1.79 +if [ ".$help" != . ]; then
    1.80 +    if [ ".$help" != ".Usage" ]; then
    1.81 +        echo "$progname:ERROR: $help" 1>&2
    1.82 +    fi
    1.83 +    cat 1>&2 <<EOT
    1.84 +$progname:USAGE: $progname [options]
    1.85 +
    1.86 +  -h, --help        print usage message (this one)
    1.87 +  -B, --build       build new RPM database from scratch
    1.88 +  -R, --rebuild     rebuild new from old RPM database
    1.89 +  -C, --cleanup     cleanup existing RPM database
    1.90 +  -F, --fixate      fixate existing RPM database
    1.91 +  -L, --list        list all RPM database files
    1.92 +  -f, --force       operate in force mode (no save operations)
    1.93 +  -q, --quiet       operate in quiet mode (no verbose messages at all)
    1.94 +  -v, --verbose     operate in more verbose mode (increase verbose level)
    1.95 +  --prefix=PREFIX   use OpenPKG instance under PREFIX
    1.96 +  --dbpath=PATH     use OpenPKG RPM database under PATH
    1.97 +  --rpm=PROG        use OpenPKG RPM executable PROG
    1.98 +  --musr=USERNAME   use OpenPKG management user USERNAME
    1.99 +  --mgrp=GROUPNAME  use OpenPKG management group GROUPNAME
   1.100 +
   1.101 +This is OpenPKG rpmdb, an RPM database administration utility, providing
   1.102 +lower-level maintainance functions for the Berkeley-DB 4.1 based RPM 4.2
   1.103 +database. It allows building new RPM databases from scratch, rebuilding
   1.104 +a new from an old RPM database (content dumping and reloading),
   1.105 +cleaning up problems on an existing RPM database (removal of DB region
   1.106 +files, etc) and fixating the files in an existing RPM database (file
   1.107 +attributes).
   1.108 +
   1.109 +EOT
   1.110 +    if [ ".$help" != ".Usage" ]; then
   1.111 +        exit 2
   1.112 +    else
   1.113 +        exit 0
   1.114 +    fi
   1.115 +fi
   1.116 +
   1.117 +#   delayed determination of variables
   1.118 +if [ ".$dbpath" = . ]; then
   1.119 +    dbpath="$prefix/RPM/DB"
   1.120 +fi
   1.121 +if [ ".$rpm" = . ]; then
   1.122 +    rpm="$prefix/bin/openpkg rpm"
   1.123 +fi
   1.124 +
   1.125 +##
   1.126 +##  DATABASE FILE INFORMATION
   1.127 +##
   1.128 +
   1.129 +dbfiles="
   1.130 +    hash:Basenames
   1.131 +    hash:Conflictname
   1.132 +    hash:Depends
   1.133 +    btree:Dirnames
   1.134 +    hash:Filemd5s
   1.135 +    hash:Group
   1.136 +    btree:Installtid
   1.137 +    hash:Name
   1.138 +    hash:Packages
   1.139 +    hash:Providename
   1.140 +    btree:Provideversion
   1.141 +    hash:Pubkeys
   1.142 +    hash:Requirename
   1.143 +    btree:Requireversion
   1.144 +    hash:Sha1header
   1.145 +    hash:Sigmd5
   1.146 +    hash:Triggername
   1.147 +    region:__db.001
   1.148 +    region:__db.002
   1.149 +    region:__db.003
   1.150 +    region:__db.004
   1.151 +    region:__db.005
   1.152 +    region:__db.006
   1.153 +    region:__db.007
   1.154 +    region:__db.008
   1.155 +    region:__db.009
   1.156 +"
   1.157 +
   1.158 +##
   1.159 +##  HELPER FUNCTIONS
   1.160 +##
   1.161 +
   1.162 +error () {
   1.163 +    echo "$progname:ERROR: $*" 1>&2
   1.164 +    exit 1
   1.165 +}
   1.166 +
   1.167 +warning () {
   1.168 +    echo "$progname:WARNING: $*" 1>&2
   1.169 +}
   1.170 +
   1.171 +verbose () {
   1.172 +    local level=$1
   1.173 +    shift
   1.174 +    if [ $level -le $verbose ]; then
   1.175 +        local lead=""
   1.176 +        case "$level" in
   1.177 +            1 ) lead="" ;;
   1.178 +            2 ) lead="" ;;
   1.179 +            3 ) lead="  " ;;
   1.180 +            * ) lead="    " ;;
   1.181 +        esac
   1.182 +        echo "$progname: $lead$*" 1>&2
   1.183 +    fi
   1.184 +}
   1.185 +
   1.186 +rpm () {
   1.187 +    local opts="--dbpath `echo $dbpath | sed -e 's;/*$;;' -e 's;$;/;'`"
   1.188 +    if [ ".$force" = .yes ]; then
   1.189 +        opts="$opts --define '__dbi_private yes'"
   1.190 +    fi
   1.191 +    verbose 3 "run: $rpm $opts $@"
   1.192 +    eval "$rpm $opts \"\$@\""
   1.193 +}
   1.194 +
   1.195 +rpmdb_load () {
   1.196 +    $prefix/lib/openpkg/rpmdb_load ${1+"$@"}
   1.197 +}
   1.198 +
   1.199 +rpmdb_dump () {
   1.200 +    $prefix/lib/openpkg/rpmdb_dump ${1+"$@"}
   1.201 +}
   1.202 +
   1.203 +##
   1.204 +##  RPM DATABASE OPERATIONS
   1.205 +##
   1.206 +
   1.207 +db_wait () {
   1.208 +    #   wait until RPM has released the database in case we are called
   1.209 +    #   asynchronously to RPM (especially important when upgrading from
   1.210 +    #   RPM 4.0 where concurrent access is still not possible)
   1.211 +    verbose 2 "waiting for RPM database to be available"
   1.212 +    local i=0
   1.213 +    while [ $i -lt 10 ]; do
   1.214 +        if $prefix/libexec/openpkg/rpm -q openpkg >/dev/null 2>&1; then
   1.215 +            break
   1.216 +        fi
   1.217 +        sleep 1
   1.218 +        i=`expr $i + 1`
   1.219 +    done
   1.220 +    if [ $i -eq 10 ]; then
   1.221 +        exit 1
   1.222 +    else
   1.223 +        exit 0
   1.224 +    fi
   1.225 +}
   1.226 +
   1.227 +db_remove () {
   1.228 +    #   remove all known files
   1.229 +    verbose 2 "removing (possibly existing) old RPM database DB files"
   1.230 +    for dbfile in $dbfiles; do
   1.231 +        eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'`
   1.232 +        verbose 3 "removing database file: $dbpath/$dbfile ($dbtype)"
   1.233 +        rm -f $dbpath/$dbfile
   1.234 +    done
   1.235 +}
   1.236 +
   1.237 +db_init () {
   1.238 +    #   perform official "initdb" operation
   1.239 +    #   (is mostly a no-operation in RPM 4.2, but anyway)
   1.240 +    verbose 2 "creating new RPM database (built-in RPM procedure)"
   1.241 +    rpm --initdb
   1.242 +
   1.243 +    #   perform some real RPM work, so more database files
   1.244 +    #   magically spring into existence
   1.245 +    verbose 2 "operating on new RPM database"
   1.246 +    rpm --import $prefix/etc/openpkg/openpkg.org.pgp || true
   1.247 +    rpm -e gpg-pubkey-63c4cb9f-3c591eda --allmatches || true
   1.248 +
   1.249 +    #   perform official "rebuilddb" operation in the hope it
   1.250 +    #   creates even more database files now that we have some content
   1.251 +    verbose 2 "rebuilding new RPM database (built-in RPM procedure)"
   1.252 +    rpm --rebuilddb
   1.253 +}
   1.254 +
   1.255 +db_unbreak () {
   1.256 +    #   cleanup DB region files
   1.257 +    verbose 2 "cleaning up RPM database DB region files"
   1.258 +    for dbfile in $dbfiles; do
   1.259 +        eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'`
   1.260 +        if [ ".$dbtype" = .region ]; then
   1.261 +            verbose 3 "cleaning up DB file: $dbpath/$dbfile ($dbtype)"
   1.262 +            rm -f $dbpath/$dbfile || true
   1.263 +            touch $dbpath/$dbfile || true
   1.264 +        fi
   1.265 +    done
   1.266 +}
   1.267 +
   1.268 +db_extend () {
   1.269 +    #   make sure all RPM database DB files are present
   1.270 +    verbose 2 "making sure RPM database contains all possible DB files"
   1.271 +    for dbfile in $dbfiles; do
   1.272 +        eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'`
   1.273 +        if [ ! -f $dbpath/$dbfile ]; then
   1.274 +            verbose 3 "creating DB file: $dbpath/$dbfile ($dbtype)"
   1.275 +            if [ ".$dbtype" = .hash -o ".$dbtype" = .btree ]; then
   1.276 +                ( echo "VERSION=3"
   1.277 +                  echo "format=bytevalue"
   1.278 +                  echo "type=$dbtype"
   1.279 +                  echo "db_pagesize=16384"
   1.280 +                  echo "HEADER=END"
   1.281 +                  echo "DATA=END"
   1.282 +                ) | rpmdb_load $dbpath/$dbfile || true
   1.283 +            else
   1.284 +                touch $dbpath/$dbfile || true
   1.285 +            fi
   1.286 +        fi
   1.287 +    done
   1.288 +}
   1.289 +
   1.290 +db_reload () {
   1.291 +    #   rebuilding new from old RPM database DB files by dumping and
   1.292 +    #   reloading their entire content
   1.293 +    verbose 2 "dumping and reloading RPM database DB file contents"
   1.294 +    for dbfile in $dbfiles; do
   1.295 +        eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'`
   1.296 +        verbose 3 "dumping and reloading DB file: $dbpath/$dbfile ($dbtype)"
   1.297 +        if [ -f $dbpath/$dbfile ]; then
   1.298 +            if [ ".$dbtype" = .hash -o ".$dbtype" = .btree ]; then
   1.299 +                rpmdb_dump $dbpath/$dbfile |\
   1.300 +                rpmdb_load $dbpath/$dbfile.new
   1.301 +                rm -f $dbpath/$dbfile
   1.302 +                mv $dbpath/$dbfile.new $dbpath/$dbfile
   1.303 +            else
   1.304 +                rm -f $dbpath/$dbfile || true
   1.305 +                touch $dbpath/$dbfile || true
   1.306 +            fi
   1.307 +        fi
   1.308 +    done
   1.309 +}
   1.310 +
   1.311 +db_rebuild () {
   1.312 +    #   perform official "rebuilddb" operation
   1.313 +    verbose 2 "rebuilding RPM database (built-in RPM procedure)"
   1.314 +    rpm --rebuilddb
   1.315 +}
   1.316 +
   1.317 +db_operate () {
   1.318 +    #   perform some read/write operation on RPM database
   1.319 +    #   (we have no package available, but removing and reimporting
   1.320 +    #   the OpenPKG OpenPGP keys is a harmless thing and always possible)
   1.321 +    verbose 2 "performing read/write operation on RPM database"
   1.322 +    for spec in \
   1.323 +        openpkg.org.pgp:gpg-pubkey-63c4cb9f-3c591eda \
   1.324 +        openpkg.com.pgp:gpg-pubkey-61b7ae34-4544a6af \
   1.325 +        openpkg.net.pgp:gpg-pubkey-52197903-4544a74d \
   1.326 +    ; do
   1.327 +        eval `echo "$spec" | sed -e 's/^\(.*\):\(.*\)$/file="\1"; package="\2"/'`
   1.328 +        rpm -q $package >/dev/null 2>&1 && rpm -e $package --allmatches || true
   1.329 +        rpm -q $package >/dev/null 2>&1 || rpm --import $prefix/etc/openpkg/$file || true
   1.330 +    done
   1.331 +    rpm -qa >/dev/null 2>&1
   1.332 +}
   1.333 +
   1.334 +db_fixate () {
   1.335 +    #   fix ownership and permissions of (especially newly created)
   1.336 +    #   RPM database files to make sure they are consistent
   1.337 +    verbose 2 "making sure RPM database files have consistent attributes"
   1.338 +    for dbfile in $dbfiles; do
   1.339 +        eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'`
   1.340 +        verbose 3 "fixating DB file: $dbpath/$dbfile ($dbtype)"
   1.341 +        chown $musr:$mgrp $dbpath/$dbfile 2>/dev/null || true
   1.342 +        chmod 644 $dbpath/$dbfile 2>/dev/null || true
   1.343 +    done
   1.344 +}
   1.345 +
   1.346 +db_list () {
   1.347 +    #   list all database files
   1.348 +    for dbfile in $dbfiles; do
   1.349 +        eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'`
   1.350 +        if [ $verbose -eq 0 ]; then
   1.351 +            echo "$dbfile"
   1.352 +        elif [ $verbose -eq 1 ]; then
   1.353 +            echo "$dbpath/$dbfile"
   1.354 +        elif [ $verbose -ge 2 ]; then
   1.355 +            echo "$dbpath/$dbfile ($dbtype)"
   1.356 +        fi
   1.357 +    done
   1.358 +}
   1.359 +
   1.360 +##
   1.361 +##  ENVIRONMENT CONSISTENCY CHECKS
   1.362 +##
   1.363 +
   1.364 +#   sanity check OpenPKG instance
   1.365 +if [ ".$prefix" = . ]; then
   1.366 +    error "OpenPKG instance directory is empty"
   1.367 +fi
   1.368 +if [ ! -d $prefix ]; then
   1.369 +    error "OpenPKG instance directory \"$prefix\" not found"
   1.370 +fi
   1.371 +if [ ! -x $prefix/bin/openpkg ]; then
   1.372 +    error "OpenPKG instance directory \"$prefix\" not valid"
   1.373 +fi
   1.374 +
   1.375 +#   sanity check OpenPKG RPM database
   1.376 +if [ ".$dbpath" = . ]; then
   1.377 +    error "OpenPKG RPM database directory is empty"
   1.378 +fi
   1.379 +if [ ! -d $dbpath ]; then
   1.380 +    error "OpenPKG RPM database directory \"$dbpath\" not found"
   1.381 +fi
   1.382 +if [ ! -w $dbpath ]; then
   1.383 +    error "OpenPKG RPM database directory \"$dbpath\" not writable"
   1.384 +fi
   1.385 +
   1.386 +##
   1.387 +##  DISPATCH INTO COMMANDS
   1.388 +##
   1.389 +
   1.390 +case "$mode" in
   1.391 +    build )
   1.392 +        verbose 1 "BUILDING NEW RPM DATABASE FROM SCRATCH ($dbpath)"
   1.393 +        db_remove
   1.394 +        db_init
   1.395 +        db_extend
   1.396 +        db_rebuild
   1.397 +        db_fixate
   1.398 +        db_operate
   1.399 +        ;;
   1.400 +
   1.401 +    rebuild )
   1.402 +        verbose 1 "REBUILDING NEW FROM OLD RPM DATABASE ($dbpath)"
   1.403 +        db_unbreak
   1.404 +        db_extend
   1.405 +        db_reload
   1.406 +        db_rebuild
   1.407 +        db_fixate
   1.408 +        db_operate
   1.409 +        ;;
   1.410 +
   1.411 +    cleanup )
   1.412 +        verbose 1 "CLEANING UP EXISTING RPM DATABASE ($dbpath)"
   1.413 +        db_unbreak
   1.414 +        db_extend
   1.415 +        db_rebuild
   1.416 +        db_fixate
   1.417 +        db_operate
   1.418 +        ;;
   1.419 +
   1.420 +    fixate )
   1.421 +        verbose 1 "FIXATING EXISTING RPM DATABASE ($dbpath)"
   1.422 +        db_extend
   1.423 +        db_fixate
   1.424 +        db_operate
   1.425 +        ;;
   1.426 +
   1.427 +    list )
   1.428 +        db_list
   1.429 +        ;;
   1.430 +esac
   1.431 +
   1.432 +exit 0
   1.433 +

mercurial