]> git.proxmox.com Git - qemu-server.git/blame - qmupdate
bump version to 2.0-72
[qemu-server.git] / qmupdate
CommitLineData
1e3baf05
DM
1#!/usr/bin/perl -w
2
3use strict;
4use IO::File;
fc1ddcdc 5use Digest::SHA;
1e3baf05
DM
6
7# script to upgrade V0.9.1 to V0.9.2 format
8
9my $confvars_0_9_1 = {
10 onboot => 'bool',
11 autostart => 'bool',
12 reboot => 'bool',
13 cpulimit => 'natural',
14 cpuunits => 'natural',
15 hda => 'file',
16 hdb => 'file',
17 sda => 'file',
18 sdb => 'file',
19 cdrom => 'file',
20 memory => 'natural',
21 keyboard => 'lang',
22 name => 'string',
23 ostype => 'ostype',
24 boot => 'boot',
25 smp => 'natural',
26 acpi => 'bool',
27 network => 'network',
28};
29
30sub load_config_0_9_1 {
31 my ($vmid, $filename) = @_;
32
33 my $fh = new IO::File ($filename, "r") ||
34 return undef;
35
36 my $res = {};
37
38 while (my $line = <$fh>) {
39
40 next if $line =~ m/^\#/;
41
42 next if $line =~ m/^\s*$/;
43
44 if ($line =~ m/^([a-z]+):\s*(\S+)\s*$/) {
45 my $key = $1;
46 my $value = $2;
47 if (my $type = $confvars_0_9_1->{$key}) {
48 $res->{$key} = $value;
49 } else {
50 return undef; # unknown setting
51 }
52 }
53 }
54
55 return $res;
56}
57
58sub parse_network_0_9_1 {
59 my ($data) = @_;
60
61 my $res = {
62 type => 'tap',
63 };
64 foreach my $rec (split (/\s*,\s*/, $data)) {
65 if ($rec =~ m/^(tap|user)$/) {
66 $res->{type} = $rec;
67 } elsif ($rec =~ m/^model\s*=\s*(ne2k_pci|e1000|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)$/) {
68 $res->{model} = $1;
69 } elsif ($rec =~ m/macaddr\s*=\s*([0-9a-f:]+)/i) {
70 $res->{macaddr} = $1;
71 } else {
72 return undef;
73 }
74 }
75
76 return $res;
77}
78
79sub random_ether_addr {
80
fc1ddcdc 81 my $rand = Digest::SHA::sha1_hex (rand(), time());
1e3baf05
DM
82
83 my $mac = '';
84 for (my $i = 0; $i < 6; $i++) {
85 my $ss = hex (substr ($rand, $i*2, 2));
86 if (!$i) {
87 $ss &= 0xfe; # clear multicast
88 $ss |= 2; # set local id
89 }
90 $ss = sprintf ("%02X", $ss);
91
92 if (!$i) {
93 $mac .= "$ss";
94 } else {
95 $mac .= ":$ss";
96 }
97 }
98
99 return $mac;
100}
101
102sub convert_0_9_1_to_0_9_2 {
103 my ($vmid, $cfile, $conf) = @_;
104
105 print "Upgrading VM $vmid to new format\n";
106
107 die "undefined vm id" if !$vmid || $vmid !~ m/^\d+$/;
108
109 my $dmap = {
110 hda => 'ide0',
111 hdb => 'ide1',
112 sda => 'scsi0',
113 sdb => 'scsi1',
114 };
115
116 my $tmpdir = "/var/lib/vz/images/$vmid.upgrade";
117 my $tmpconf = "$cfile.upgrade";
118
119 my $images = [];
120
121 eval {
122 mkdir $tmpdir || die "unable to create dir '$tmpdir'\n";
123
124 my $fh = new IO::File ($cfile, "r") ||
125 die "unable to read config for VM $vmid\n";
126 my $newfh = new IO::File ($tmpconf, "w") ||
127 die "unable to create file '$tmpconf'\n";
128
129 while (my $line = <$fh>) {
130
131 next if $line =~ m/^\#/;
132
133 next if $line =~ m/^\s*$/;
134
135 if ($line =~ m/^([a-z]+):\s*(\S+)\s*$/) {
136 my $key = $1;
137 my $value = $2;
138 if (my $type = $confvars_0_9_1->{$key}) {
139 if ($key eq 'network') {
140 my $onw = parse_network_0_9_1 ($value);
141 if ($onw && ($onw->{type} eq 'tap')) {
142 if (!$onw->{macaddr}) {
143 $onw->{macaddr} = random_ether_addr ();
144 }
145 print $newfh "vlan0: $onw->{model}=$onw->{macaddr}\n";
146 } elsif ($onw && ($onw->{type} eq 'user')) {
147 if (!$onw->{macaddr}) {
148 $onw->{macaddr} = random_ether_addr ();
149 }
150 print $newfh "vlanu: $onw->{model}=$onw->{macaddr}\n";
151 } else {
152 die "unable to convert network specification\n";
153 }
154 } elsif ($key eq 'cdrom') {
155 $value =~ s|^/.*/||;
156 print $newfh "ide2: $value,media=cdrom\n";
157 } elsif (defined ($dmap->{$key})) {
158 if ($value =~ m|^/var/lib/vz/images/([^/]+)$|) {
159 $value = $1;
160 } elsif ($value !~ m|/|) {
161 # no nothing
162 } else {
163 die "wrong image path";
164 }
165
166 link "/var/lib/vz/images/$value", "$tmpdir/$value";
167
168 (-f "$tmpdir/$value") ||
169 die "unable to create image link\n";
170
171 push @$images, $value;
172
173 print $newfh "$dmap->{$key}: $value\n";
174 } else {
175 print $newfh "$key: $value\n";
176 }
177 } else {
178 die "unknown setting '$key'\n";
179 }
180 }
181 }
182
183 if ($conf->{hda}) {
184 print $newfh "bootdisk: ide0\n";
185 } elsif ($conf->{hdb}) {
186 print $newfh "bootdisk: ide1\n";
187 } elsif ($conf->{sda}) {
188 print $newfh "bootdisk: scsi0\n";
189 } elsif ($conf->{sdb}) {
190 print $newfh "bootdisk: scsi1\n";
191 }
192 };
193
194 my $err = $@;
195
196 if ($err) {
197 system ("rm -rf $tmpdir $tmpconf");
198 } else {
199
200 if (!rename $tmpdir, "/var/lib/vz/images/$vmid") {
201 system ("rm -rf $tmpdir $tmpconf");
202 die "commiting '/var/lib/vz/images/$vmid' failed - $!\n";
203 }
204 if (!rename $tmpconf, $cfile) {
205 system ("rm -rf /var/lib/vz/images/$vmid $tmpconf");
206 die "commiting new configuration '$cfile' failed - $!\n";
207 }
208
209 foreach my $img (@$images) {
210 unlink "/var/lib/vz/images/$img";
211 }
212 }
213 die $err if $err;
214}
215
216foreach my $vmconf (</etc/qemu-server/*.conf>) {
217 next if $vmconf !~ m|/etc/qemu-server/(\d+)\.conf|;
218 my $vmid = $1;
219 next if -d "/var/lib/vz/images/$vmid"; # already new format
220
221 eval {
222 my $res = load_config_0_9_1 ($vmid, $vmconf);
223
224 if ($res && ($res->{network} || $res->{hda} || $res->{hdb} ||
225 $res->{sda} || $res->{sda} || $res->{cdrom})) {
226 convert_0_9_1_to_0_9_2 ($vmid, $vmconf, $res);
227 }
228 };
229
230 warn $@ if $@;
231}
232
233exit 0;
234