3 # Copyright (C) 2003 Mark Lawrence <nomad@null.net>,
4 # 2203,2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
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; either version 2, or (at your option)
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 # Copy/Sync a virtual host from one machine to another
24 # 2003-04-04: Version 0.4 - Mark lawrence
25 # - Set "ONBOOT=no" in the destination .conf file when --startstop
26 # is not used, in case the destination roothost reboots. We don't
27 # want two copies of a vserver running at the same time.
29 # 2003-03-04: Version 0.3 - Mark lawrence
30 # - Changed all checks for [ "" != "$var" ] into [ -n|-z "$var" ]. "" doesn't
31 # seem to work for bash on the Sparc architecture.
32 # - Changed $ssh variable into $shcmd.
34 # 2003-02-23: Version 0.2 - Mark Lawrence
35 # - Set ONBOOT to "no" in the original .conf file when the "-s" flag is
36 # used so that if/when you reboot the source roothost you don't have the
37 # same vserver and IP address running on two machines.
39 : ${UTIL_VSERVER_VARS:=$(dirname $0)/util-vserver-vars}
40 test -e "$UTIL_VSERVER_VARS" || {
41 echo "Can not find util-vserver installation; aborting..."
44 . "$UTIL_VSERVER_VARS"
50 mktemp="$(which mktemp 2>/dev/null) /tmp/vc.XXXXXX" || \
51 mktemp=$(which tempfile 2>/dev/null) || {
52 echo $"Can not find mktemp or tempfile" >&2
56 ### Helper functions ###
58 # Save stdin and stdout for later use
72 ! $quiet && echo "I: $me: $1" >&3
76 ! $quiet && echo "W: $me: $1" >&4
80 ! $quiet && echo "E: $me: $2" >&4
85 ### Usage/Info functions ###
89 Usage: $me [-hVvqidrRs] vserver newname
90 $me [-hVvqidrRs] vserver host:[newname]
98 $me uses rsync to make a copy of a vserver. If the destination
99 name contains a host specification the vserver will be synchronised to
100 the remote destination over ssh/rsh.
102 This can be used on a running vserver to make a warm backup. With the -s
103 flag a vserver can even be operationally moved to different hardware within
106 The -i and -d flags can be used to minimally reconfigure the destination
107 vserver (rewrites /etc/vservers/newname.conf and $VROOTDIR/newname/etc/hosts)
111 -V, --version copyright and version information
112 -v, --verbose show all output
113 -q, --quiet direct all output to /dev/null (no password
114 prompt for logins on remote hosts!)
115 -d, --domain [string] new dns domain (must be used with -i)
116 -i, --ip [addr] new IP address (must be used with -d)
117 -r, --vsroot location of "/vserver/" directory
118 -R, --rsh use rsh (instead of default ssh) for
120 -s, --stopstart stop the local vserver before copying and start
121 it on the destination host afterwards
129 Copyright (c) 2002 Mark Lawrence <nomad@null.net>
131 This program is free software; you can redistribute it and/or modify
132 it under the terms of the GNU General Public License as published by
133 the Free Software Foundation; either version 2 of the License, or (at
134 your option) any later version.
140 ### Default values and Command line options ###
153 if [ $# -eq 0 ]; then # Script invoked with no command-line args?
158 temp=$(getopt -o hVvqd:i:rRs --long help,version,verbose,quiet,domain:,ip:,vsroot,rsh,stopstart, -n $me -- "$@")
160 if [ $? -ne 0 ]; then
161 echo " (See -h for help)"
165 # Note the quotes around `$temp': they are essential!
170 -h|--help) full_usage
173 -V|--version) full_version
176 -v|--verbose) verbose=(true)
179 -q|--quiet) quiet=(true)
182 -d|--domain) domain="$2"
188 -r|--vsroot) vsroot="$2"
194 -s|--stopstart) stopstart=(true)
200 *) echo "Internal error!"
206 if [ $# -ne 2 ]; then
214 # By default we are reasonably quiet (ouput only via info, warn & error)
222 info "called on $(hostname) at $now"
226 vconf=/etc/vservers/$vserver.conf
227 vroot=$vsroot/$vserver
233 if (echo $2 | grep '^[a-z][a-z0-9]\+$'); then
240 warn "rsh is set but not used for a local copy"
242 elif (echo $2 | grep '^[a-z].*[a-z0-9]:$'); then
245 elif (echo $2 | grep '^[a-z].*[a-z0-9]:[a-z].*[a-z0-9]$'); then
249 error 1 "Second argument must be of the form \"[host:]name\" or \"host:\""
252 target=$vsroot/$newname
253 targetconf=/etc/vservers/$newname.conf
256 ### Perform some sanity checks ###
258 if [ ! -d $vroot ]; then
259 error 1 "Directory \"$vroot\" does not exist"
262 if [ ! -e $vconf ]; then
263 error 1 "Vserver file \"$vconf\" does not exist"
266 if [ -z "$dhost" ] && [ "$vserver" == "$newname" ]; then
267 error 1 "Source and destination names cannot be the same on the localhost"
270 if [ -n "$dhost" ] && ! (host $dhost | grep 'has address'); then
271 warn "$dhost does not resolve into an IP address"
274 if [ \( -n "$ip" -a -z "$domain" \) -o \
275 \( -z "$ip" -a -n "$domain" \) ]
277 error 1 "Both IP address and domain must be specified together"
281 ! (echo $ip | grep '^[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}$' ); then
282 error 1 "\"$ip\" is not a valid IP address"
285 # This works both locally and remote
286 if ($shcmd $dhost $SBINDIR/vserver $newname running | grep 'is running'); then
287 warn "destination vserver \"$newname\" is running"
288 error 1 "Cannot copy over a running vserver"
294 info "Attempting to copy $vserver to $dhost$colon$newname"
297 info "Stopping virtual server \"$vserver\" on localhost"
298 $SBINDIR/vserver $vserver stop
302 mkdir -p -m755 $target
306 info "Syncing directories"
307 # trailing slashes very important in the rsync!
308 if ! rsync -avxz $rsflag $shcmd $vroot/ $dhost$colon$target/; then
309 error 1 "rsync failed"
312 if [ -n "$ip" -a -n "$domain" ]; then
313 # Insert the new IPROOT/S_HOSTNAME values into the config file
314 info "Modifying $targetconf"
316 if (sed -e "s/^S_HOSTNAME=.*/S_HOSTNAME=\"$newname\"/" \
317 -e "s/^IPROOT=.*/IPROOT=\"$ip\"/" $vconf > $tmpf)
319 if ! rsync -v $rsflag $shcmd $tmpf $dhost$colon$targetconf; then
320 error $? "vserver config file copy/change failed"
324 warn "Unable to reconfigure virtual server config file"
327 # create a new /etc/hostname
328 info "Creating hostname file"
329 echo $newname > $tmpf
330 if ! rsync -v $rsflag $shcmd $tmpf $dhost$colon$target/etc/hostname; then
331 error 1 "vserver /etc/hostname copy failed"
334 info "Creating /etc/hosts"
336 # /etc/hosts (automatically generated by $me)
339 $ip $newname.$domain $newname
341 # The following lines are desirable for IPv6 capable hosts
343 ::1 ip6-localhost ip6-loopback
345 ff00::0 ip6-mcastprefix
347 ff02::2 ip6-allrouters
352 if ! rsync -v $rsflag $shcmd $tmpf $dhost$colon$target/etc/hosts; then
353 error 1 "vserver /etc/hosts copy failed"
358 if ! $stopstart; then
359 # Make sure that this vserver doesn't start on the
360 # destination host if it reboots
362 sed -e 's/^ONBOOT=.*/ONBOOT=no/' $vconf > $tmpf
366 # copy newname.conf unchanged
367 info "Copying $targetconf"
368 if ! rsync -v $rsflag $shcmd $vconf $dhost$colon$targetconf; then
369 error 1 "vserver config file copy/change failed"
377 info "Starting virtual server \"$vserver\" on $dhost"
378 $shcmd $dhost $SBINDIR/vserver $vserver start
379 if ($shcmd $dhost $SBINDIR/vserver $vserver running | \
380 grep 'not running'); then
381 error 1 "Virtual server \"$vserver\" failed to start on $dhost"
384 # Make sure that we don't start the original on next boot
386 sed -e 's/^ONBOOT=.*/ONBOOT=no/' $vconf > $tmpf