mirror of
https://git.proxmox.com/git/qemu-server
synced 2025-05-03 10:29:59 +00:00
implement copy_vm
This is based on patches from Alexandre Derumier <aderumier@odiso.com>. It just implements copy/clone for stopped VMs and Templates. Copying running VMs or copy from snapshots is not implemented.
This commit is contained in:
parent
5133de429e
commit
b83e0181f1
@ -1867,20 +1867,22 @@ __PACKAGE__->register_method({
|
|||||||
if -f $conffile;
|
if -f $conffile;
|
||||||
|
|
||||||
# create empty/temp config - this fails if VM already exists on other node
|
# create empty/temp config - this fails if VM already exists on other node
|
||||||
PVE::Tools::file_set_contents($conffile, "# qmcopy temporary file\n");
|
PVE::Tools::file_set_contents($conffile, "# qmcopy temporary file\nlock: copy\n");
|
||||||
|
|
||||||
my $realcmd = sub {
|
my $realcmd = sub {
|
||||||
my $upid = shift;
|
my $upid = shift;
|
||||||
|
|
||||||
eval {
|
my $newvollist = [];
|
||||||
print "COPY VM $vmid start\n";
|
|
||||||
|
|
||||||
my $newconf = {};
|
eval {
|
||||||
|
my $newconf = { lock => 'copy' };
|
||||||
my $drives = {};
|
my $drives = {};
|
||||||
my $vollist = [];
|
my $vollist = [];
|
||||||
foreach my $opt (keys %$conf) {
|
foreach my $opt (keys %$conf) {
|
||||||
my $value = $conf->{$opt};
|
my $value = $conf->{$opt};
|
||||||
|
|
||||||
|
next if $opt eq 'snapshots'; # do not copy snapshot info
|
||||||
|
|
||||||
# always change MAC! address
|
# always change MAC! address
|
||||||
if ($opt =~ m/^net(\d+)$/) {
|
if ($opt =~ m/^net(\d+)$/) {
|
||||||
my $net = PVE::QemuServer::parse_net($value);
|
my $net = PVE::QemuServer::parse_net($value);
|
||||||
@ -1903,21 +1905,51 @@ __PACKAGE__->register_method({
|
|||||||
|
|
||||||
PVE::Storage::activate_volumes($storecfg, $vollist);
|
PVE::Storage::activate_volumes($storecfg, $vollist);
|
||||||
|
|
||||||
foreach my $opt (keys %$drives) {
|
eval {
|
||||||
my $drive = $drives->{$opt};
|
local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub { die "interrupted by signal\n"; };
|
||||||
print "COPY drive $opt: $drive->{file}\n";
|
|
||||||
|
|
||||||
}
|
foreach my $opt (keys %$drives) {
|
||||||
|
my $drive = $drives->{$opt};
|
||||||
|
|
||||||
sleep(10);
|
my $newvolid;
|
||||||
|
if (!$param->{full} && PVE::Storage::volume_is_base($storecfg, $drive->{file})) {
|
||||||
|
print "clone drive $opt ($drive->{file})\n";
|
||||||
|
$newvolid = PVE::Storage::vdisk_clone($storecfg, $drive->{file}, $newid);
|
||||||
|
} else {
|
||||||
|
my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file});
|
||||||
|
my $defformat = PVE::Storage::storage_default_format($storecfg, $storeid);
|
||||||
|
my $fmt = $drive->{format} || $defformat;
|
||||||
|
|
||||||
|
my ($size) = PVE::Storage::volume_size_info($storecfg, $drive->{file}, 3);
|
||||||
|
|
||||||
|
print "copy drive $opt ($drive->{file})\n";
|
||||||
|
$newvolid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $newid, $fmt, undef, ($size/1024));
|
||||||
|
|
||||||
|
PVE::QemuServer::qemu_img_convert($drive->{file}, $newvolid, $size);
|
||||||
|
}
|
||||||
|
|
||||||
|
my ($size) = PVE::Storage::volume_size_info($storecfg, $newvolid, 3);
|
||||||
|
my $disk = { file => $newvolid, size => $size };
|
||||||
|
$newconf->{$opt} = PVE::QemuServer::print_drive($vmid, $disk);
|
||||||
|
push @$newvollist, $newvolid;
|
||||||
|
|
||||||
|
PVE::QemuServer::update_config_nolock($newid, $newconf, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
die $@ if $@;
|
||||||
|
|
||||||
|
delete $newconf->{lock};
|
||||||
PVE::QemuServer::update_config_nolock($newid, $newconf, 1);
|
PVE::QemuServer::update_config_nolock($newid, $newconf, 1);
|
||||||
|
|
||||||
print "COPY VM $vmid end\n";
|
|
||||||
};
|
};
|
||||||
if (my $err = $@) {
|
if (my $err = $@) {
|
||||||
# fixme: remove all created files
|
|
||||||
unlink $conffile;
|
unlink $conffile;
|
||||||
|
|
||||||
|
sleep 1; # some storage like rbd need to wait before release volume - really?
|
||||||
|
|
||||||
|
foreach my $volid (@$newvollist) {
|
||||||
|
eval { PVE::Storage::vdisk_free($storecfg, $volid); };
|
||||||
|
warn $@ if $@;
|
||||||
|
}
|
||||||
die "copy failed: $err";
|
die "copy failed: $err";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user