I have seen quite a few messages from people saying how easy it is to
simply copy a virtual server from one root host to another. While trivial
to do manually I have sometimes found it annoying to have to remember the
flags to rsync so that it doesn't cross filesystems, or have forgotten to
copy the config file across or whatever.

I also have a need to keep copies of virtual servers across different root
hosts as a warm-backup, and wanted a quick way to synchronise and stop &
start as needed from a script.

Since I haven't seen anybody else post such a thing I wrote a script which
I call "vcp" (attached) to do just that. Someone might find it useful -
feedback and/or enhancements are welcome. If it is useful enough to lots
of people then perhaps it will be picked up by Jacques...

Cheers, Mark.
-- 
Mark Lawrence ([EMAIL PROTECTED])          Mobile: +41 79 309 0633
#!/bin/sh
#
# Copyright (C) 2002, Mark Lawrence <[EMAIL PROTECTED]>.
# Licence: GPL
#
# vcp: Copy/Sync a virtual host from one machine to another
#
VERSION="0.1.0"
umask 022


### Helper functions ###

error () {
        echo "E: $2" >&2
        exit $1
}

warn () {
        echo "W: $1" >&2
}

info () {
        echo "I: $1"
}


### Usage/Info functions ###

usage () {
    cat <<EOF 1>&2
Usage:  ${0##*/} [-hVds] <vserver> <destination_host>
EOF
}

full_usage () {
        usage
        cat <<EOF
e.g.    ${0##*/} -s mail01 rhost02

This script will copy the file system contents of a virtual server from
the localhost to another root host, optionally stopping the local and
starting the remote vservers as necessary to enact a virtual server move.

It relies on rsync and /usr/sbin/vserver, and assumes the standard
/etc/vservers/ and /vservers/ locations.

It can be used on a running virtual server without the "-s" option
to provide a "warm backup"

Options:
        -h              this help
        -V              copyright and version information
        -d              debug
        -s              stop the local vserver before copying, and start
                        it on the destination host afterwards

EOF
}

full_version () {
    cat <<EOF
${0##*/} version $VERSION
Copyright (c) 2002 Mark Lawrence   <[EMAIL PROTECTED]>

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
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.

EOF
}


### Command line & setup ###

if [ $# -eq 0 ]; then  # Script invoked with no command-line args?
        usage
        exit 1
fi  

stopstart=(false)
vserver=""
dhost=""
shost=""

exec 3> /dev/null # for the debug option

shopt -s extglob
while getopts "hVsd" Option; do
        case $Option in
                h)      full_usage
                        exit 1
                        ;;
                V)      full_version
                        exit 1
                        ;;
                s)      stopstart=(true)
                        ;;
                d)      exec 3>&2
                        ;;
                *)      usage
                        exit 1
                        ;;
        esac
done

# Decrements the argument pointer so it points to next argument.
shift $(($OPTIND - 1))

if (($# != 2)); then
        usage
        exit 1
fi

vserver=$1
vconf=/etc/vservers/$vserver.conf
vroot=/vservers/$vserver
dhost=$2


### Perform some sanity checks and do the copy  ###

if [ ! -d $vroot ]; then
        error 2 "Directory \"$vroot\" does not exist"
fi

if [ ! -r $vconf ]; then
        error 2 "Vserver file \"$vconf\" does not exist"
fi

if (ssh $dhost /usr/sbin/vserver $vserver running | grep -q 'is running'); then
        warn "vserver \"$vserver\" already running on host \"$dhost\""
        error 3 "Cannot copy over a running vserver"
fi

if $stopstart; then
        info "Stopping virtual server \"$vserver\" on localhost"
        /usr/sbin/vserver $vserver stop 1>&3 2>&3
fi

info "Syncing files between hosts"
rsync -avxz $vroot/ $dhost:$vroot/ 1>&3 2>&3 # trailing slashes very important!
if (($?)); then
        error $? "rsync failed"
fi

info "Syncing configuration file"
rsync -avxz $vconf $dhost:$vconf 1>&3 2>&3
if (($?)); then
        error $? "rsync failed"
fi

if $stopstart; then
        info "Starting virtual server \"$vserver\" on $dhost"
        ssh $dhost /usr/sbin/vserver $vserver start 1>&3 2>&3
        if (ssh $dhost /usr/sbin/vserver $vserver running | \
        grep -q 'not running'); then
                error 4 "Virtual server \"$vserver\" failed to start on $dhost"
        fi
fi

exit 0

Reply via email to