getVserverStatus(): fix problems with leading whitespaces in numerical values
[util-vserver.git] / util-vserver / scripts / functions
1 # $Id$  --*- sh -*--
2
3 # Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 #  
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; version 2 of the License.
8 #  
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #  
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 _VS_NEWLINE='
19 '
20 declare -r _VS_NEWLINE=${_VS_NEWLINE:0-1}
21
22 function findObject
23 {
24     local mod=$1
25     local var=$2
26     local file=
27     local i=X
28     shift 2
29     
30     for i; do
31         test "$i"        || continue
32         test ! $mod "$i" || { file=$i; break; }
33     done
34
35     test -z "$i" -o "$file" || {
36         echo "Can not find file for '$var'; aborting"
37         exit 1
38     } >&2
39
40     eval "$var=\"$file\""
41 }
42
43 function findFile
44 {
45     findObject -f "$@"
46 }
47
48 function findDir
49 {
50     findObject -d "$@"
51 }
52
53 function findAndCopy
54 {
55     local dst=$1
56     test ! -s "$dst"         || return 0
57     
58     local tmp
59     shift
60     findFile tmp "$@"
61
62     test "$tmp" -a -s "$tmp" || return 0
63     cp -af "$tmp" "$dst"
64 }
65
66 function getPhysicalDir
67 {
68     ( set -P && cd "$1" && pwd )
69 }
70
71 function _pkgMountBindDir()
72 {
73     test "$1" != "$2" || return 0
74
75     mount -n --bind "$1" "$2"
76 }
77
78 function _pkgSetVarsBase
79 {
80     case "$vserver" in
81         ./*|/*)
82             if test -d "$vserver/vdir"; then
83                 BASEDIR=$vserver
84                 VDIR=$(getPhysicalDir "$vserver/vdir")
85                 
86                 PKGDIR=$BASEDIR/apps/pkgmgmt
87                 test -d "$PKGDIR" || {
88                     echo "Can not find configuration-directory for package-managment tools"
89                     exit 1
90                 } >&2
91                 findDir EXECDIR      $PKGDIR/execdir     /
92             else
93                 VDIR=$(getPhysicalDir "$vserver")
94                 PKGDIR=
95             fi
96             ;;
97         *)
98             BASEDIR=$CONFDIR/$vserver
99             test -d "$BASEDIR" || {
100                 echo "Can not find configuration-directory"
101                 exit 1
102             } >&2
103             
104             VDIR=$BASEDIR/vdir
105             test -d "$VDIR"   || VDIR=$DEFAULT_VSERVERDIR/$vserver
106             VDIR=$(getPhysicalDir "$VDIR")
107             
108             PKGDIR=$BASEDIR/apps/pkgmgmt
109             test -d "$PKGDIR" || {
110                 echo "Can not find configuration-directory for package-managment tools"
111                 exit 1
112             } >&2
113
114             findDir EXECDIR      $PKGDIR/execdir     /
115
116             ;;
117     esac
118
119     if test -z "$WORKAROUND_106057"; then
120         _rpmdb_mntpoint=/dev
121     else
122         _rpmdb_mntpoint=/.rpmdb
123     fi
124 }
125
126 function _pkgSetVarsRPM
127 {
128     if test "$PKGDIR"; then
129         findDir RPMETCDIR    $PKGDIR/rpmetc      $PKGDIR/base/rpm/etc       /etc/rpm
130         findDir RPMSTATEDIR  $PKGDIR/rpmstate    $PKGDIR/base/rpm/state
131
132         findDir RPMLIBDIR    $PKGDIR/rpmlib      /
133
134     else
135         findDir RPMETCDIR    "$VDIR"/etc/rpm     /etc/rpm
136         findDir RPMSTATEDIR  "$VDIR"/var/lib/rpm
137         RPMLIBDIR=/
138     fi
139     
140     RPMSTATEDIR=$(getPhysicalDir "$RPMSTATEDIR")
141     RPMETCDIR=$(getPhysicalDir "$RPMETCDIR")
142 }
143
144 function _pkgSetVarsApt
145 {
146     if test "$PKGDIR"; then
147         findDir APTETCDIR    $PKGDIR/aptetc      $PKGDIR/base/apt/etc       /etc/apt
148         findDir APTSTATEDIR  $PKGDIR/aptstate    $PKGDIR/base/apt/state
149         findDir APTCACHEDIR  $PKGDIR/aptcache    $PKGDIR/base/apt/cache
150         findDir APTARCHIVDIR $PKGDIR/aptarchives $PKGDIR/base/apt/archives  /var/cache/apt/archives
151     else
152         findDir APTETCDIR    "$VDIR"/etc/apt            /etc/apt
153         findDir APTSTATEDIR  "$VDIR"/var/state/apt
154         findDir APTCACHEDIR  "$VDIR"/var/cache/apt
155         findDir APTARCHIVDIR "$VDIR"/var/cache/apt/archives /var/cache/apt/archives
156     fi
157
158     findFile APT_CONFIG "$APTETCDIR"/apt.conf ""
159     test -z "$APT_CONFIG" || export APT_CONFIG
160 }
161
162 function _pkgMountBase
163 {
164     :
165 }
166
167 function _pkgMountApt
168 {
169     :
170 }
171
172 function _pkgMountRPM
173 {
174     _pkgMountBindDir "$RPMETCDIR" /etc/rpm
175     test "$RPMLIBDIR" = "/" || _pkgMountBindDir "$RPMLIBDIR" /usr/lib/rpm
176
177     "$_SECURE_MOUNT" --chroot "$VDIR" -n --secure --bind "$RPMSTATEDIR" "$_rpmdb_mntpoint"
178     test -z "$WORKAROUND_106057" || mount -n --bind "$RPMSTATEDIR" "$_rpmdb_mntpoint"
179
180     test -e "$VDIR"/proc/self/status || \
181         "$_SECURE_MOUNT" --chroot "$VDIR" -n --secure -t proc none /proc
182 }
183
184 function _pkgSetEnvBase
185 {
186     test "$EXECDIR"   = "/" || {
187         PATH=$EXECDIR:$PATH
188         LD_LIBRARY_PATH=$EXECDIR${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
189     }
190
191     export PATH LD_LIBRARY_PATH
192 }
193
194 function _pkgSetEnvApt
195 {
196     :
197 }
198
199 function _pkgSetEnvRPM
200 {
201     CUR_VSERVER=$vserver
202     RPM_FAKE_NAMESPACE_MOUNTS=$_rpmdb_mntpoint
203     RPM_BINARY=$_VRPM_PRELOAD
204
205     export CUR_VSERVER RPM_FAKE_NAMESPACE_MOUNTS RPM_BINARY
206 }
207
208 function pkgInit
209 {
210     local i
211     local vserver=$1
212     shift
213     
214     _pkgSetVarsBase
215     for i; do
216         case "$i" in
217             rpm)        _pkgSetVarsRPM;;
218             apt)        _pkgSetVarsApt;;
219             *)          echo "Unknown packaging flavor" >&2; exit 1;;
220         esac
221     done
222
223     _pkgMountBase
224     for i; do
225         case "$i" in
226             rpm)        _pkgMountRPM;;
227             apt)        _pkgMountApt;;
228         esac
229     done
230
231     _pkgSetEnvBase
232     for i; do
233         case "$i" in
234             rpm)        _pkgSetEnvRPM;;
235             apt)        _pkgSetEnvApt;;
236         esac
237     done
238
239     _PKG_FLAVORS="$@"
240     _PKG_VSERVER=$vserver
241 }
242
243 function isAvoidNamespace
244 {
245     local cfgdir
246
247     $_VSERVER_INFO - FEATURE namespace   || return 0
248     cfgdir=$($_VSERVER_INFO "$1" CFGDIR) || return 0
249     test ! -e "$cfgdir"/namespace        || return 1
250     test -e "$CONFDIR"/.defaults/nonamespace -o \
251          -e "$cfgdir"/nonamespace
252 }
253
254 function getAllVservers
255 {
256     local i
257     declare -a _tmp=()
258
259     for i in $CONFDIR/*; do
260         test   -d "$i"          || continue
261         test ! -e "$i"/disabled || continue
262         test   -d "$i"/vdir     || continue
263         case "$i" in
264             *.~*~) continue;;
265         esac
266
267         _tmp=( "${_tmp[@]}" "${i##$CONFDIR/}")
268     done
269
270     eval $1='( "${_tmp[@]}" )'
271 }
272
273 ## Usage: getVserverCtx <vdir> <result-varname> [<procnumber-varname> [<do-cleanup>]]
274 ## Returns: 0 iff vserver is running
275 function getVserverStatus
276 {
277     test -r "$1"/run || return 1
278
279     local _ctx
280     read _ctx <"$1"/run
281     eval "$2"=\$_ctx
282
283     test "$3"        || return 0
284     local _tmp=$($_VPS ax | $_AWK '{print $2}' | $_GREP -x "$_ctx" | $_WC -l )
285     let _tmp=_tmp+0
286     eval "$3"=\$_tmp
287
288     if test "$_tmp" = 0; then
289         local runfile=$($_READLINK "$1/run")
290         test -z "$4" || rm -f "$runfile"
291         return 1
292     fi
293
294     return 0
295 }
296
297 ## Usage: isCtxRunning <ctx>
298 function isCtxRunning
299 {
300     local _tmp=$($_VPS ax | $_AWK '{print $2}' | $_GREP -x "$1" | $_WC -l )
301     test $_tmp -gt 0
302 }
303
304 ## Usage: isVserverRunning <vdir> [<ctx-varname>]
305 function isVserverRunning
306 {
307     local ctx procnum
308
309     getVserverStatus "$1" ctx procnum 1 || return 1
310     test $procnum != 0                  || return 1
311     test -z "$2" || eval "$2"=\$ctx
312     return 0
313 }
314
315 ## Called as 'getFileValue <varname> <filename>'
316 function getFileValue
317 {
318     test -r "$2" || return 0
319     eval read "$1" <"$2"
320 }
321
322 ## Called as 'getFileArray <varname> <filename>'
323 function getFileArray
324 {
325     test -r "$2" || return 0
326     
327     local IFS=$_VS_NEWLINE
328     eval "$1"='( $(< "$2") )'
329 }
330
331 function checkComponents
332 {
333     local       i
334     local       msg=$1
335     local       x_failed=
336
337     shift
338     
339     for i; do
340         local failed=
341         case "$i" in
342             core)       test -x "$_CHBIND"           || failed=1;;
343             build)      test -x "$_VSERVER_BUILD"    || failed=1;;
344             sysv)       test -x "$INITRDDIR/vserver" || failed=1;;
345             devel)      test -d "$INCLUDEDIR/vserver.h" || failed=1;;
346             *)          echo "Unknown component '$i'" >&2
347                         return false
348                         ;;
349         esac
350
351         test -z "$failed" || {
352             echo "$msg: $i"
353             x_failed=1
354         } >&2
355     done
356
357     test -z "$x_failed"
358 }
359
360 ## Usage: isKernelAPI <ver> [<cmp-modifier>]
361 function isKernelAPI
362 {
363     local api=$($_VSERVER_INFO - APIVER) || api=0
364     test $[ $api ] -${2:-ge} $[ $1 ]
365 }
366
367 ## Usage: callInNamespace <vserver> <command> <args>*
368 function callInNamespace
369 {
370     local ctx=
371     
372     isAvoidNamespace "$1" || \
373     ctx=$( $_VSERVER_INFO "$1" CONTEXT t ) || ctx=
374
375     shift
376     if test "$ctx"; then
377         $_VNAMESPACE --enter "$ctx" -- "$@"
378     else
379         "$@"
380     fi
381 }
382
383 ## Usage: pkgmgmt.guessStyle <vserver> <resultvar>
384 function pkgmgmt.guessStyle()
385 {
386     local vdir=$($_VSERVER_INFO "$1" VDIR) || {
387         echo $"Can not determine vserver-root" >&2
388         return 1
389     }
390     local cfgdir=$($_VSERVER_INFO "$1" APPDIR pkgmgmt) || :
391
392     if test "$cfgdir" -a -e "$cfgdir"/style; then
393         read style <"$cfgdir"/style
394     elif test -e "$vdir"/etc/redhat-release -o -e "$vdir"/etc/fedora-release; then
395         style=redhat
396     elif test -e "$vdir"/etc/mandrake-release; then
397         style=mandrake
398     elif test -e "$vdir"/etc/debian_version; then
399         style=debian
400     else
401         echo $"Can not determine packagemanagement style" >&2
402         return 1
403     fi
404
405     eval $2=\$style
406     return 0
407 }
408
409 ## Usage: pkgmgmt.isInternal <vserver>
410 ## returns true iff <vserver> is configured for internal packagemanagement
411 ## A typical application is
412 ## | is_external=
413 ## | pkgmgmt.isInternal "$vserver" || is_external=1
414 function pkgmgmt.isInternal
415 {
416     local cfgdir=$($_VSERVER_INFO "$1" APPDIR pkgmgmt) || :
417
418     test -z "$cfgdir" -o ! -d "$cfgdir" -o -e "$cfgdir"/internal
419 }