I fixed the ownership problem some time ago. I even posted the code to the
list and/or the tool maintainers but I guess it got lost... Perhaps
Roderick can tell us where he obtained the script from?

I have attached my latest copy plus the *man* page which gives an example
of how to copy from one host to another. As others have pointed out there
are other ways to do it manually, however I suggest that to make life easy
for newcomers it is worth having a documented tool.

Cheers,
Mark.

On Fri, 5 Dec 2003 [EMAIL PROTECTED] wrote:

> hi,
>
> rsync won`t help because the userrights (direcotry specially) eventuelly get
> wrong, if i copy from hostmachine to hostmachine.
>
>
> I have no idea how to copy "correctly" between two server.
>
>
> Greetings
> Oliver
>
> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED] Behalf Of Roderick A.
> Anderson
> Sent: Freitag, 5. Dezember 2003 19:57
> To: [EMAIL PROTECTED]
> Subject: Re: [vserver] Copying vservers
>
>
> I have a request for Mark Lawrence.  I've looked at and wanted to use the
> vserver-copy script you wrote but it doesn't quite (or at least doesn't
> appear to) do a copy from one partition to another.  I have very little
> experience with rsync so hesitate to fiddle with it.
>
>
> Best,
> Rod
> --
>     "Open Source Software - You usually get more than you pay for..."
>      "Build A Brighter Lamp :: Linux Apache {middleware} PostgreSQL"
>
>
> _______________________________________________
> Vserver mailing list
> [EMAIL PROTECTED]
> http://list.linux-vserver.org/mailman/listinfo/vserver
>
>
>
> _______________________________________________
> Vserver mailing list
> [EMAIL PROTECTED]
> http://list.linux-vserver.org/mailman/listinfo/vserver
>
>

#!/bin/sh
#
# Copyright (C) 2002, Mark Lawrence <[EMAIL PROTECTED]>.
# Licence: GPL
#
# Copy/Sync a virtual host from one machine to another
#
# History:
#
# 2003-02-23: Version 0.2 - Mark Lawrence
# - Set ONBOOT to "no" in the original .conf file when the "-s" flag is 
#   used so that if/when you reboot the source roothost you don't have the
#   same vserver and IP address running on two machines.
#
# 2003-03-04: Version 0.3 - Mark lawrence
# - Changed all checks for [ "" != "$var" ] into [ -n|-z "$var" ]. "" doesn't
#   seem to work for bash on the Sparc architecture.
# - Changed $ssh variable into $shcmd.
#
# 2003-04-04: Version 0.4 - Mark lawrence
# - Set "ONBOOT=no" in the destination .conf file when --startstop
#   is not used, in case the destination roothost reboots. We don't
#   want two copies of a vserver running at the same time.
#
# 2003-06-24: Version 0.5 - Mark lawrence
# - Added --numeric-ids to the main rsync call, because
#   otherwise the uids could be translated/change during the copy.
# - Aadded --delete to the main rsync call because I found out the
#   hard way that things like mail queue files would always grow.
#   Ie: mails in the queue are copied, and will be delivered again if
#   you backup from the copy, or start the copy of the vserver on another
#   machine.

VERSION="0.5"
umask 022
me=${0##*/}


### Helper functions ###

# Save stdin and stdout for later use
exec 3>&1
exec 4>&2

noninteractive () {
        exec &> /dev/null
}

interactive () {
        exec 1>&3
        exec 2>&4
}

info () {
        ! $quiet && echo "I: $me: $1" >&3
}

warn () {
        ! $quiet && echo "W: $me: $1" >&4
}

error () {
        ! $quiet && echo "E: $me: $2" >&4
        rm -f $tmpf
        exit $1
}


### Usage/Info functions ###

usage () {
    cat <<EOF 1>&2
Usage:  $me [-hVvqidrRs] vserver newname
        $me [-hVvqidrRs] vserver host:[newname]
        (Use -h for help)
EOF
}

full_usage () {
        usage
        cat <<EOF

$me uses rsync to make a copy of a vserver. If the destination
name contains a host specification the vserver will be synchronised to
the remote destination over ssh/rsh.

This can be used on a running vserver to make a warm backup. With the -s
flag a vserver can even be operationally moved to different hardware within
seconds.

The -i and -d flags can be used to minimally reconfigure the destination
vserver (rewrites /etc/vservers/newname.conf and /vservers/newname/etc/hosts)

Options:
        -h, --help              this help
        -V, --version           copyright and version information
        -v, --verbose           show all output
        -q, --quiet             direct all output to /dev/null (no password
                                prompt for logins on remote hosts!)
        -d, --domain [string]   new dns domain (must be used with -i)
        -i, --ip [addr]         new IP address (must be used with -d)
        -r, --vsroot            location of "/vserver/" directory
        -R, --rsh               use rsh (instead of default ssh) for
                                network transport
        -s, --stopstart         stop the local vserver before copying and start
                                it on the destination host afterwards

EOF
}

full_version () {
    cat <<EOF
$me 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
}


### Default values and Command line options ###

stopstart=(false)
verbose=(false)
quiet=(false)
shcmd="ssh"
rsflag="-e"
rsh=(false)
colon=":"
domain=""
ip=""
vsroot="/vservers"

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

temp=$(getopt -o hVvqd:i:rRs --long 
help,version,verbose,quiet,domain:,ip:,vsroot,rsh,stopstart, -n $me -- "$@")

if [ $? -ne 0 ]; then
        echo "  (See -h for help)"
        exit 1
fi

# Note the quotes around `$temp': they are essential!
eval set -- "$temp"

