|
1 #!@l_prefix@/lib/openpkg/bash |
|
2 ## |
|
3 ## rpmdb -- OpenPKG RPM Database Administration Utility |
|
4 ## Copyright (c) 2000-2007 OpenPKG Foundation e.V. <http://openpkg.net/> |
|
5 ## Copyright (c) 2000-2007 Ralf S. Engelschall <http://engelschall.com/> |
|
6 ## |
|
7 ## Permission to use, copy, modify, and distribute this software for |
|
8 ## any purpose with or without fee is hereby granted, provided that |
|
9 ## the above copyright notice and this permission notice appear in all |
|
10 ## copies. |
|
11 ## |
|
12 ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
|
13 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
|
14 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
15 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR |
|
16 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
17 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
18 ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
19 ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
|
20 ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
|
21 ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
|
22 ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
23 ## SUCH DAMAGE. |
|
24 ## |
|
25 |
|
26 # program information |
|
27 progname="rpmdb" |
|
28 |
|
29 # configuration defaults |
|
30 help="" |
|
31 prefix="@l_prefix@" |
|
32 dbpath="" |
|
33 rpm="" |
|
34 musr="@l_musr@" |
|
35 mgrp="@l_mgrp@" |
|
36 mode="" |
|
37 force=no |
|
38 verbose=2 |
|
39 |
|
40 ## |
|
41 ## PARSE COMMAND LINE |
|
42 ## |
|
43 |
|
44 # iterate over argument line |
|
45 for opt |
|
46 do |
|
47 case $opt in |
|
48 -*=*) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;; |
|
49 *) arg='' ;; |
|
50 esac |
|
51 case $opt in |
|
52 -h|--help ) help="Usage" ;; |
|
53 -B|--build ) mode=build ;; |
|
54 -R|--rebuild ) mode=rebuild ;; |
|
55 -C|--cleanup ) mode=cleanup ;; |
|
56 -F|--fixate ) mode=fixate ;; |
|
57 -L|--list ) mode=list ;; |
|
58 -f|--force ) force=yes ;; |
|
59 -q|--quiet ) verbose=0 ;; |
|
60 -v|--verbose ) verbose=`expr $verbose + 1` ;; |
|
61 --prefix=* ) prefix=$arg ;; |
|
62 --dbpath=* ) dbpath=$arg ;; |
|
63 --rpm=* ) rpm=$arg ;; |
|
64 --musr=* ) musr=$arg ;; |
|
65 --mgrp=* ) mgrp=$arg ;; |
|
66 * ) help="Invalid option \`$opt'"; break ;; |
|
67 esac |
|
68 done |
|
69 |
|
70 # makre sure exactly one run-time mode is specified |
|
71 if [ ".$mode" = . ]; then |
|
72 help="No or invalid run-time mode specified" |
|
73 fi |
|
74 |
|
75 # error or usage message |
|
76 if [ ".$help" != . ]; then |
|
77 if [ ".$help" != ".Usage" ]; then |
|
78 echo "$progname:ERROR: $help" 1>&2 |
|
79 fi |
|
80 cat 1>&2 <<EOT |
|
81 $progname:USAGE: $progname [options] |
|
82 |
|
83 -h, --help print usage message (this one) |
|
84 -B, --build build new RPM database from scratch |
|
85 -R, --rebuild rebuild new from old RPM database |
|
86 -C, --cleanup cleanup existing RPM database |
|
87 -F, --fixate fixate existing RPM database |
|
88 -L, --list list all RPM database files |
|
89 -f, --force operate in force mode (no save operations) |
|
90 -q, --quiet operate in quiet mode (no verbose messages at all) |
|
91 -v, --verbose operate in more verbose mode (increase verbose level) |
|
92 --prefix=PREFIX use OpenPKG instance under PREFIX |
|
93 --dbpath=PATH use OpenPKG RPM database under PATH |
|
94 --rpm=PROG use OpenPKG RPM executable PROG |
|
95 --musr=USERNAME use OpenPKG management user USERNAME |
|
96 --mgrp=GROUPNAME use OpenPKG management group GROUPNAME |
|
97 |
|
98 This is OpenPKG rpmdb, an RPM database administration utility, providing |
|
99 lower-level maintainance functions for the Berkeley-DB 4.1 based RPM 4.2 |
|
100 database. It allows building new RPM databases from scratch, rebuilding |
|
101 a new from an old RPM database (content dumping and reloading), |
|
102 cleaning up problems on an existing RPM database (removal of DB region |
|
103 files, etc) and fixating the files in an existing RPM database (file |
|
104 attributes). |
|
105 |
|
106 EOT |
|
107 if [ ".$help" != ".Usage" ]; then |
|
108 exit 2 |
|
109 else |
|
110 exit 0 |
|
111 fi |
|
112 fi |
|
113 |
|
114 # delayed determination of variables |
|
115 if [ ".$dbpath" = . ]; then |
|
116 dbpath="$prefix/RPM/DB" |
|
117 fi |
|
118 if [ ".$rpm" = . ]; then |
|
119 rpm="$prefix/bin/openpkg rpm" |
|
120 fi |
|
121 |
|
122 ## |
|
123 ## DATABASE FILE INFORMATION |
|
124 ## |
|
125 |
|
126 dbfiles=" |
|
127 hash:Basenames |
|
128 hash:Conflictname |
|
129 hash:Depends |
|
130 btree:Dirnames |
|
131 hash:Filemd5s |
|
132 hash:Group |
|
133 btree:Installtid |
|
134 hash:Name |
|
135 hash:Packages |
|
136 hash:Providename |
|
137 btree:Provideversion |
|
138 hash:Pubkeys |
|
139 hash:Requirename |
|
140 btree:Requireversion |
|
141 hash:Sha1header |
|
142 hash:Sigmd5 |
|
143 hash:Triggername |
|
144 region:__db.001 |
|
145 region:__db.002 |
|
146 region:__db.003 |
|
147 region:__db.004 |
|
148 region:__db.005 |
|
149 region:__db.006 |
|
150 region:__db.007 |
|
151 region:__db.008 |
|
152 region:__db.009 |
|
153 " |
|
154 |
|
155 ## |
|
156 ## HELPER FUNCTIONS |
|
157 ## |
|
158 |
|
159 error () { |
|
160 echo "$progname:ERROR: $*" 1>&2 |
|
161 exit 1 |
|
162 } |
|
163 |
|
164 warning () { |
|
165 echo "$progname:WARNING: $*" 1>&2 |
|
166 } |
|
167 |
|
168 verbose () { |
|
169 local level=$1 |
|
170 shift |
|
171 if [ $level -le $verbose ]; then |
|
172 local lead="" |
|
173 case "$level" in |
|
174 1 ) lead="" ;; |
|
175 2 ) lead="" ;; |
|
176 3 ) lead=" " ;; |
|
177 * ) lead=" " ;; |
|
178 esac |
|
179 echo "$progname: $lead$*" 1>&2 |
|
180 fi |
|
181 } |
|
182 |
|
183 rpm () { |
|
184 local opts="--dbpath `echo $dbpath | sed -e 's;/*$;;' -e 's;$;/;'`" |
|
185 if [ ".$force" = .yes ]; then |
|
186 opts="$opts --define '__dbi_private yes'" |
|
187 fi |
|
188 verbose 3 "run: $rpm $opts $@" |
|
189 eval "$rpm $opts \"\$@\"" |
|
190 } |
|
191 |
|
192 rpmdb_load () { |
|
193 $prefix/lib/openpkg/rpmdb_load ${1+"$@"} |
|
194 } |
|
195 |
|
196 rpmdb_dump () { |
|
197 $prefix/lib/openpkg/rpmdb_dump ${1+"$@"} |
|
198 } |
|
199 |
|
200 ## |
|
201 ## RPM DATABASE OPERATIONS |
|
202 ## |
|
203 |
|
204 db_wait () { |
|
205 # wait until RPM has released the database in case we are called |
|
206 # asynchronously to RPM (especially important when upgrading from |
|
207 # RPM 4.0 where concurrent access is still not possible) |
|
208 verbose 2 "waiting for RPM database to be available" |
|
209 local i=0 |
|
210 while [ $i -lt 10 ]; do |
|
211 if $prefix/libexec/openpkg/rpm -q openpkg >/dev/null 2>&1; then |
|
212 break |
|
213 fi |
|
214 sleep 1 |
|
215 i=`expr $i + 1` |
|
216 done |
|
217 if [ $i -eq 10 ]; then |
|
218 exit 1 |
|
219 else |
|
220 exit 0 |
|
221 fi |
|
222 } |
|
223 |
|
224 db_remove () { |
|
225 # remove all known files |
|
226 verbose 2 "removing (possibly existing) old RPM database DB files" |
|
227 for dbfile in $dbfiles; do |
|
228 eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` |
|
229 verbose 3 "removing database file: $dbpath/$dbfile ($dbtype)" |
|
230 rm -f $dbpath/$dbfile |
|
231 done |
|
232 } |
|
233 |
|
234 db_init () { |
|
235 # perform official "initdb" operation |
|
236 # (is mostly a no-operation in RPM 4.2, but anyway) |
|
237 verbose 2 "creating new RPM database (built-in RPM procedure)" |
|
238 rpm --initdb |
|
239 |
|
240 # perform some real RPM work, so more database files |
|
241 # magically spring into existence |
|
242 verbose 2 "operating on new RPM database" |
|
243 rpm --import $prefix/etc/openpkg/openpkg.org.pgp || true |
|
244 rpm -e gpg-pubkey-63c4cb9f-3c591eda --allmatches || true |
|
245 |
|
246 # perform official "rebuilddb" operation in the hope it |
|
247 # creates even more database files now that we have some content |
|
248 verbose 2 "rebuilding new RPM database (built-in RPM procedure)" |
|
249 rpm --rebuilddb |
|
250 } |
|
251 |
|
252 db_unbreak () { |
|
253 # cleanup DB region files |
|
254 verbose 2 "cleaning up RPM database DB region files" |
|
255 for dbfile in $dbfiles; do |
|
256 eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` |
|
257 if [ ".$dbtype" = .region ]; then |
|
258 verbose 3 "cleaning up DB file: $dbpath/$dbfile ($dbtype)" |
|
259 rm -f $dbpath/$dbfile || true |
|
260 touch $dbpath/$dbfile || true |
|
261 fi |
|
262 done |
|
263 } |
|
264 |
|
265 db_extend () { |
|
266 # make sure all RPM database DB files are present |
|
267 verbose 2 "making sure RPM database contains all possible DB files" |
|
268 for dbfile in $dbfiles; do |
|
269 eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` |
|
270 if [ ! -f $dbpath/$dbfile ]; then |
|
271 verbose 3 "creating DB file: $dbpath/$dbfile ($dbtype)" |
|
272 if [ ".$dbtype" = .hash -o ".$dbtype" = .btree ]; then |
|
273 ( echo "VERSION=3" |
|
274 echo "format=bytevalue" |
|
275 echo "type=$dbtype" |
|
276 echo "db_pagesize=16384" |
|
277 echo "HEADER=END" |
|
278 echo "DATA=END" |
|
279 ) | rpmdb_load $dbpath/$dbfile || true |
|
280 else |
|
281 touch $dbpath/$dbfile || true |
|
282 fi |
|
283 fi |
|
284 done |
|
285 } |
|
286 |
|
287 db_reload () { |
|
288 # rebuilding new from old RPM database DB files by dumping and |
|
289 # reloading their entire content |
|
290 verbose 2 "dumping and reloading RPM database DB file contents" |
|
291 for dbfile in $dbfiles; do |
|
292 eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` |
|
293 verbose 3 "dumping and reloading DB file: $dbpath/$dbfile ($dbtype)" |
|
294 if [ -f $dbpath/$dbfile ]; then |
|
295 if [ ".$dbtype" = .hash -o ".$dbtype" = .btree ]; then |
|
296 rpmdb_dump $dbpath/$dbfile |\ |
|
297 rpmdb_load $dbpath/$dbfile.new |
|
298 rm -f $dbpath/$dbfile |
|
299 mv $dbpath/$dbfile.new $dbpath/$dbfile |
|
300 else |
|
301 rm -f $dbpath/$dbfile || true |
|
302 touch $dbpath/$dbfile || true |
|
303 fi |
|
304 fi |
|
305 done |
|
306 } |
|
307 |
|
308 db_rebuild () { |
|
309 # perform official "rebuilddb" operation |
|
310 verbose 2 "rebuilding RPM database (built-in RPM procedure)" |
|
311 rpm --rebuilddb |
|
312 } |
|
313 |
|
314 db_operate () { |
|
315 # perform some read/write operation on RPM database |
|
316 # (we have no package available, but removing and reimporting |
|
317 # the OpenPKG OpenPGP keys is a harmless thing and always possible) |
|
318 verbose 2 "performing read/write operation on RPM database" |
|
319 for spec in \ |
|
320 openpkg.org.pgp:gpg-pubkey-63c4cb9f-3c591eda \ |
|
321 openpkg.com.pgp:gpg-pubkey-61b7ae34-4544a6af \ |
|
322 openpkg.net.pgp:gpg-pubkey-52197903-4544a74d \ |
|
323 ; do |
|
324 eval `echo "$spec" | sed -e 's/^\(.*\):\(.*\)$/file="\1"; package="\2"/'` |
|
325 rpm -q $package >/dev/null 2>&1 && rpm -e $package --allmatches || true |
|
326 rpm -q $package >/dev/null 2>&1 || rpm --import $prefix/etc/openpkg/$file || true |
|
327 done |
|
328 rpm -qa >/dev/null 2>&1 |
|
329 } |
|
330 |
|
331 db_fixate () { |
|
332 # fix ownership and permissions of (especially newly created) |
|
333 # RPM database files to make sure they are consistent |
|
334 verbose 2 "making sure RPM database files have consistent attributes" |
|
335 for dbfile in $dbfiles; do |
|
336 eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` |
|
337 verbose 3 "fixating DB file: $dbpath/$dbfile ($dbtype)" |
|
338 chown $musr:$mgrp $dbpath/$dbfile 2>/dev/null || true |
|
339 chmod 644 $dbpath/$dbfile 2>/dev/null || true |
|
340 done |
|
341 } |
|
342 |
|
343 db_list () { |
|
344 # list all database files |
|
345 for dbfile in $dbfiles; do |
|
346 eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` |
|
347 if [ $verbose -eq 0 ]; then |
|
348 echo "$dbfile" |
|
349 elif [ $verbose -eq 1 ]; then |
|
350 echo "$dbpath/$dbfile" |
|
351 elif [ $verbose -ge 2 ]; then |
|
352 echo "$dbpath/$dbfile ($dbtype)" |
|
353 fi |
|
354 done |
|
355 } |
|
356 |
|
357 ## |
|
358 ## ENVIRONMENT CONSISTENCY CHECKS |
|
359 ## |
|
360 |
|
361 # sanity check OpenPKG instance |
|
362 if [ ".$prefix" = . ]; then |
|
363 error "OpenPKG instance directory is empty" |
|
364 fi |
|
365 if [ ! -d $prefix ]; then |
|
366 error "OpenPKG instance directory \"$prefix\" not found" |
|
367 fi |
|
368 if [ ! -x $prefix/bin/openpkg ]; then |
|
369 error "OpenPKG instance directory \"$prefix\" not valid" |
|
370 fi |
|
371 |
|
372 # sanity check OpenPKG RPM database |
|
373 if [ ".$dbpath" = . ]; then |
|
374 error "OpenPKG RPM database directory is empty" |
|
375 fi |
|
376 if [ ! -d $dbpath ]; then |
|
377 error "OpenPKG RPM database directory \"$dbpath\" not found" |
|
378 fi |
|
379 if [ ! -w $dbpath ]; then |
|
380 error "OpenPKG RPM database directory \"$dbpath\" not writable" |
|
381 fi |
|
382 |
|
383 ## |
|
384 ## DISPATCH INTO COMMANDS |
|
385 ## |
|
386 |
|
387 case "$mode" in |
|
388 build ) |
|
389 verbose 1 "BUILDING NEW RPM DATABASE FROM SCRATCH ($dbpath)" |
|
390 db_remove |
|
391 db_init |
|
392 db_extend |
|
393 db_rebuild |
|
394 db_fixate |
|
395 db_operate |
|
396 ;; |
|
397 |
|
398 rebuild ) |
|
399 verbose 1 "REBUILDING NEW FROM OLD RPM DATABASE ($dbpath)" |
|
400 db_unbreak |
|
401 db_extend |
|
402 db_reload |
|
403 db_rebuild |
|
404 db_fixate |
|
405 db_operate |
|
406 ;; |
|
407 |
|
408 cleanup ) |
|
409 verbose 1 "CLEANING UP EXISTING RPM DATABASE ($dbpath)" |
|
410 db_unbreak |
|
411 db_extend |
|
412 db_rebuild |
|
413 db_fixate |
|
414 db_operate |
|
415 ;; |
|
416 |
|
417 fixate ) |
|
418 verbose 1 "FIXATING EXISTING RPM DATABASE ($dbpath)" |
|
419 db_extend |
|
420 db_fixate |
|
421 db_operate |
|
422 ;; |
|
423 |
|
424 list ) |
|
425 db_list |
|
426 ;; |
|
427 esac |
|
428 |
|
429 exit 0 |
|
430 |