vshost-util-vserver

Build script and sources for util-vserver.
git clone https://ccx.te2000.cz/git/vshost-util-vserver
Log | Files | Refs

pkgmgmt (13247B)


      1 #!/bin/bash
      2 # $Id$
      3 
      4 # Copyright (C) 2004,2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
      5 #  
      6 # This program is free software; you can redistribute it and/or modify
      7 # it under the terms of the GNU General Public License as published by
      8 # the Free Software Foundation; version 2 of the License.
      9 #  
     10 # This program is distributed in the hope that it will be useful,
     11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 # GNU General Public License for more details.
     14 #  
     15 # You should have received a copy of the GNU General Public License
     16 # along with this program; if not, write to the Free Software
     17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     18 
     19 : ${UTIL_VSERVER_VARS:=/usr/lib/util-vserver/util-vserver-vars}
     20 test -e "$UTIL_VSERVER_VARS" || {
     21     echo $"Can not find util-vserver installation (the file '$UTIL_VSERVER_VARS' would be expected); aborting..." >&2
     22     exit 1
     23 }
     24 . "$UTIL_VSERVER_VARS"
     25 . "$_LIB_FUNCTIONS"
     26 . "$_LIB_VSERVER_BUILD_FUNCTIONS"
     27 . "$_LIB_VSERVER_BUILD_FUNCTIONS_PKGMGMT"
     28 . "$_LIB_VSERVER_FUNCTIONS"
     29 
     30 function showHelp()
     31 {
     32     echo \
     33 $"Usage: $0 --externalize|--internalize [-y] [--] <vserver-name>
     34 
     35 Report bugs to <$PACKAGE_BUGREPORT>."
     36     exit 0
     37 }
     38 
     39 function showVersion()
     40 {
     41     echo $"\
     42 vpkg $PACKAGE_VERSION -- shows information about packages in vservers
     43 This program is part of $PACKAGE_STRING
     44 
     45 Copyright (C) 2004,2005 Enrico Scholz
     46 This program is free software; you may redistribute it under the terms of
     47 the GNU General Public License.  This program has absolutely no warranty."
     48     exit 0
     49 }
     50 
     51 function init()
     52 {
     53     if test -z "$WORKAROUND_106057"; then
     54 	rpmdb_mntpoint=/dev
     55     else
     56 	rpmdb_mntpoint=/.rpmdb
     57     fi
     58 }
     59 
     60 function _createDirs()
     61 {
     62     for i; do
     63 	test -n "$i" || continue
     64 	mkdir -p -m755 "$i"
     65     done
     66 }
     67 
     68 function _copySecure()
     69 {
     70     local chroot=$1
     71     local srcdir=$2
     72     local dstdir=$3
     73 
     74     
     75     ( cd "$srcdir" && tar chf - '.' ) | \
     76     ( cd "$chroot" && $_EXEC_CD "$dstdir" $_TAR xf - )
     77 }
     78 
     79 function _copySecureRev()
     80 {
     81     local chroot=$1
     82     local srcdir=$2
     83     local dstdir=$3
     84 
     85     ( cd "$chroot" && $_EXEC_CD "$srcdir" $_TAR cf - '.' ) | \
     86     ( cd "$dstdir" && tar xf - )
     87 }
     88 
     89 ## Usage: _substFile <filename> <sed-expression>
     90 function _substFile()
     91 {
     92     local file=$1
     93     local expr=$2
     94     
     95     $_CHROOT_SH testfile "$file" || return 0
     96 
     97     local tmp=$($_MKTEMP pkgmgmt_subst.XXXXXX)
     98     trap "$_RM -f $tmp" EXIT
     99 
    100     $_CHROOT_SH cat "$file" | \
    101 	$_SED -e "$expr" >$tmp
    102 
    103     $_CHROOT_SH cat "$file" | $_CMP -s $tmp - || \
    104 	$_CHROOT_SH truncate "$file" <$tmp
    105 
    106     $_RM -f $tmp
    107 }
    108 
    109 function _hashAuto()
    110 {
    111     local file=$1
    112     local hash=$2
    113 
    114     $_CHROOT_SH testfile "$file" || return 0
    115     
    116     local tmp=$($_MKTEMP apt.conf.XXXXXX)
    117     trap "$_RM -f $tmp" EXIT
    118 
    119     $_CHROOT_SH cat "$file" | \
    120 	$_SED -e "s|^\([^$hash].*@autogenerated@\)|$hash$hash\1|" >$tmp
    121 
    122     $_CHROOT_SH cat "$file" | $_CMP -s $tmp - || \
    123 	$_CHROOT_SH truncate "$file" <$tmp
    124 
    125     $_RM -f $tmp
    126 }
    127 
    128 function _unhashAuto()
    129 {
    130     test -e "$1" || return 0
    131 
    132     local hash=$2
    133     local tmp=$($_MKTEMP apt.conf.XXXXXX)
    134     trap "$_RM -f $tmp" EXIT
    135 
    136     $_SED -e "s|^$hash$hash\(.*@autogenerated@\)|\1|" "$1" >$tmp
    137     $_CMP -s "$tmp" "$1" || \
    138 	$_CAT "$tmp" >"$1"
    139 
    140     $_RM -f $tmp
    141 }
    142 
    143 function _mountFilesystemsInternal()
    144 {
    145     local fstab="$1"
    146     test -e "$fstab" || return 0
    147     shift
    148 
    149     pushd "$vdir" >/dev/null
    150     "$@" $_SECURE_MOUNT -n -a --chroot --fstab "$fstab"
    151     popd >/dev/null
    152 }
    153 
    154 function _mountFilesystems()
    155 {
    156     local cfgdir
    157     cfgdir=$($_VSERVER_INFO "$1" CFGDIR) || {
    158 	echo "Can not determine configuration directory for '$1'; ..." >&2
    159 	return 1
    160     }
    161     test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1"
    162     
    163     _mountFilesystemsInternal "$cfgdir"/fstab                           || return 1
    164     _mountFilesystemsInternal "$cfgdir"/fstab.local                     || return 1
    165     _mountFilesystemsInternal "$cfgdir"/fstab.remote "${CHBIND_CMD[@]}" || return 1
    166 }
    167 
    168 function _umountFilesystems()
    169 {
    170     local cfgdir
    171     cfgdir=$($_VSERVER_INFO "$1" CFGDIR) || {
    172 	echo "Can not determine configuration directory for '$1'; ..." >&2
    173 	return 1
    174     }
    175     local vdir=$cfgdir/vdir
    176     local is_ok=1
    177     test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1"
    178 
    179     pushd "$vdir/" >/dev/null || return 1
    180 	_umountVserverInternal  "$cfgdir"/fstab.remote "${CHBIND_CMD[@]}" || is_ok=
    181 	_umountVserverInternal  "$cfgdir"/fstab.local                     || is_ok=
    182 	_umountVserverInternal  "$cfgdir"/fstab                           || is_ok=
    183     popd >/dev/null           || return 1
    184     
    185     test -n "$is_ok"
    186 }
    187 
    188 # Usage: verifyInternalPackages <vserver> <style>
    189 function verifyInternalPackages()
    190 {
    191     local pkgs res=0
    192     local ERR="\
    193 The following errors occured while trying to internalize the
    194 packagemanagement:
    195 "
    196     
    197     case $2 in
    198 	(RH)	pkgs=$(vrpm "$1" -- -q --qf '---%{NAME}---\n' rpm apt yum urpmi "${YUM_RELEASEPKGS[@]}")
    199 		hasSubstring "$pkgs" ---rpm--- || {
    200 		    warning "$ERR
    201 * The vserver does not seem to have the 'rpm' package which is required
    202   for internal package management. It is suggested to install it before
    203   continuing."
    204 		    res=1
    205 		    ERR=
    206 		}
    207 		
    208 		hasSubstring "$pkgs"  ---apt--- ---yum--- ---urpmi--- || {
    209 		    warning "$ERR
    210 * The vserver does not seem to have a depsolver like 'apt' or 'yum'
    211   installed. It is suggested to install such a program before setting
    212   up internal package management."
    213 		    res=1
    214 		    ERR=
    215 		}
    216 
    217 		test -n "$have_apt" || test -n "$have_urpmi" ||
    218 		test -z "$have_yum" || \
    219 		hasSubstring "$pkgs" "${YUM_RELEASEPKGS[@]}" || {
    220 		    warning "$ERR
    221 * yum requires a special package which describes the version of the
    222   distribution. Such a package could not be found within the vserver
    223   so please install it before continuing. Usually, this package is
    224   named 'redhat-release' of 'fedora-release'."
    225 		    res=1
    226 		    ERR=
    227 		}
    228 		;;
    229     esac
    230 
    231     return $res
    232 }
    233 
    234 function processVserver_RH()
    235 {
    236     local vserver=$1
    237     local is_internalize=$2
    238     local have_apt
    239     local have_yum
    240     local have_urpmi
    241     local cfgdir
    242     local i
    243 
    244     cfgdir=$($_VSERVER_INFO "$vserver" APPDIR pkgmgmt) || \
    245     cfgdir=$($_VSERVER_INFO "$vserver" APPDIR)/pkgmgmt
    246 
    247     ## Figure out the environment....
    248     have_apt=1
    249     have_yum=1
    250     have_urpmi=1
    251     pkgmgmt.isAptAvailable "$cfgdir" "$vdir" "$is_internalize" || have_apt=
    252     pkgmgmt.isYumAvailable "$cfgdir" "$vdir" "$is_internalize" || have_yum=
    253     pkgmgmt.isUrpmiAvailable "$cfgdir" "$vdir" "$is_internalize" || have_urpmi=
    254 
    255     local APTETCDIR=
    256     local APTSTATEDIR=
    257     local APTCACHEDIR=
    258     local APTARCHIVDIR=
    259     local RPMETCDIR=
    260     local RPMSTATEDIR=
    261 
    262     ## Create directories and assign variables where configuration
    263     ## can/will be found on the host
    264     if test -n "$is_internalize"; then
    265 	verifyInternalPackages "$vserver" RH || test -n "$IS_FORCE" ||
    266 	    panic "
    267 Can not continue; use '--force' to override this check"
    268     
    269 	pushd "$vdir" >/dev/null
    270 
    271 	test ! -L var/lib/rpm || {
    272 	    $_EXEC_CD /var/lib $_RM            rpm &&
    273 	    $_EXEC_CD /var/lib $_MKDIR -m755   rpm &&
    274 	    $_EXEC_CD /var/lib $_CHOWN rpm:rpm rpm ||
    275 	    :
    276 	} </dev/null 2>/dev/null
    277 
    278 	for i in var/cache/apt/{,archives/{,partial},genpkglist,gensrclist} \
    279 		 var/state/{,apt/{,lists/{,partial}}} \
    280 		 etc/apt etc/rpm; do
    281 	    test -d "$i" ||
    282 		$_EXEC_CD /$(dirname "$i") $_MKDIR -m755 $(basename "$i") || :
    283 	done #2>/dev/null
    284 	
    285 	popd >/dev/null
    286 	
    287 	if test -n "$have_apt"; then
    288 	    findDir APTETCDIR     "$cfgdir"/aptetc "$cfgdir"/base/apt/etc /etc/apt /
    289 	elif test -n "$have_urpmi"; then
    290 	    findDir URPMISTATEDIR "$cfgdir"/base/var/lib/urpmi
    291 	    findDir URPMIETCDIR   "$cfgdir"/base/etc/urpmi
    292 	fi
    293 
    294 	findDir RPMETCDIR   "$cfgdir"/rpmetc   "$cfgdir"/base/rpm/etc    \
    295 			    "$cfgdir"/base/etc/rpm /etc/rpm /
    296 	findDir RPMSTATEDIR "$cfgdir"/rpmstate "$cfgdir"/base/rpm/state  \
    297 			    "$cfgdir"/base/var/lib/rpm
    298     else
    299 	mkdir -m755 -p "$cfgdir"
    300 	local need_base=
    301 
    302 	if test -n "$have_apt"; then
    303 	    findDir APTETCDIR    "$cfgdir"/aptetc      "$cfgdir"/base/apt/etc       /
    304 	    findDir APTSTATEDIR  "$cfgdir"/aptstate    "$cfgdir"/base/apt/state     /
    305 	    findDir APTCACHEDIR  "$cfgdir"/aptcache    "$cfgdir"/base/apt/cache     /
    306 	    findDir APTARCHIVDIR "$cfgdir"/aptarchives "$cfgdir"/base/apt/archives  /
    307 	    
    308 	    test "$APTETCDIR"    != / || APTETCDIR=$cfgdir/base/apt/etc
    309 	    test "$APTSTATEDIR"  != / || APTSTATEDIR=$cfgdir/base/apt/state
    310 	    test "$APTCACHEDIR"  != / || APTCACHEDIR=$cfgdir/base/apt/cache
    311 	    test "$APTARCHIVDIR" != / || APTARCHIVDIR=$cfgdir/base/apt/archive
    312 
    313 	    test -d "$cfgdir"/aptetc   -a -d "$cfgdir"/aptstate -a \
    314 	         -d "$cfgdir"/aptcache -a -d "$cfgdir"/aptarchives || need_base=1
    315 	fi
    316 
    317 	findDir RPMETCDIR     "$cfgdir"/rpmetc   "$cfgdir"/base/rpm/etc    /
    318 	findDir RPMSTATEDIR   "$cfgdir"/rpmstate "$cfgdir"/base/rpm/state  /
    319 
    320 	test "$RPMETCDIR"   != / || RPMETCDIR=$cfgdir/base/rpm/etc
    321 	test "$RPMSTATEDIR" != / || RPMSTATEDIR=$cfgdir/base/rpm/state
    322 
    323 	test -d "$cfgdir"/rpmetc -a -d "$cfgdir"/rpmstate || need_base=1
    324 	test ! -e "$cfgdir"/base || need_base=
    325 
    326 	test -z "$need_base" || ln -s "$PKGCFGDIR" "$cfgdir"/base
    327 
    328 	mkdir -m755 -p "$PKGCFGDIR"
    329 	_createDirs "$APTETCDIR" "$APTSTATEDIR" "$APTCACHEDIR" "$APTARCHIVDIR" \
    330 		    "$RPMETCDIR" "$RPMSTATEDIR"
    331     fi
    332 
    333     ## Copy the files...
    334     if test -n "$is_internalize"; then
    335 	if test -n "$have_apt"; then
    336 	    _copySecure "$vdir" "$APTETCDIR" /etc/apt
    337 	    pushd "$vdir" >/dev/null
    338 		_hashAuto /etc/apt/apt.conf '/'
    339 	    popd >/dev/null
    340 	elif test -n "$have_urpmi"; then
    341 	    _copySecure "$vdir" "$URPMISTATEDIR" /var/lib/urpmi
    342 	    _copySecure "$vdir" "$URPMIETCDIR" /etc/urpmi
    343 	fi
    344 
    345 	_copySecure "$vdir" "$RPMETCDIR"   /etc/rpm
    346 	_copySecure "$vdir" "$RPMSTATEDIR" /var/lib/rpm
    347 
    348 	pushd "$vdir" >/dev/null
    349 	    ## remove %_dbpath settings
    350 	    _substFile /etc/rpm/macros '/^%_dbpath[ \t].*/D'
    351 	popd >/dev/null
    352     else
    353 	if test -n "$have_apt"; then
    354 	    _copySecureRev "$vdir" /etc/apt "$APTETCDIR"
    355 	    _unhashAuto "$APTETCDIR"/apt.conf '/'
    356 	fi
    357 
    358 	_copySecureRev "$vdir" /etc/rpm     "$RPMETCDIR"
    359 	_copySecureRev "$vdir" /var/lib/rpm "$RPMSTATEDIR"
    360 
    361 	echo -e "%_dbpath\t\t$rpmdb_mntpoint" >>$RPMETCDIR/macros
    362     fi
    363 
    364     ## Cleanups...
    365     if test -n "$is_internalize"; then
    366 	:
    367     else
    368 	tmpdir=$($_MKTEMPDIR -p /var/tmp pkgmgmt.XXXXXX)
    369 	trap "$_RM -rf $tmpdir" EXIT
    370 	pushd "$vdir" >/dev/null
    371 	$_EXEC_CD /var/lib $_MV rpm $tmpdir/
    372 	$_EXEC_CD /var/lib $_LN_S "$rpmdb_mntpoint" rpm
    373 	$_RM -rf $tmpdir
    374     fi
    375 
    376     ## Finish it...
    377     if test -n "$is_internalize"; then
    378 	$_TOUCH "$cfgdir"/internal
    379     else
    380 	$_RM -f "$cfgdir"/internal
    381     fi
    382 }
    383 
    384 function processVserver_Debian()
    385 {
    386     local vserver=$1
    387     local is_internalize=$2
    388 
    389     if test -n "$is_internalize"; then
    390 	echo $"Debian vservers should be internalized everytime; do not know how to handle '$vserver'" >&2
    391     else
    392 	echo $"External packagemanagement is not supported for Debian vserver" >&2
    393     fi
    394 
    395     return 1
    396 }
    397 
    398 function processVserver()
    399 {
    400     local vserver=$1
    401     local is_external=
    402     local skip=1
    403     local vdir
    404 
    405     ! $_VSERVER_INFO -q "$vserver" RUNNING || {
    406 	echo $"Can not operate on running vservers; please stop '$vserver' and retry again..."
    407 	return 1
    408     } >&2
    409 
    410     vdir=$($_VSERVER_INFO "$vserver" VDIR) && test -d "$vdir" || {
    411 	echo $"Vserver '$vserver' does not seem to exist; skipping it..."
    412 	return 1
    413     } >&2
    414 
    415     _setVserverDir "$vserver"
    416     _setVserverName
    417     _setVserverDirName
    418     pkgmgmt.initVariables
    419     
    420     pkgmgmt.isInternal "$vserver" || is_external=1
    421 
    422     case "$is_external"X"$IS_INTERNALIZE"X"$IS_EXTERNALIZE" in
    423 	(*X1X1)	echo $"Can not externalize and internalize at the same time";;
    424 	(*XX)	echo $"No operation specified; try '--help' for more information";;
    425 	(1XX1)	echo $"Vserver '$vserver' has already external packagemanagment; skipping it...";;
    426 	(X1X)	echo $"Vserver '$vserver' has already internal packagemanagment; skipping it...";;
    427 	(*)	skip=
    428     esac >&2
    429 
    430     test -z "$skip" || return 1
    431 
    432     local style
    433     _mountFilesystems  "$vserver"       || return 1
    434     pkgmgmt.guessStyle "$vserver" style || return 1
    435 
    436     case "$style" in
    437 	(redhat|mandrake)	processVserver_RH     "$vserver" "$IS_INTERNALIZE";;
    438 	(debian)		processVserver_Debian "$vserver" "$IS_INTERNALIZE";;
    439 	(*)
    440 	    echo $"Vserver style '$style' is not supported for packagemanagment" >&2
    441 	    return 1
    442     esac
    443 
    444     _umountFilesystems "$vserver"       || return 1
    445 }
    446 
    447 tmp=$(getopt -o y --long debug,externalize,internalize,help,version,force -n "$0" -- "$@") || exit 1
    448 eval set -- "$tmp"
    449 
    450 IS_EXTERNALIZE=
    451 IS_INTERNALIZE=
    452 IS_YES=
    453 IS_FORCE=
    454 
    455 while true; do
    456     case "$1" in
    457 	(--help)	showHelp $0;;
    458 	(--version)	showVersion;;
    459 	(--debug)	set -x;;
    460 	(--externalize)	IS_EXTERNALIZE=1;;
    461 	(--internalize)	IS_INTERNALIZE=1;;
    462 	(--force)       IS_FORCE=1;;
    463 	(-y)		IS_YES=1;;
    464 	(--)		shift; break;;
    465 	(*)	   	echo $"vserver: internal error; arg=='$1'" >&2; exit 1;;
    466     esac
    467     shift
    468 done
    469 
    470 test -n "$1" || {
    471     echo $"No vserver specified; try '--help' for more information"
    472     exit 1
    473 } >&2
    474 
    475 
    476 set -e
    477 init
    478 
    479 ok=1
    480 passed=
    481 for i; do
    482     processVserver "$i" && passed=1 || ok=
    483 done
    484     
    485 test -z "$ok"     || exit 0
    486 test -z "$passed" || exit 1
    487 exit 2