while true; do
        case "$1" in
                -h|--help)      full_usage
                                exit 1
                                ;;
                -V|--version)   full_version
                                exit 1
                                ;;
                -v|--verbose)   verbose=(true)
                                shift
                                ;;
                -q|--quiet)     quiet=(true)
                                shift
                                ;;
                -d|--domain)    domain="$2"
                                shift 2
                                ;;
                -i|--ip)        ip="$2"
                                shift 2
                                ;;
                -r|--vsroot)    vsroot="$2"
                                shift 2
                                ;;
                -R|--rsh)       rsh=(true)
                                shift
                                ;;
                -s|--stopstart) stopstart=(true)
                                shift
                                ;;
                --)             shift
                                break
                                ;;
                *)              echo "Internal error!"
                                exit 1
                                ;;
        esac
done

if [ $# -ne 2 ]; then
        usage
        exit 1
fi


### ###

# By default we are reasonably quiet (ouput only via info, warn & error)
if $verbose; then
        interactive
else
        noninteractive
fi

now=$(date)
info "called on $(hostname) at $now"


vserver=$1
vconf=/etc/vservers/$vserver.conf
vroot=$vsroot/$vserver

if $rsh; then
        shcmd="rsh"
fi

if (echo $2 | grep '^[a-z][a-z0-9]\+$'); then
        dhost=""
        newname=$2
        shcmd=""
        rsflag=""
        colon=""
        if $rsh; then
                warn "rsh is set but not used for a local copy"
        fi
elif (echo $2 | grep '^[a-z].*[a-z0-9]:$'); then
        dhost=${2/:/}
        newname=$vserver
elif (echo $2 | grep '^[a-z].*[a-z0-9]:[a-z].*[a-z0-9]$'); then
        dhost=${2/:*/}
        newname=${2/*:/}
else
        error 1 "Second argument must be of the form \"host:[name]\" or \"newname\""
fi

target=$vsroot/$newname
targetconf=/etc/vservers/$newname.conf


### Perform some sanity checks ###

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

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

if [ -z "$dhost" ] && [ "$vserver" == "$newname" ]; then
        error 1 "Source and destination names cannot be the same on the localhost"
fi

if [ -n "$dhost" ] && ! (host $dhost | grep 'has address'); then
        warn "$dhost does not resolve into an IP address"
fi

if [ \( -n "$ip" -a -z "$domain" \) -o \
     \( -z "$ip" -a -n "$domain" \) ]
then
        error 1 "Both IP address and domain must be specified together"
fi

if [ -n "$ip" ] && \
! (echo $ip | grep '^[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}$' ); then
        error 1 "\"$ip\" is not a valid IP address"
fi

# This works both locally and remote
if ($shcmd $dhost /usr/sbin/vserver $newname running | grep 'is running'); then
        warn "destination vserver \"$newname\" is running" 
        error 1 "Cannot copy over a running vserver"
fi


### Do the copy ###

info "Attempting to copy $vserver to $dhost$colon$newname"

if $stopstart; then
        info "Stopping virtual server \"$vserver\" on localhost"
        /usr/sbin/vserver $vserver stop
fi

info "Syncing directories"
# trailing slashes very important in the rsync!
if ! rsync                      \
 --archive                      \
 --verbose                      \
 --one-file-system              \
 --delete                       \
 --compress                     \
 --numeric-ids                  \
 --progress $rsflag $shcmd $vroot/ $dhost$colon$target/; then
        error 1 "rsync failed"
fi

if [ -n "$ip" -a -n "$domain" ]; then
        # Insert the new IPROOT/S_HOSTNAME values into the config file
        info "Modifying $targetconf"
        tmpf=$(tempfile)
        if (sed -e "s/^S_HOSTNAME=.*/S_HOSTNAME=\"$newname\"/" \
                -e "s/^IPROOT=.*/IPROOT=\"$ip\"/" $vconf > $tmpf)
        then
                if ! rsync -v $rsflag $shcmd $tmpf $dhost$colon$targetconf; then
                        error $? "vserver config file copy/change failed"
                fi

        else
                warn "Unable to reconfigure virtual server config file"
        fi

        # create a new /etc/hostname
        info "Creating hostname file"
        echo $newname > $tmpf
        if ! rsync -v $rsflag $shcmd $tmpf $dhost$colon$target/etc/hostname; then
                error 1 "vserver /etc/hostname copy failed"
        fi

        info "Creating /etc/hosts"
        cat << EOF > $tmpf
# /etc/hosts (automatically generated by $me)

127.0.0.1       localhost
$ip     $newname.$domain        $newname

# The following lines are desirable for IPv6 capable hosts

::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
EOF

        # copy /etc/hosts
        if ! rsync -v $rsflag $shcmd $tmpf $dhost$colon$target/etc/hosts; then
                error 1 "vserver /etc/hosts copy failed"
        fi
        rm -f $tmpf

else
        if ! $stopstart; then
                # Make sure that this vserver doesn't start on the 
                # destination host if it reboots
                tmpf=$(tempfile)
                sed -e 's/^ONBOOT=.*/ONBOOT=no/' $vconf > $tmpf
                vconf=$tmpf
        fi

        # copy newname.conf unchanged
        info "Copying $targetconf"
        if ! rsync -v $rsflag $shcmd $vconf $dhost$colon$targetconf; then
                error 1 "vserver config file copy/change failed"
        fi

        rm -f $tmpf
fi


if $stopstart; then
        info "Starting virtual server \"$vserver\" on $dhost"
        $shcmd $dhost /usr/sbin/vserver $vserver start
        if ($shcmd $dhost /usr/sbin/vserver $vserver running | \
        grep 'not running'); then
                error 1 "Virtual server \"$vserver\" failed to start on $dhost"
        fi

        # Make sure that we don't start the original on next boot
        tmpf=$(tempfile)
        sed -e 's/^ONBOOT=.*/ONBOOT=no/' $vconf > $tmpf
        mv $tmpf $vconf
fi

exit 0
.TH "vserver-copy" "8" "0.5" "Mark Lawrence <[EMAIL PROTECTED]>" "System 
Administration"
.SH "NAME"
.LP 
vserver-copy \- copy/move a virtual server.
.SH "SYNTAX"
.LP 
vserver-copy [\fIoptions\fP] \fIvserver\fP \fInewname\fP 
.LP 
vserver-copy [\fIoptions\fP] \fIvserver\fP \fIhost\fP:[\fInewname\fP]
.SH "DESCRIPTION"
.LP 
vserver-copy makes a copy of a virtual server using rsync. It will
rewrite the vserver.conf configuration file with the new hostname and
IP information when given. If the destination name contains a host
specification then ssh/rsh will be used for the data transfer.

vserver-copy can used on a running vserver, although naturally the
consistency of open database files and the like cannot be guaranteed.
A running vserver can however be safely moved from one root host to another
using the \-s flag.

If downtime is an issue when moving a virtual server across hosts you
should first run vserver without the \-s flag. This will pre\-populate the
destination filesystem requiring only updates to be made on the next
invocation.
.SH "OPTIONS"
.LP 
.TP 
\fB\-h\fR,\fB-\-help\fR
output usage information and exit
.TP 
\fB\-V\fR,\fB-\-version\fR
output version information and exit
.TP 
\fB\-v\fR,\fB-\-verbose\fR
show all output (normally only informational messages and warnings)
.TP 
\fB\-q\fR,\fB-\-quiet\fR
suppress all output
.TP 
\fB\-d\fR,\fB-\-domain\fR domain
the new DNS domain when changing name. Overwrites /etc/hosts. Must be
used with \-i
.TP 
\fB\-i\fR,\fB-\-ip\fR address
the new IP address when changing name. Overwrites /etc/hosts. Must be
used with \-d
.TP 
\fB\-r\fR,\fB-\-vsroot\fR
directory containing virtual servers. Defaults to "/vserver"
.TP 
\fB\-R\fR,\fB-\-rsh\fR
use rsh instead of the default ssh for network transfer
.TP
\fB\-s\fR,\fB-\-stopstart\fR
stop the virtual server before copying and start the new vserver afterwards.
This really only makes sense if you are copying across root hosts and not
changing names or IP addresses.
.SH "FILES"
.LP 
\fI/etc/vservers/vserver.conf\fP 
.SH "EXAMPLES"
.LP 
# Copy a template vserver (same IP addresses etc)

/usr/sbin/vserver-copy template web01

# Copy webserver with change in configuration

/usr/sbin/vserver-copy -i 192.168.5.62 -d example.com template web62

# Move a running vserver to another roothost

/usr/sbin/vserver-copy -s web62 roothost02:

.SH "BUGS"
.LP 
If a virtual server is moved from one root host to another a gratuitious
ping should be sent to inform other devices on the local ethernet segment
of the change in MAC address.

Without this ping the devices will continue to attempt to reach the old
MAC address for the length of their arp-cache timeout (10 minute default
on Suns!).

This functionality should probably be implmemented during the 
"vserver <name> start" process.
.SH "AUTHOR"
.LP 
Mark Lawrence <[EMAIL PROTECTED]>
.SH "SEE ALSO"
.LP 
vserver(8)

Reply via email to