added vwait
[util-vserver.git] / util-vserver / scripts / pkgmgmt
index 1eacba5..397eca2 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/bash
 # $Id$
 
-# Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+# Copyright (C) 2004,2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
 #  
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@ test -e "$UTIL_VSERVER_VARS" || {
 . "$UTIL_VSERVER_VARS"
 . "$_LIB_FUNCTIONS"
 . "$_LIB_VSERVER_BUILD_FUNCTIONS_PKGMGMT"
-. "$PKGLIBDIR/vserver.functions"
+. "$__PKGLIBDIR/vserver.functions"
 
 function showHelp()
 {
@@ -41,7 +41,7 @@ function showVersion()
 vpkg $PACKAGE_VERSION -- shows information about packages in vservers
 This program is part of $PACKAGE_STRING
 
-Copyright (C) 2004 Enrico Scholz
+Copyright (C) 2004,2005 Enrico Scholz
 This program is free software; you may redistribute it under the terms of
 the GNU General Public License.  This program has absolutely no warranty."
     exit 0
@@ -86,22 +86,41 @@ function _copySecureRev()
     ( cd "$dstdir" && tar xf - )
 }
 
+## Usage: _substFile <filename> <sed-expression>
+function _substFile()
+{
+    local file=$1
+    local expr=$2
+    
+    $_CHROOT_SH testfile "$file" || return 0
+
+    local tmp=$($_MKTEMP /tmp/pkgmgmt_subst.XXXXXX)
+    trap "$_RM -f $tmp" EXIT
+
+    $_CHROOT_SH cat "$file" | \
+       $_SED -e "$expr" >$tmp
+
+    $_CHROOT_SH cat "$file" | $_CMP -s $tmp - || \
+       $_CHROOT_SH truncate "$file" <$tmp
+
+    $_RM -f $tmp
+}
+
 function _hashAuto()
 {
+    local file=$1
     local hash=$2
-    local dir=$(dirname "$1")
-    local file=$(basename "$1")
 
-    $_EXEC_CD "$dir" "$(which test)" "$file" || return 0
+    $_CHROOT_SH testfile "$file" || return 0
     
     local tmp=$($_MKTEMP /tmp/apt.conf.XXXXXX)
     trap "$_RM -f $tmp" EXIT
 
-    $_EXEC_CD "$dir" $_CAT "$file" | \
+    $_CHROOT_SH cat "$file" | \
        $_SED -e "s|^\([^$hash].*@autogenerated@\)|$hash$hash\1|" >$tmp
 
-    $_CAT $tmp | $_EXEC_CD "$dir" "$(which cmp)" -s - "$file" || \
-       $_CHROOT_CAT "$1" <$tmp
+    $_CHROOT_SH cat "$file" | $_CMP -s $tmp - || \
+       $_CHROOT_SH truncate "$file" <$tmp
 
     $_RM -f $tmp
 }
@@ -164,6 +183,51 @@ function _umountFilesystems()
     test -n "$is_ok"
 }
 
+# Usage: verifyInternalPackages <vserver> <style>
+function verifyInternalPackages()
+{
+    local pkgs res=0
+    local ERR="\
+The following errors occured while trying to internalize the
+packagemanagement:
+"
+    
+    case $2 in
+       (RH)    pkgs=$(vrpm "$1" -- -q --qf '---%{NAME}---\n' rpm apt yum "${YUM_RELEASEPKGS[@]}")
+               hasSubstring "$pkgs" ---rpm--- || {
+                   warning "$ERR
+* The vserver does not seem to have the 'rpm' package which is required
+  for internal package management. It is suggested to install it before
+  continuing."
+                   res=1
+                   ERR=
+               }
+               
+               hasSubstring "$pkgs"  ---apt--- ---yum--- || {
+                   warning "$ERR
+* The vserver does not seem to have a depsolver like 'apt' or 'yum'
+  installed. It is suggested to install such a program before setting
+  up internal package management."
+                   res=1
+                   ERR=
+               }
+
+               test -n "$have_apt" || test -z "$have_yum"   || \
+               hasSubstring "$pkgs" "${YUM_RELEASEPKGS[@]}" || {
+                   warning "$ERR
+* yum requires a special package which describes the version of the
+  distribution. Such a package could not be found within the vserver
+  so please install it before continuing. Usually, this package is
+  named 'redhat-release' of 'fedora-release'."
+                   res=1
+                   ERR=
+               }
+               ;;
+    esac
+
+    return $res
+}
+
 function processVserver_RH()
 {
     local vserver=$1
@@ -177,7 +241,9 @@ function processVserver_RH()
 
     ## Figure out the environment....
     have_apt=1
+    have_yum=1
     pkgmgmt.isAptAvailable "$cfgdir" "$vdir" "$is_internalize" || have_apt=
+    pkgmgmt.isYumAvailable "$cfgdir" "$vdir" "$is_internalize" || have_yum=
 
     local APTETCDIR=
     local APTSTATEDIR=
@@ -189,6 +255,10 @@ function processVserver_RH()
     ## Create directories and assign variables where configuration
     ## can/will be found on the host
     if test -n "$is_internalize"; then
+       verifyInternalPackages "$vserver" RH || test -n "$IS_FORCE" ||
+           panic "
+Can not continue; use '--force' to override this check"
+    
        pushd "$vdir" >/dev/null
 
        test ! -L var/lib/rpm || {
@@ -260,6 +330,10 @@ function processVserver_RH()
        _copySecure "$vdir" "$RPMETCDIR"   /etc/rpm
        _copySecure "$vdir" "$RPMSTATEDIR" /var/lib/rpm
 
+       pushd "$vdir" >/dev/null
+           ## remove %_dbpath settings
+           _substFile /etc/rpm/macros '/^%_dbpath[ \t].*/D'
+       popd >/dev/null
     else
        if test -n "$have_apt"; then
            _copySecureRev "$vdir" /etc/apt "$APTETCDIR"
@@ -268,6 +342,8 @@ function processVserver_RH()
 
        _copySecureRev "$vdir" /etc/rpm     "$RPMETCDIR"
        _copySecureRev "$vdir" /var/lib/rpm "$RPMSTATEDIR"
+
+       echo -e "%_dbpath\t\t$rpmdb_mntpoint" >>$RPMETCDIR/macros
     fi
 
     ## Cleanups...
@@ -348,12 +424,13 @@ function processVserver()
     _umountFilesystems "$vserver"       || return 1
 }
 
-tmp=$(getopt -o y --long debug,externalize,internalize,help,version -n "$0" -- "$@") || exit 1
+tmp=$(getopt -o y --long debug,externalize,internalize,help,version,force -n "$0" -- "$@") || exit 1
 eval set -- "$tmp"
 
 IS_EXTERNALIZE=
 IS_INTERNALIZE=
 IS_YES=
+IS_FORCE=
 
 while true; do
     case "$1" in
@@ -362,6 +439,7 @@ while true; do
        (--debug)       set -x;;
        (--externalize) IS_EXTERNALIZE=1;;
        (--internalize) IS_INTERNALIZE=1;;
+       (--force)       IS_FORCE=1;;
        (-y)            IS_YES=1;;
        (--)            shift; break;;
        (*)             echo $"vserver: internal error; arg=='$1'" >&2; exit 1;;