openpkg/rc

changeset 428
f880f219c566
parent 427
71503088f51b
child 469
65414bdd541c
equal deleted inserted replaced
1:3a3ff239b35b 2:926b080b8dc0
1 #!@l_prefix@/lib/openpkg/bash --noprofile 1 #!@l_prefix@/lib/openpkg/bash --noprofile
2 ## 2 ##
3 ## rc -- OpenPKG Runcommand Processor 3 ## rc -- OpenPKG Run-Command Processor
4 ## Copyright (c) 2000-2007 OpenPKG Foundation e.V. <http://openpkg.net/> 4 ## Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/>
5 ## Copyright (c) 2000-2007 Ralf S. Engelschall <http://engelschall.com/> 5 ##
6 ## 6 ## This software is property of the OpenPKG GmbH, DE MUC HRB 160208.
7 ## Permission to use, copy, modify, and distribute this software for 7 ## All rights reserved. Licenses which grant limited permission to use,
8 ## any purpose with or without fee is hereby granted, provided that 8 ## copy, modify and distribute this software are available from the
9 ## the above copyright notice and this permission notice appear in all 9 ## OpenPKG GmbH.
10 ## copies. 10 ##
11 ## 11 ## THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
12 ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
13 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 12 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 13 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
15 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR 14 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
16 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 15 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
17 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 16 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 ## configuration 26 ## configuration
28 ## 27 ##
29 28
30 # program name, version and date 29 # program name, version and date
31 progname="rc" 30 progname="rc"
32 progvers="1.2.0" 31 progvers="1.2.1"
33 progdate="28-Jul-2003" 32 progdate="2007-12-27"
34 33
35 # path to OpenPKG instance 34 # path to OpenPKG instance
36 prefix="@l_prefix@" 35 prefix="@l_prefix@"
37 36
38 # path to GNU bash and GNU shtool 37 # path to GNU bash and GNU shtool
45 rcfunc="$prefix/etc/rc.func" 44 rcfunc="$prefix/etc/rc.func"
46 45
47 # helper variables 46 # helper variables
48 NL=" 47 NL="
49 " 48 "
49
50 ##
51 ## temporary file handling
52 ##
53
54 # establish secure temporary directory
55 i=0
56 while [ $i -lt 10 ]; do
57 tmpdir="/tmp/rc-`date '+%Y%m%d%H%M%S'`-$$"
58 (umask 022; mkdir $tmpdir >/dev/null 2>&1) && break
59 i=$(($i + 1))
60 sleep 1
61 done
62 if [ $i -eq 10 ]; then
63 echo "openpkg:rc:ERROR: unable to establish secure temporary directory" 1>&2
64 exit 1
65 fi
66 declare -r tmpdir
67 cleanup () {
68 if [ ".$tmpdir" != . ]; then
69 if [ -d $tmpdir ]; then
70 rm -rf $tmpdir >/dev/null 2>&1 || true
71 fi
72 fi
73 }
74 trap "cleanup; trap - EXIT INT ABRT QUIT TERM" EXIT INT ABRT QUIT TERM
75
76 # determine reasonable temporary files
77 tmpfile="$tmpdir/rc.tmp"
78 outfile="$tmpdir/rc.out"
79 errfile="$tmpdir/rc.err"
80 allfile="$tmpdir/rc.all"
81 deffile="$tmpdir/rc.def"
82
83 # initialize files
84 cp /dev/null $deffile
50 85
51 ## 86 ##
52 ## command line option parsing 87 ## command line option parsing
53 ## 88 ##
54 89
63 config=0 98 config=0
64 query=0 99 query=0
65 100
66 # iterate over argument line 101 # iterate over argument line
67 while [ $# -gt 0 ]; do 102 while [ $# -gt 0 ]; do
68 opt=$1 103 case "$1" in
69 case $opt in
70 -*=*) arg=${opt/-*=/} ;;
71 *) arg='' ;;
72 esac
73 case $opt in
74 -s|--silent ) silent=1 ;; 104 -s|--silent ) silent=1 ;;
75 -v|--verbose ) verbose=1 ;; 105 -v|--verbose ) verbose=1 ;;
76 -d|--debug ) debug=1 ;; 106 -d|--debug ) debug=1 ;;
77 -h|--help ) help="Usage" ;; 107 -h|--help ) help="Usage" ;;
78 -k|--keep ) keep=1 ;; 108 -k|--keep ) keep=1 ;;
79 -p|--print ) print=1 ;; 109 -p|--print ) print=1 ;;
80 -e|--eval ) eval=1 ;; 110 -e|--eval ) eval=1 ;;
81 -c|--config ) config=1 ;; 111 -c|--config ) config=1 ;;
82 -q|--query ) query=1 ;; 112 -q|--query ) query=1 ;;
83 -* ) help="Invalid option \`$opt'"; break ;; 113 -D|--define ) echo "@$2" | \
84 * ) break ;; 114 sed -e "s;';\\\\';g" | \
115 sed -e "s;^@\\([a-z][a-zA-Z0-9_]*\\)=\\(.*\\)\$;\1='\2';" \
116 -e "s;^@.*;;" >>$deffile; shift ;;
117 -* ) help="Invalid option \`$1'"; break ;;
118 * ) break ;;
85 esac 119 esac
86 shift 120 shift
87 done 121 done
88 122
89 # display error or usage message 123 # display error or usage message
90 if [ ".$help" != .0 ]; then 124 if [ ".$help" != .0 ]; then
91 if [ ".$help" != ".Usage" ]; then 125 if [ ".$help" != ".Usage" ]; then
92 echo "$progname:ERROR: $help" 1>&2 126 echo "$progname:ERROR: $help" 1>&2
93 fi 127 fi
94 echo "Usage: $progname [-s|--silent] [-v|--verbose] [-d|--debug] [-k|--keep] [-h|--help]" 1>&2 128 echo "Usage: $progname [-s|--silent] [-v|--verbose] [-d|--debug] [-k|--keep] [-h|--help]" 1>&2
95 echo " [-p|--print] [-e|--eval] [-c|--config] [-q|--query]" 1>&2 129 echo " [-p|--print] [-e|--eval] [-c|--config] [-q|--query] [-D|--define <name>=<value>]" 1>&2
96 echo " <package> <command> [<command> ...]" 1>&2 130 echo " <package> <command> [<command> ...]" 1>&2
97 if [ ".$help" != ".Usage" ]; then 131 if [ ".$help" != ".Usage" ]; then
98 exit 1 132 exit 1
99 else 133 else
100 exit 0 134 exit 0
115 fi 149 fi
116 fi 150 fi
117 151
118 # extend run-time environment with local OpenPKG tools (shtool, rpmtool, etc) 152 # extend run-time environment with local OpenPKG tools (shtool, rpmtool, etc)
119 PATH_ORIG="$PATH" 153 PATH_ORIG="$PATH"
154 PATH="$prefix/lib/openpkg/fallback:$PATH"
120 PATH="$prefix/bin:$PATH" 155 PATH="$prefix/bin:$PATH"
121 PATH="$prefix/sbin:$PATH" 156 PATH="$prefix/sbin:$PATH"
122 PATH="$prefix/lib/openpkg:$PATH" 157 PATH="$prefix/lib/openpkg:$PATH"
123 158 PATH="$prefix/lib/openpkg/override:$PATH"
124 # establish secure temporary directory
125 i=0
126 while [ $i -lt 10 ]; do
127 tmpdir="/tmp/rc-`date '+%Y%m%d%H%M%S'`-$$"
128 (umask 022; mkdir $tmpdir >/dev/null 2>&1) && break
129 i=$(($i + 1))
130 sleep 1
131 done
132 if [ $i -eq 10 ]; then
133 echo "openpkg:rc:ERROR: unable to establish secure temporary directory" 1>&2
134 exit 1
135 fi
136 declare -r tmpdir
137 trap "trap - EXIT INT ABRT QUIT TERM; rm -rf $tmpdir >/dev/null 2>&1 || true" EXIT INT ABRT QUIT TERM
138
139 # determine reasonable temporary files
140 tmpfile="$tmpdir/rc.tmp"
141 outfile="$tmpdir/rc.out"
142 errfile="$tmpdir/rc.err"
143 allfile="$tmpdir/rc.all"
144 159
145 # handle --query option 160 # handle --query option
146 if [ ".$query" = .1 ]; then 161 if [ ".$query" = .1 ]; then
147 # suck in all %config sections of all scripts 162 # suck in all %config sections of all scripts
148 # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf) 163 # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf)
149 touch $tmpfile 164 touch $tmpfile
150 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 165 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
151 echo ". $rcconf" >>$tmpfile 166 echo ". $rcconf" >>$tmpfile
167 echo ". $deffile" >>$tmpfile
152 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` 168 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'`
153 for s_name in $scripts; do 169 for s_name in $scripts; do
154 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 170 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
155 done 171 done
156 . $tmpfile 172 . $tmpfile
157 173
158 # apply override values to get effective values 174 # apply override values to get effective values
159 . $rcconf 175 . $rcconf
176 . $deffile
160 177
161 # display variable value 178 # display variable value
162 for var in $*; do 179 for var in $*; do
163 eval "echo \${$var}" 180 eval "echo \${$var}"
164 done 181 done
172 # suck in all %config sections of all scripts 189 # suck in all %config sections of all scripts
173 # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf) 190 # (rc.openpkg is special: has to be first and requires pre-inclusion of rc.conf)
174 touch $tmpfile 191 touch $tmpfile
175 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 192 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
176 echo ". $rcconf" >>$tmpfile 193 echo ". $rcconf" >>$tmpfile
194 echo ". $deffile" >>$tmpfile
177 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` 195 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'`
178 for s_name in $scripts; do 196 for s_name in $scripts; do
179 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 197 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
180 done 198 done
181 . $tmpfile 199 . $tmpfile
190 done 208 done
191 IFS="$OIFS" 209 IFS="$OIFS"
192 210
193 # apply override values to get effective values 211 # apply override values to get effective values
194 . $rcconf 212 . $rcconf
213 . $deffile
195 214
196 # determine how to print in bold mode in case output 215 # determine how to print in bold mode in case output
197 # is connected to a terminal device 216 # is connected to a terminal device
198 if [ -t 1 ]; then 217 if [ -t 1 ]; then
199 begin_bold=`$shtool echo -e '%B'` 218 begin_bold=`$shtool echo -e '%B'`
235 exit 1 254 exit 1
236 fi 255 fi
237 scripts="${1/*rc./}" 256 scripts="${1/*rc./}"
238 shift 257 shift
239 isall=0 258 isall=0
259 if [ ".$scripts" = ".cron" ]; then
260 # "cron" is an "all" with a random delay (to ensure that multiple
261 # OpenPKG instances do not all startup at exactly the same time)
262 # plus a mutex lock to ensure that multiple OpenPKG cron tasks of
263 # the same OpenPKG instance do not stumble over each other).
264
265 # determine delay range and timeout
266 case "${1-quarterly}" in
267 monthly ) delay=1800; timeout=28800 ;; # 30m / 8h
268 weekly ) delay=1800; timeout=14400 ;; # 30m / 4h
269 daily ) delay=900; timeout=7200 ;; # 15m / 2h
270 hourly ) delay=600; timeout=3600 ;; # 5m / 1h
271 quarterly|* ) delay=30; timeout=900 ;; # 30s / 15m
272 esac
273
274 # apply random run-time delay
275 # (hint: $RANDOM is a random value 0..32767)
276 sleep $(( ($RANDOM * $delay) / 32767 ))
277
278 # wrap ourself for mutual exclusion run-time
279 # and then perform the "all" command
280 cleanup
281 exec $prefix/lib/openpkg/mutex \
282 -t $timeout $prefix/RPM/TMP/openpkg-rc-cron.mutex \
283 sh -c "exec $0 all $*" || exit $?
284 fi
240 if [ ".$scripts" = ".all" ]; then 285 if [ ".$scripts" = ".all" ]; then
241 isall=1 286 isall=1
242 . $rcconf 287 . $rcconf
243 if [ ".$openpkg_runall" != . ]; then 288 . $deffile
244 # backward compatibility only
245 echo "openpkg:rc:WARNING: variable \"openpkg_runall\" was renamed to \"openpkg_rc_all\"." 1>&2
246 echo "openpkg:rc:WARNING: value of deprecated variable \"openpkg_runall\" taken over for compatibility." 1>&2
247 echo "openpkg:rc:WARNING: please update your local configuration in \"$rcconf\"." 1>&2
248 openpkg_rc_all="$openpkg_runall"
249 fi
250 case "$openpkg_rc_all" in 289 case "$openpkg_rc_all" in
251 [Nn][Oo] | [Ff][Aa][Ll][Ss][Ee] | [Oo][Ff][Ff] | 0 ) exit 0 ;; 290 [Nn][Oo] | [Ff][Aa][Ll][Ss][Ee] | [Oo][Ff][Ff] | 0 ) exit 0 ;;
252 esac 291 esac
253 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;"` 292 scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;"`
293
294 # the "all" target is usually called from system startup scripts,
295 # and we really want to ensure that no potentially corrupt
296 # (because of an unclean shutdown of the system) RPM DB journal
297 # files are staying around and preventing the startup of the
298 # OpenPKG instance. When called manually it also doesn't hurt to
299 # cleanup.
300 rm -f $prefix/RPM/DB/__db.* >/dev/null 2>&1 || true
254 else 301 else
255 if [ ! -f "$rcdir/rc.$scripts" ]; then 302 if [ ! -f "$rcdir/rc.$scripts" ]; then
256 echo "openpkg:rc:ERROR: package \"$scripts\" not found" 1>&2 303 echo "openpkg:rc:ERROR: package \"$scripts\" not found" 1>&2
257 exit 1 304 exit 1
258 fi 305 fi
266 echo ${LOGNAME:-${USER}}` 313 echo ${LOGNAME:-${USER}}`
267 if [ ".$user" = . ]; then 314 if [ ".$user" = . ]; then
268 echo "openpkg:rc:ERROR: unable to determine current username" 1>&2 315 echo "openpkg:rc:ERROR: unable to determine current username" 1>&2
269 exit 1 316 exit 1
270 fi 317 fi
318
319 # just call OpenPKG RPM to let it once perform the run-time integrity checks
320 $prefix/bin/openpkg rpm -q openpkg >/dev/null || exit $?
271 321
272 # iterate over the specified commands 322 # iterate over the specified commands
273 rv=0 323 rv=0
274 cmds="$*" 324 cmds="$*"
275 for cmd in $cmds; do 325 for cmd in $cmds; do
395 # variable, we place the %config section of "openpkg" to the front. 445 # variable, we place the %config section of "openpkg" to the front.
396 # And we have to extra pre-include the rc.conf to allow 446 # And we have to extra pre-include the rc.conf to allow
397 # rc.conf to override the default of $openpkg_rc_def, too. 447 # rc.conf to override the default of $openpkg_rc_def, too.
398 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 448 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
399 echo ". $rcconf" >>$tmpfile 449 echo ". $rcconf" >>$tmpfile
450 echo ". $deffile" >>$tmpfile
400 l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` 451 l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'`
401 for l_name in $l_scripts; do 452 for l_name in $l_scripts; do
402 sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 453 sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
403 done 454 done
404 455
405 # generate: inclusion of the application of override variables 456 # generate: inclusion of the application of override variables
406 echo ". $rcconf" >>$tmpfile 457 echo ". $rcconf" >>$tmpfile
458 echo ". $deffile" >>$tmpfile
407 459
408 # for --eval redirect stderr and stdout (but remember stdout) 460 # for --eval redirect stderr and stdout (but remember stdout)
409 # (let stderr pass unfiltered in case of debug mode) 461 # (let stderr pass unfiltered in case of debug mode)
410 if [ ".$eval" = .1 ]; then 462 if [ ".$eval" = .1 ]; then
411 if [ ".$debug" = .1 ]; then 463 if [ ".$debug" = .1 ]; then
490 # variable, we place the %config section of "openpkg" to the front. 542 # variable, we place the %config section of "openpkg" to the front.
491 # And we have to extra pre-include the rc.conf to allow 543 # And we have to extra pre-include the rc.conf to allow
492 # rc.conf to override the default of $openpkg_rc_def, too. 544 # rc.conf to override the default of $openpkg_rc_def, too.
493 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 545 sed <$rcdir/rc.openpkg >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
494 echo ". $rcconf" >>$tmpfile 546 echo ". $rcconf" >>$tmpfile
547 echo ". $deffile" >>$tmpfile
495 l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'` 548 l_scripts=`/bin/ls $rcdir/rc.* | sed -e "s;^$rcdir/rc\.;;" | egrep -v '^openpkg$'`
496 for l_name in $l_scripts; do 549 for l_name in $l_scripts; do
497 sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d' 550 sed <$rcdir/rc.$l_name >>$tmpfile -e "1,/^%config/d" -e '/^%.*/,$d'
498 done 551 done
499 552
500 # generate: inclusion of the application of override variables 553 # generate: inclusion of the application of override variables
501 echo ". $rcconf" >>$tmpfile 554 echo ". $rcconf" >>$tmpfile
555 echo ". $deffile" >>$tmpfile
502 556
503 # generate: %common section and particular command section 557 # generate: %common section and particular command section
504 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d' 558 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d'
505 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d' 559 sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d'
506 560

mercurial