/[vz-tools]/trunk/vz-clone.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/vz-clone.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 24 - (hide annotations)
Thu Oct 4 18:54:41 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 3651 byte(s)
rsync know how to handle device and special files, ssync doesn't.
So it's out...
1 dpavlin 20 #!/usr/bin/perl -w
2    
3     use strict;
4 dpavlin 24 use Shell qw/rsync vzlist lvcreate mount umount lvremove which lvdisplay mke2fs/;
5 dpavlin 20
6     my $vz = '/vz';
7     my $conf = '/etc/vz/conf';
8    
9 dpavlin 21 my $snap_size = '100M';
10    
11 dpavlin 20 my $VEID = shift @ARGV || die "Usage: $0 VEID\n\n",vzlist;
12    
13 dpavlin 21 my $CVEID = "10$VEID";
14 dpavlin 20
15     my $orig_conf = "/etc/vz/conf/$VEID.conf";
16    
17     die "$VEID config $orig_conf doesn't exist\n" unless -e $orig_conf;
18    
19     print "Clone VE $VEID -> $CVEID\n";
20    
21 dpavlin 21 my $vz_lv;
22 dpavlin 20
23 dpavlin 21 open(my $m, '<', '/etc/fstab') || die "can't open /etc/fstab: $!";
24     while(<$m>) {
25     next if m/^#/;
26     my @v = split(/\s+/,$_);
27     if ( $v[1] =~ m/\Q$vz\E/ ) {
28     $vz_lv = $v[0];
29 dpavlin 23 warn "found LV $vz_lv for $vz\n";
30 dpavlin 21 last;
31     }
32     }
33    
34 dpavlin 23 sub fs_quota {
35     my $id = shift;
36     open(my $q, '-|', "vzquota -b show $id") || die "can't exec vzquota show $id: $!";
37     my $l = <$q>;
38     $l =~ s/^\s+//;
39     my ( $usage, $soft, $hard ) = split(/\s+/,$l);
40     warn "quota for $id | $soft < $hard | usage: $usage\n";
41     return ( $usage, $soft, $hard ) if wantarray;
42     return $soft;
43     }
44    
45 dpavlin 21 sub copy_files {
46     my ( $from, $to ) = @_;
47 dpavlin 24 warn "rsync $from -> $to\n";
48     rsync('-raSHAD', "$from/", "$to/" );
49 dpavlin 21 }
50    
51     if ( $vz_lv ) {
52    
53     my ( $vz_lv_path, $vz_lv_name ) = ( $1, $2 ) if ( $vz_lv =~ m!^(.+)/([^/]+)$! );
54    
55     my $snap = $vz_lv_name . '-snap';
56 dpavlin 23 my $clone = "$vz_lv_name-clone-$CVEID";
57    
58     sub do_mount {
59     my ( $from, $to ) = @_;
60     mkdir $to || die "can't create $to: $!";
61     print "Mounting $from to $to\n";
62     mount( $from, $to, '-o', 'noatime' );
63     }
64    
65     sub test_mkdir {
66     my $dir = shift;
67     if ( ! -d $dir ) {
68     mkdir $dir || die "can't mkdir $dir: $!";
69     }
70     }
71    
72     sub mount_bind {
73     my ( $from, $to ) = @_;
74     die "$from doesn't exist!" unless -d $from;
75     test_mkdir( $to );
76     mount( '--bind', $from, $to );
77     }
78    
79 dpavlin 21 print "Creating $snap_size snapshot $snap from $vz_lv\n";
80     lvcreate( '--size', $snap_size, '--snapshot', '--name', $snap, $vz_lv );
81    
82 dpavlin 23 do_mount( "$vz_lv_path/$snap", "/tmp/$snap" );
83 dpavlin 21
84 dpavlin 23 my $clone_size = fs_quota( $VEID ) . 'k';
85     my $vg_name = $1 if ( $vz_lv_path =~ m!/([^/]+)/*$! );
86 dpavlin 21
87 dpavlin 23 if ( lvdisplay( "$vz_lv_path/$clone" ) ) {
88     warn "using existing $vz_lv_path/$clone\n";
89     } else {
90     print "Creating LV $clone ($clone_size bytes) in VG $vg_name for $VEID clone filesystem\n";
91     lvcreate( '--size', $clone_size, '--name', $clone, $vg_name );
92     mke2fs( '-m', 0, '-j', "$vz_lv_path/$clone" );
93     }
94 dpavlin 21
95 dpavlin 23 do_mount( "$vz_lv_path/$clone", "/tmp/$clone" );
96 dpavlin 21
97 dpavlin 23 test_mkdir( "/tmp/$clone/private" );
98     test_mkdir( "/tmp/$clone/root" );
99 dpavlin 21
100 dpavlin 23 mount_bind( "/tmp/$clone/private", "$vz/private/$CVEID" );
101     mount_bind( "/tmp/$clone/root", "$vz/root/$CVEID" );
102 dpavlin 21
103 dpavlin 23 copy_files( "/tmp/$snap/private/$VEID", "$vz/private/$CVEID" );
104    
105     print "Cleanup\n";
106    
107 dpavlin 24 #umount( "$vz_lv_path/$clone" );
108 dpavlin 23 umount( "$vz_lv_path/$snap" );
109    
110 dpavlin 21 lvremove( '-f', "$vz_lv_path/$snap" );
111    
112     } else {
113    
114     copy_files( "$vz/private/$VEID", "$vz/private/$CVEID" );
115     }
116    
117     my $note = "# modified by $0\n";
118    
119 dpavlin 20 sub fix_ip {
120     my $ip = shift;
121 dpavlin 21 $ip =~ s/['"]//g;
122 dpavlin 20 $ip =~ s/^\d+\./10./;
123     warn "$CVEID new IP number: $ip\n";
124 dpavlin 21 return $note . qq{IP_ADDRESS="$ip"};
125 dpavlin 20 }
126    
127 dpavlin 21 sub fix_hostname {
128     my $hostname = shift;
129     $hostname =~ s/['"]//g;
130     $hostname = "clone-$hostname";
131     warn "$CVEID new hostname: $hostname\n";
132     return $note . qq{HOSTNAME="$hostname"};
133     }
134    
135 dpavlin 20 open(my $o, '<', "$conf/$VEID.conf") || die "can't open $conf/$VEID.conf: $!";
136     open(my $n, '>', "$conf/$CVEID.conf") || die "can't open $conf/$CVEID.conf: $!";
137     while(<$o>) {
138 dpavlin 21 s!^HOSTNAME=(.*)$!fix_hostname($1)!ie;
139     s!^IP_ADDRESS=(.*)$!fix_ip($1)!ie;
140     s!^(ONBOOT=).*$!# modified by $0\n$1"no"!i;
141 dpavlin 20 print $n $_;
142     }
143    
144 dpavlin 22 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"

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26