#!/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
. "$UTIL_VSERVER_VARS"
. "$_LIB_FUNCTIONS"
. "$_LIB_VSERVER_BUILD_FUNCTIONS_PKGMGMT"
+. "$__PKGLIBDIR/vserver.functions"
function showHelp()
{
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
function _createDirs()
{
for i; do
- test "$i" || continue
+ test -n "$i" || continue
mkdir -p -m755 "$i"
done
}
( 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
+ local tmp=$($_MKTEMP /tmp/apt.conf.XXXXXX)
+ trap "$_RM -f $tmp" EXIT
- $_EXEC_CD "$dir" /bin/cat "$file" | \
- sed -e "s|^\([^$hash].*@autogenerated@\)|$hash$hash\1|" >$tmp
+ $_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
+ $_RM -f $tmp
}
function _unhashAuto()
test -e "$1" || return 0
local hash=$2
- local tmp=$(mktemp /tmp/apt.conf.XXXXXX)
- trap "rm -f $tmp" EXIT
+ local tmp=$($_MKTEMP /tmp/apt.conf.XXXXXX)
+ trap "$_RM -f $tmp" EXIT
+
+ $_SED -e "s|^$hash$hash\(.*@autogenerated@\)|\1|" "$1" >$tmp
+ $_CMP -s "$tmp" "$1" || \
+ $_CAT "$tmp" >"$1"
+
+ $_RM -f $tmp
+}
+
+function _mountFilesystemsInternal()
+{
+ local fstab="$1"
+ test -e "$fstab" || return 0
+ shift
+
+ pushd "$vdir" >/dev/null
+ "$@" $_SECURE_MOUNT -n -a --chroot --fstab "$fstab"
+ popd >/dev/null
+}
+
+function _mountFilesystems()
+{
+ local cfgdir
+ cfgdir=$($_VSERVER_INFO "$1" CFGDIR) || {
+ echo "Can not determine configuration directory for '$1'; ..." >&2
+ return 1
+ }
+ test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1"
+
+ _mountFilesystemsInternal "$cfgdir"/fstab $_CHBIND "${CHBIND_OPTS[@]}" || return 1
+ _mountFilesystemsInternal "$cfgdir"/fstab.local $_CHBIND "${CHBIND_OPTS[@]}" || return 1
+}
+
+function _umountFilesystems()
+{
+ local cfgdir
+ cfgdir=$($_VSERVER_INFO "$1" CFGDIR) || {
+ echo "Can not determine configuration directory for '$1'; ..." >&2
+ return 1
+ }
+ local vdir=$cfgdir/vdir
+ local is_ok=1
+ test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1"
+
+ pushd "$vdir/" >/dev/null || return 1
+ _umountVserverInternal "$cfgdir"/fstab.local || is_ok=
+ _umountVserverInternal "$cfgdir"/fstab $_CHBIND "${CHBIND_OPTS[@]}" || is_ok=
+ popd >/dev/null || return 1
+
+ test -n "$is_ok"
+}
- sed -e "s|^$hash$hash\(.*@autogenerated@\)|\1|" "$1" >$tmp
- cmp -s "$tmp" "$1" || \
- cat "$tmp" >"$1"
+# 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
- rm -f $tmp
+ return $res
}
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=
## Create directories and assign variables where configuration
## can/will be found on the host
- if test "$is_internalize"; then
+ 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 || {
- $_EXEC_CD /var/lib /bin/rm rpm &&
- $_EXEC_CD /var/lib /bin/mkdir -m755 rpm &&
- $_EXEC_CD /var/lib /bin/chown rpm:rpm rpm ||
+ $_EXEC_CD /var/lib $_RM rpm &&
+ $_EXEC_CD /var/lib $_MKDIR -m755 rpm &&
+ $_EXEC_CD /var/lib $_CHOWN rpm:rpm rpm ||
:
} </dev/null 2>/dev/null
var/state/{,apt/{,lists/{,partial}}} \
etc/apt etc/rpm; do
test -d "$i" ||
- $_EXEC_CD /$(dirname "$i") /bin/mkdir -m755 $(basename "$i") || :
+ $_EXEC_CD /$(dirname "$i") $_MKDIR -m755 $(basename "$i") || :
done #2>/dev/null
popd >/dev/null
- if test "$have_apt"; then
+ if test -n "$have_apt"; then
findDir APTETCDIR "$cfgdir"/aptetc "$cfgdir"/base/apt/etc /etc/apt /
fi
mkdir -m755 -p "$cfgdir"
local need_base=
- if test "$have_apt"; then
+ if test -n "$have_apt"; then
findDir APTETCDIR "$cfgdir"/aptetc "$cfgdir"/base/apt/etc /
findDir APTSTATEDIR "$cfgdir"/aptstate "$cfgdir"/base/apt/state /
findDir APTCACHEDIR "$cfgdir"/aptcache "$cfgdir"/base/apt/cache /
fi
## Copy the files...
- if test "$is_internalize"; then
- if test "$have_apt"; then
+ if test -n "$is_internalize"; then
+ if test -n "$have_apt"; then
_copySecure "$vdir" "$APTETCDIR" /etc/apt
pushd "$vdir" >/dev/null
_hashAuto /etc/apt/apt.conf '/'
_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 "$have_apt"; then
+ if test -n "$have_apt"; then
_copySecureRev "$vdir" /etc/apt "$APTETCDIR"
_unhashAuto "$APTETCDIR"/apt.conf '/'
fi
_copySecureRev "$vdir" /etc/rpm "$RPMETCDIR"
_copySecureRev "$vdir" /var/lib/rpm "$RPMSTATEDIR"
+
+ echo -e "%_dbpath\t\t$rpmdb_mntpoint" >>$RPMETCDIR/macros
fi
## Cleanups...
- if test "$is_internalize"; then
+ if test -n "$is_internalize"; then
:
else
- tmpdir=$(mktemp -d /var/tmp/pgmgmt.XXXXXX)
- trap "rm -rf $tmpdir" EXIT
+ tmpdir=$($_MKTEMPDIR /var/tmp/pgmgmt.XXXXXX)
+ trap "$_RM -rf $tmpdir" EXIT
pushd "$vdir" >/dev/null
- $_EXEC_CD /var/lib /bin/mv rpm $tmpdir/
- $_EXEC_CD /var/lib /bin/ln -s "$rpmdb_mntpoint" rpm
- rm -rf $tmpdir
+ $_EXEC_CD /var/lib $_MV rpm $tmpdir/
+ $_EXEC_CD /var/lib $_LN_S "$rpmdb_mntpoint" rpm
+ $_RM -rf $tmpdir
fi
## Finish it...
- if test "$is_internalize"; then
- touch "$cfgdir"/internal
+ if test -n "$is_internalize"; then
+ $_TOUCH "$cfgdir"/internal
else
- rm -f "$cfgdir"/internal
+ $_RM -f "$cfgdir"/internal
fi
}
local vserver=$1
local is_internalize=$2
- if test "$is_internalize"; then
+ if test -n "$is_internalize"; then
echo $"Debian vservers should be internalized everytime; do not know how to handle '$vserver'" >&2
else
echo $"External packagemanagement is not supported for Debian vserver" >&2
test -z "$skip" || return 1
local style
+ _mountFilesystems "$vserver" || return 1
pkgmgmt.guessStyle "$vserver" style || return 1
case "$style" in
echo $"Vserver style '$style' is not supported for packagemanagment" >&2
return 1
esac
+
+ _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
(--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;;
shift
done
-test "$1" || {
+test -n "$1" || {
echo $"No vserver specified; try '--help' for more information"
exit 1
} >&2