--- trunk/vz-clone.pl 2007/10/04 11:30:05 20 +++ trunk/vz-clone.pl 2007/10/04 13:12:08 21 @@ -1,14 +1,16 @@ #!/usr/bin/perl -w use strict; -use Shell qw/rsync vzlist/; +use Shell qw/rsync vzlist lvcreate mount umount lvremove/; my $vz = '/vz'; my $conf = '/etc/vz/conf'; +my $snap_size = '100M'; + my $VEID = shift @ARGV || die "Usage: $0 VEID\n\n",vzlist; -my $CVEID = "99$VEID"; +my $CVEID = "10$VEID"; my $orig_conf = "/etc/vz/conf/$VEID.conf"; @@ -16,22 +18,80 @@ print "Clone VE $VEID -> $CVEID\n"; -rsync('-ra', "$vz/private/$VEID", "$vz/private/$CVEID" ); +my $vz_lv; + +open(my $m, '<', '/etc/fstab') || die "can't open /etc/fstab: $!"; +while(<$m>) { + next if m/^#/; + my @v = split(/\s+/,$_); + if ( $v[1] =~ m/\Q$vz\E/ ) { + $vz_lv = $v[0]; + warn "found lv $vz_lv for $vz\n"; + last; + } +} + +sub copy_files { + my ( $from, $to ) = @_; + warn "rsync $from -> $to\n"; + rsync('-ra', "$from/", "$to/" ); +} + +if ( $vz_lv ) { + + my ( $vz_lv_path, $vz_lv_name ) = ( $1, $2 ) if ( $vz_lv =~ m!^(.+)/([^/]+)$! ); + + my $snap = $vz_lv_name . '-snap'; + + print "Creating $snap_size snapshot $snap from $vz_lv\n"; + + lvcreate( '--size', $snap_size, '--snapshot', '--name', $snap, $vz_lv ); + + my $snap_path = "/tmp/$snap"; + mkdir $snap_path || die "can't create $snap_path: $!"; + + print "Mounting $vz_lv_path/$snap to $snap_path\n"; + + mount( "$vz_lv_path/$snap", $snap_path, '-o', 'noatime' ); + + copy_files( "$snap_path/private/$VEID", "$vz/private/$CVEID" ); + + print "Umount $snap_path and remove $vz_lv_path/$snap\n"; + + umount( $snap_path ); + + lvremove( '-f', "$vz_lv_path/$snap" ); + +} else { + + copy_files( "$vz/private/$VEID", "$vz/private/$CVEID" ); +} + +my $note = "# modified by $0\n"; sub fix_ip { my $ip = shift; + $ip =~ s/['"]//g; $ip =~ s/^\d+\./10./; warn "$CVEID new IP number: $ip\n"; - return qq{IP_ADDRESS=$ip}; + return $note . qq{IP_ADDRESS="$ip"}; +} + +sub fix_hostname { + my $hostname = shift; + $hostname =~ s/['"]//g; + $hostname = "clone-$hostname"; + warn "$CVEID new hostname: $hostname\n"; + return $note . qq{HOSTNAME="$hostname"}; } open(my $o, '<', "$conf/$VEID.conf") || die "can't open $conf/$VEID.conf: $!"; open(my $n, '>', "$conf/$CVEID.conf") || die "can't open $conf/$CVEID.conf: $!"; while(<$o>) { - s!^(HOSTNAME=)(.*)$!$1clone-$2!i; - s!^(IP_ADDRESS=.*)$!fix_up($1)!e; - s!^(ONBOOT=).*$!# modified by $0\n$1="no"!gi; + s!^HOSTNAME=(.*)$!fix_hostname($1)!ie; + s!^IP_ADDRESS=(.*)$!fix_ip($1)!ie; + s!^(ONBOOT=).*$!# modified by $0\n$1"no"!i; print $n $_; } -print "Please edit config $conf/$CVEID.conf before vzctl start $CVEID\n" +print "\nPlease review config file: $conf/$CVEID.conf\nStart clone of $VEID with: vzctl start $CVEID\n"