diff -r 71503088f51b -r f880f219c566 openpkg/rpmdb
--- a/openpkg/rpmdb Tue Jul 31 12:12:54 2012 +0200
+++ b/openpkg/rpmdb Tue Jul 31 12:23:42 2012 +0200
@@ -1,15 +1,14 @@
#!@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
+## Copyright (c) 2000-2012 OpenPKG GmbH
##
-## 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 property of the OpenPKG GmbH, DE MUC HRB 160208.
+## All rights reserved. Licenses which grant limited permission to use,
+## copy, modify and distribute this software are available from the
+## OpenPKG GmbH.
##
-## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+## 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
@@ -30,6 +29,8 @@
help=""
prefix="@l_prefix@"
dbpath=""
+dbapi=""
+tmpdir=""
rpm=""
musr="@l_musr@"
mgrp="@l_mgrp@"
@@ -42,6 +43,7 @@
##
# iterate over argument line
+args=""
for opt
do
case $opt in
@@ -51,6 +53,7 @@
case $opt in
-h|--help ) help="Usage" ;;
-B|--build ) mode=build ;;
+ -M|--migrate ) mode=migrate ;;
-R|--rebuild ) mode=rebuild ;;
-C|--cleanup ) mode=cleanup ;;
-F|--fixate ) mode=fixate ;;
@@ -60,14 +63,19 @@
-v|--verbose ) verbose=`expr $verbose + 1` ;;
--prefix=* ) prefix=$arg ;;
--dbpath=* ) dbpath=$arg ;;
+ --dblib=* ) dblib=$arg ;;
+ --tmpdir=* ) tmpdir=$arg ;;
--rpm=* ) rpm=$arg ;;
--musr=* ) musr=$arg ;;
--mgrp=* ) mgrp=$arg ;;
- * ) help="Invalid option \`$opt'"; break ;;
+ -- ) ;;
+ -* ) help="Invalid option \`$opt'"; break ;;
+ * ) args="$args \"$opt\"" ;;
esac
done
+eval "set -- $args"
-# makre sure exactly one run-time mode is specified
+# make sure exactly one run-time mode is specified
if [ ".$mode" = . ]; then
help="No or invalid run-time mode specified"
fi
@@ -82,6 +90,7 @@
-h, --help print usage message (this one)
-B, --build build new RPM database from scratch
+ -M, --migrate migrate RPM database to new format
-R, --rebuild rebuild new from old RPM database
-C, --cleanup cleanup existing RPM database
-F, --fixate fixate existing RPM database
@@ -91,12 +100,14 @@
-v, --verbose operate in more verbose mode (increase verbose level)
--prefix=PREFIX use OpenPKG instance under PREFIX
--dbpath=PATH use OpenPKG RPM database under PATH
+ --dblib=LIB use OpenPKG RPM database backend library ("db" or "sqlite")
+ --tmpdir=PATH use OpenPKG temporary directory under PATH
--rpm=PROG use OpenPKG RPM executable PROG
--musr=USERNAME use OpenPKG management user USERNAME
--mgrp=GROUPNAME use OpenPKG management group GROUPNAME
This is OpenPKG rpmdb, an RPM database administration utility, providing
-lower-level maintainance functions for the Berkeley-DB 4.1 based RPM 4.2
+lower-level maintainance functions for the Berkeley-DB based RPM
database. It allows building new RPM databases from scratch, rebuilding
a new from an old RPM database (content dumping and reloading),
cleaning up problems on an existing RPM database (removal of DB region
@@ -115,6 +126,12 @@
if [ ".$dbpath" = . ]; then
dbpath="$prefix/RPM/DB"
fi
+if [ ".$dblib" = . ]; then
+ dblib="${1-db}"
+fi
+if [ ".$tmpdir" = . ]; then
+ tmpdir="$prefix/RPM/TMP"
+fi
if [ ".$rpm" = . ]; then
rpm="$prefix/bin/openpkg rpm"
fi
@@ -124,32 +141,61 @@
##
dbfiles="
- hash:Basenames
- hash:Conflictname
- hash:Depends
- btree:Dirnames
- hash:Filemd5s
- hash:Group
- btree:Installtid
- hash:Name
- hash:Packages
- hash:Providename
- btree:Provideversion
- hash:Pubkeys
- hash:Requirename
- btree:Requireversion
- hash:Sha1header
- hash:Sigmd5
- hash:Triggername
- region:__db.001
- region:__db.002
- region:__db.003
- region:__db.004
- region:__db.005
- region:__db.006
- region:__db.007
- region:__db.008
- region:__db.009
+ 3:btree:Basenames
+ 3:btree:Conflictname
+ 3:temporary:Depends
+ 3:btree:Dirnames
+ 3:btree:Filedigests
+ 3:btree:Filepaths
+ 3:btree:Group
+ 3:btree:Installtid
+ 3:btree:Name
+ 3:hash:Packagecolor
+ 3:btree:Packages
+ 3:btree:Providename
+ 3:btree:Provideversion
+ 3:hash:Pubkeys
+ 3:btree:Requirename
+ 3:btree:Requireversion
+ 3:hash:Sha1header
+ 3:hash:Sigmd5
+ 3:btree:Triggername
+ 3:btree:Obsoletename
+ 3:btree:Nvra
+ 3:btree:Sourcepkgid
+ 3:btree:BuildEnvironment
+ 3:region:__db.001
+ 3:region:__db.002
+ 3:region:__db.003
+ 3:region:__db.004
+ 3:region:__db.005
+ 3:region:__db.006
+ 3:region:__db.007
+ 3:region:__db.008
+ 3:region:__db.009
+ 4:*:Basenames
+ 4:*:Conflictname
+ 4:temporary:Depends
+ 4:*:Dirnames
+ 4:*:Filedigests
+ 4:*:Filepaths
+ 4:*:Group
+ 4:*:Installtid
+ 4:*:Name
+ 4:*:Packagecolor
+ 4:*:Packages
+ 4:*:Providename
+ 4:*:Provideversion
+ 4:*:Pubkeys
+ 4:*:Requirename
+ 4:*:Requireversion
+ 4:*:Sha1header
+ 4:*:Sigmd5
+ 4:*:Triggername
+ 4:*:Obsoletename
+ 4:*:Nvra
+ 4:*:Sourcepkgid
+ 4:*:BuildEnvironment
"
##
@@ -180,8 +226,45 @@
fi
}
+rpmdb_version_load () {
+ if [ -f $dbpath/VERSION ]; then
+ eval `(. $dbpath/VERSION || exit $?; echo "DBAPI=\"$DBAPI\"; DBLIB=\"$DBLIB\"; DBVER=\"$DBVER\"")`
+ fi
+ if [ ".$DBAPI" = . ]; then DBAPI="3"; fi
+ if [ ".$DBLIB" = . ]; then DBLIB="db"; fi
+ if [ ".$DBVER" = . ]; then DBVER="4.1.2"; fi
+}
+
+rpmdb_version_save () {
+ if [ ".$DBAPI" = .3 ]; then
+ DBLIB="db"
+ DBVER=`$rpmdb_load -V 2>&1 |\
+ grep 'Berkeley DB [0-9][0-9]*\.[0-9][0-9]*' |\
+ sed -e 's;^;X;' \
+ -e 's;^X[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$;\1;' \
+ -e 's;^X[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*$;\1.0;' \
+ -e 's;^X.*$;0.0.0;'`
+ elif [ ".$DBAPI" = .4 ]; then
+ DBLIB="sqlite"
+ DBVER=`$rpmdb_sqlite --version 2>&1 |\
+ grep '^[0-9][0-9]*\.[0-9][0-9]*' |\
+ sed -e 's;^;X;' \
+ -e 's;^X[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$;\1;' \
+ -e 's;^X[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*$;\1.0;' \
+ -e 's;^X.*$;0.0.0;'`
+ fi
+ ( echo "DBAPI=$DBAPI"
+ echo "DBLIB=$DBLIB"
+ echo "DBVER=$DBVER"
+ ) >$dbpath/VERSION.new || exit $?
+ mv $dbpath/VERSION.new $dbpath/VERSION || exit $?
+ chown $musr:$mgrp $dbpath/VERSION 2>/dev/null || true
+ chmod 644 $dbpath/VERSION 2>/dev/null || true
+}
+
rpm () {
- local opts="--dbpath `echo $dbpath | sed -e 's;/*$;;' -e 's;$;/;'`"
+ local opts="--define '_dbpath `echo $dbpath | sed -e 's;/*$;;' -e 's;$;/;'`'"
+ opts="$opts --define '_repackage_all_erasures 0'"
if [ ".$force" = .yes ]; then
opts="$opts --define '__dbi_private yes'"
fi
@@ -189,13 +272,9 @@
eval "$rpm $opts \"\$@\""
}
-rpmdb_load () {
- $prefix/lib/openpkg/rpmdb_load ${1+"$@"}
-}
-
-rpmdb_dump () {
- $prefix/lib/openpkg/rpmdb_dump ${1+"$@"}
-}
+rpmdb_load="$prefix/lib/openpkg/db_tool load"
+rpmdb_dump="$prefix/lib/openpkg/db_tool dump"
+rpmdb_sqlite="$prefix/lib/openpkg/sqlite3"
##
## RPM DATABASE OPERATIONS
@@ -225,60 +304,61 @@
# 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)"
+ eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\):\(.*\)$/dbapi="\1"; dbtype="\2"; dbfile="\3";/'`
+ verbose 3 "removing database file: $dbpath/$dbfile ($dbapi:$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
+ rpmdb_version_save
}
db_unbreak () {
- # cleanup DB region files
- verbose 2 "cleaning up RPM database DB region files"
+ # cleanup DB files
+ verbose 2 "cleaning up RPM database DB 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
+ eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\):\(.*\)$/dbapi="\1"; dbtype="\2"; dbfile="\3";/'`
+ if [ -f $dbpath/$dbfile ]; then
+ if [ ".$dbapi" = .3 -a ".$dbtype" = .region ]; then
+ verbose 3 "cleaning up DB file: $dbpath/$dbfile ($dbapi:$dbtype)"
+ rm -f $dbpath/$dbfile || true
+ elif [ ".$dbtype" = .temporary ]; then
+ verbose 3 "cleaning up DB file: $dbpath/$dbfile ($dbapi:$dbtype)"
+ rm -f $dbpath/$dbfile || true
+ fi
fi
done
}
-db_extend () {
- # make sure all RPM database DB files are present
- verbose 2 "making sure RPM database contains all possible DB files"
+db_convert () {
+ # make sure all RPM database DB files have the correct type
+ # (as the type can be different during upgrading from RPM 4 to RPM 5)
+ verbose 2 "making sure RPM database are of the correct type"
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
+ eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\):\(.*\)$/dbapi="\1"; dbtype="\2"; dbfile="\3";/'`
+ if [ ".$dbapi" != ".$DBAPI" ]; then
+ continue
+ fi
+ if [ -f $dbpath/$dbfile ]; then
+ if [ ".$dbapi" = .3 ] && [ ".$dbtype" = .hash -o ".$dbtype" = .btree ]; then
+ dbtype_old="`$rpmdb_dump -h $tmpdir -r $dbpath/$dbfile | grep '^type=' | sed -e 'q' | sed -e 's/^type=//'`"
+ if [ ".$dbtype_old" != ".$dbtype" ]; then
+ verbose 3 "converting DB file: $dbpath/$dbfile ($dbtype_old -> $dbtype)"
+ rm -f $dbpath/$dbfile.new
+ $rpmdb_dump -h $tmpdir -r $dbpath/$dbfile |\
+ sed -e "s/^type=.*/type=$dbtype/" -e '/^h_nelem=.*/d' |\
+ $rpmdb_load -h $tmpdir $dbpath/$dbfile.new
+ if $rpmdb_dump -h $tmpdir -r $dbpath/$dbfile.new >/dev/null 2>&1; then
+ rm -f $dbpath/$dbfile
+ mv $dbpath/$dbfile.new $dbpath/$dbfile
+ else
+ warning "failed to convert RPM DB file \"$dbfile\""
+ fi
+ fi
fi
fi
done
@@ -289,26 +369,75 @@
# 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)"
+ eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\):\(.*\)$/dbapi="\1"; dbtype="\2"; dbfile="\3";/'`
+ if [ ".$dbapi" != ".$DBAPI" ]; then
+ continue
+ fi
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
+ if [ ".$dbapi" = .3 ]; then
+ verbose 3 "dumping and reloading DB file: $dbpath/$dbfile ($dbtype)"
+ if [ ".$dbtype" = .hash -o ".$dbtype" = .btree ]; then
+ rm -f $dbpath/$dbfile.new
+ $rpmdb_dump -h $tmpdir -r $dbpath/$dbfile |\
+ $rpmdb_load -h $tmpdir $dbpath/$dbfile.new
+ if $rpmdb_dump -h $tmpdir -r $dbpath/$dbfile.new >/dev/null 2>&1; then
+ rm -f $dbpath/$dbfile
+ mv $dbpath/$dbfile.new $dbpath/$dbfile
+ else
+ warning "failed to reload RPM DB file \"$dbfile\""
+ fi
+ elif [ ".$dbtype" = .region ]; then
+ rm -f $dbpath/$dbfile || true
+ elif [ ".$dbtype" = .temporary ]; then
+ rm -f $dbpath/$dbfile || true
+ fi
+ elif [ ".$dbapi" = .4 ]; then
+ verbose 3 "dumping and reloading DB file: $dbpath/$dbfile ($dbtype)"
+ rm -f $dbpath/$dbfile.new
+ $rpmdb_sqlite $dbpath/$dbfile .dump |\
+ $rpmdb_sqlite $dbpath/$dbfile.new
+ if $rpmdb_sqlite $dbpath/$dbfile.new >/dev/null 2>&1; then
+ rm -f $dbpath/$dbfile
+ mv $dbpath/$dbfile.new $dbpath/$dbfile
+ else
+ warning "failed to reload RPM DB file \"$dbfile\""
+ fi
fi
fi
done
+ rpmdb_version_save
+}
+
+db_migrate () {
+ # perform database migration
+ if [ ".$1" != . ]; then
+ dblib="$1"
+ fi
+ dbapi_old="$DBAPI"
+ if [ ".$dblib" = .db ]; then
+ dbapi_new="3"
+ elif [ ".$dblib" = .sqlite ]; then
+ dbapi_new="4"
+ else
+ error "unknown RPM database backend library \"$dblib\""
+ fi
+ if [ ".$dbapi_new" = ".$dbapi_old" ]; then
+ error "RPM database already uses requested backend ($DBAPI:$DBLIB:$DBVER)"
+ fi
+ verbose 2 "migrating RPM database"
+ rpm --rebuilddb --dbapi "$dbapi_old" --rebuilddbapi "$dbapi_new"
+ verbose 3 "old RPM database format: $DBAPI:$DBLIB:$DBVER"
+ DBAPI="$dbapi_new"
+ rpmdb_version_save
+ rpmdb_version_load
+ verbose 3 "new RPM database format: $DBAPI:$DBLIB:$DBVER"
}
db_rebuild () {
# perform official "rebuilddb" operation
verbose 2 "rebuilding RPM database (built-in RPM procedure)"
rpm --rebuilddb
+ rpmdb_version_save
}
db_operate () {
@@ -333,17 +462,30 @@
# 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";/'`
+ eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\):\(.*\)$/dbapi="\1"; dbtype="\2"; dbfile="\3";/'`
+ if [ ".$dbapi" != ".$DBAPI" ]; then
+ continue
+ fi
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
+ if [ -f $dbpath/$dbfile ]; then
+ chown $musr:$mgrp $dbpath/$dbfile 2>/dev/null || true
+ chmod 644 $dbpath/$dbfile 2>/dev/null || true
+ fi
done
+ chown $musr:$mgrp $dbpath/VERSION 2>/dev/null || true
+ chmod 644 $dbpath/VERSION 2>/dev/null || true
}
db_list () {
# list all database files
for dbfile in $dbfiles; do
- eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'`
+ eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\):\(.*\)$/dbapi="\1"; dbtype="\2"; dbfile="\3";/'`
+ if [ ".$dbapi" != ".$DBAPI" ]; then
+ continue
+ fi
+ if [ ! -f "$dbpath/$dbfile" ]; then
+ continue
+ fi
if [ $verbose -eq 0 ]; then
echo "$dbfile"
elif [ $verbose -eq 1 ]; then
@@ -380,6 +522,9 @@
error "OpenPKG RPM database directory \"$dbpath\" not writable"
fi
+# load database information
+rpmdb_version_load
+
##
## DISPATCH INTO COMMANDS
##
@@ -389,7 +534,15 @@
verbose 1 "BUILDING NEW RPM DATABASE FROM SCRATCH ($dbpath)"
db_remove
db_init
- db_extend
+ db_fixate
+ db_operate
+ ;;
+
+ migrate )
+ verbose 1 "MIGRATING RPM DATABASE FORMAT ($dbpath)"
+ db_unbreak
+ db_convert
+ db_migrate
db_rebuild
db_fixate
db_operate
@@ -398,7 +551,7 @@
rebuild )
verbose 1 "REBUILDING NEW FROM OLD RPM DATABASE ($dbpath)"
db_unbreak
- db_extend
+ db_convert
db_reload
db_rebuild
db_fixate
@@ -408,7 +561,7 @@
cleanup )
verbose 1 "CLEANING UP EXISTING RPM DATABASE ($dbpath)"
db_unbreak
- db_extend
+ db_convert
db_rebuild
db_fixate
db_operate
@@ -416,9 +569,7 @@
fixate )
verbose 1 "FIXATING EXISTING RPM DATABASE ($dbpath)"
- db_extend
db_fixate
- db_operate
;;
list )