--- trunk/vz-clone.pl 2007/10/04 23:19:33 25 +++ trunk/vz-clone.pl 2009/02/27 20:05:02 65 @@ -6,40 +6,51 @@ my $vz = '/vz'; my $conf = '/etc/vz/conf'; -my $snap_size = '100M'; +my $snap_size = '1G'; my ( $action, $VEID ) = @ARGV; -my $valid_actions = 'create|umount|destroy'; +my $use_snapshot = 1; + +my $valid_actions = 'create|mount|umount|destroy'; die "Usage: $0 ($valid_actions) VEID\n\n",vzlist unless $VEID && $action && $action =~ m/($valid_actions)/; -if ( $action eq 'destroy' ) { +my $CVEID = "10$VEID"; + +sub vzctl_stop { + my $veid = shift; my $vzlist = vzlist(); - if ( $vzlist =~ m/$VEID/ ) { - print "stop $VEID\n"; - vzctl('stop', $VEID); + if ( $vzlist =~ m/$veid/ ) { + print "stop $veid\n"; + vzctl('stop', $veid); } } -if ( $action =~ m/(umount|destroy)/ ) { +if ( $action eq 'create' ) { + vzctl_stop( $CVEID ); +} elsif ( $action eq 'destroy' ) { + vzctl_stop( $VEID ); +} + + +if ( $action =~ m/(create|umount|destroy)/ ) { my $clone; open(my $m, '-|', 'mount') || die "can't open mount: $!"; while(<$m>) { my @v = split(/\s+/,$_); - if ( $v[2] =~ m!/(private|root)/$VEID$! && $v[5] =~ m/bind/ ) { + if ( $v[2] =~ m{/(private|root)/$CVEID$} && $v[5] =~ m/bind/ ) { umount( $v[2] ); - } elsif ( $v[2] =~ m!-clone-$VEID$! ) { + } elsif ( $v[2] =~ m{vz-clone-$CVEID$} ) { $clone = $v[2]; } } umount( $clone ) if $clone; -} + lvremove( '-f', $clone ); -#die "unknown action: $action" unless $action eq 'create'; -exit unless $action eq 'create'; + exit if $action eq 'umount'; +} -my $CVEID = "10$VEID"; my $orig_conf = "/etc/vz/conf/$VEID.conf"; @@ -73,16 +84,17 @@ sub copy_files { my ( $from, $to ) = @_; + return if $action ne 'create'; warn "rsync $from -> $to\n"; - rsync('-raSHAD', "$from/", "$to/" ); + rsync('-raSHAD', '--delete', "$from/", "$to/" ); } if ( $vz_lv ) { - my ( $vz_lv_path, $vz_lv_name ) = ( $1, $2 ) if ( $vz_lv =~ m!^(.+)/([^/]+)$! ); + my ( $vz_lv_path, $vz_lv_name ) = ( $1, $2 ) if ( $vz_lv =~ m{^(.+)/([^/]+)$} ); my $snap = $vz_lv_name . '-snap'; - my $clone = "$vz_lv_name-clone-$CVEID"; + my $clone = "vz-clone-$CVEID"; sub do_mount { my ( $from, $to ) = @_; @@ -105,51 +117,58 @@ mount( '--bind', $from, $to ); } - print "Creating $snap_size snapshot $snap from $vz_lv\n"; - lvcreate( '--size', $snap_size, '--snapshot', '--name', $snap, $vz_lv ); + if ( $use_snapshot ) { - do_mount( "$vz_lv_path/$snap", "/tmp/$snap" ); + print "Creating $snap_size snapshot $snap from $vz_lv\n"; + lvcreate( '--size', $snap_size, '--snapshot', '--name', $snap, $vz_lv ); - my $clone_size = fs_quota( $VEID ) . 'k'; - my $vg_name = $1 if ( $vz_lv_path =~ m!/([^/]+)/*$! ); + do_mount( "$vz_lv_path/$snap", "/tmp/$snap" ); + + mount_bind( "/tmp/$snap/private/$VEID", "$vz/private/$CVEID" ); + mount_bind( "/tmp/$snap/root/$VEID", "$vz/root/$CVEID" ); - if ( lvdisplay( "$vz_lv_path/$clone" ) ) { - warn "using existing $vz_lv_path/$clone\n"; } else { - print "Creating LV $clone ($clone_size bytes) in VG $vg_name for $VEID clone filesystem\n"; - lvcreate( '--size', $clone_size, '--name', $clone, $vg_name ); - mke2fs( '-m', 0, '-j', "$vz_lv_path/$clone" ); - } - do_mount( "$vz_lv_path/$clone", "/tmp/$clone" ); - - test_mkdir( "/tmp/$clone/private" ); - test_mkdir( "/tmp/$clone/root" ); + if ( lvdisplay( "$vz_lv_path/$clone" ) ) { + warn "using existing $vz_lv_path/$clone\n"; + } else { + my $vg_name = $1 if ( $vz_lv_path =~ m{/([^/]+)/*$} ); + my $clone_size = fs_quota( $VEID ) . 'k'; + print "Creating LV $clone ($clone_size bytes) in VG $vg_name for $VEID clone filesystem\n"; + lvcreate( '--size', $clone_size, '--name', $clone, $vg_name ); + mke2fs( '-m', 0, '-j', "$vz_lv_path/$clone" ); + } - mount_bind( "/tmp/$clone/private", "$vz/private/$CVEID" ); - mount_bind( "/tmp/$clone/root", "$vz/root/$CVEID" ); + do_mount( "$vz_lv_path/$clone", "/tmp/$clone" ); - copy_files( "/tmp/$snap/private/$VEID", "$vz/private/$CVEID" ); + test_mkdir( "/tmp/$clone/private" ); + test_mkdir( "/tmp/$clone/root" ); - print "Cleanup\n"; + copy_files( "$vz/private/$VEID", "/tmp/$clone/private" ); - #umount( "$vz_lv_path/$clone" ); - umount( "$vz_lv_path/$snap" ); + mount_bind( "/tmp/$clone/private", "$vz/private/$CVEID" ); + mount_bind( "/tmp/$clone/root", "$vz/root/$CVEID" ); - lvremove( '-f', "$vz_lv_path/$snap" ); + } } else { copy_files( "$vz/private/$VEID", "$vz/private/$CVEID" ); } +exit if $action eq 'mount'; + my $note = "# modified by $0\n"; +my $ve_clone_ip; + sub fix_ip { my $ip = shift; $ip =~ s/['"]//g; - $ip =~ s/^\d+\./10./; +# $ip =~ s/^\d+\./10./; + $ip =~ s/^\d+\.\d+\./192.168./; warn "$CVEID new IP number: $ip\n"; + $ve_clone_ip = $ip; return $note . qq{IP_ADDRESS="$ip"}; } @@ -164,10 +183,12 @@ 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=(.*)$!fix_hostname($1)!ie; - s!^IP_ADDRESS=(.*)$!fix_ip($1)!ie; - s!^(ONBOOT=).*$!# modified by $0\n$1"no"!i; + 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 "\nPlease review config file: $conf/$CVEID.conf\nAdd NAT for new VE with: iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE\nStart clone of $VEID with: vzctl start $CVEID\n" +print $n qq{DISK_QUOTA="no"\n} if $use_snapshot; # don't wait for quota rebuild on startup + +print "\nPlease review config file: $conf/$CVEID.conf\nAdd NAT for new VE with: iptables -t nat -A POSTROUTING -s $ve_clone_ip -o eth0 -j MASQUERADE\nStart clone of $VEID with: vzctl start $CVEID\n"