[pve-devel] [PATCH v3 qemu-server 2/7] migrate : prepare : add create_vm for external migration

Alexandre Derumier aderumier at odiso.com
Tue Nov 27 16:38:04 CET 2018


Create vm on target cluster with same options.
Disks are created with same size and same options than source
---
 PVE/QemuMigrate.pm | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 83 insertions(+), 5 deletions(-)

diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm
index e9e9075..922d76c 100644
--- a/PVE/QemuMigrate.pm
+++ b/PVE/QemuMigrate.pm
@@ -227,6 +227,89 @@ sub prepare {
 	}
     }
 
+    # test ssh connection
+    my $cmd = [ @{$self->{rem_ssh}}, '/bin/true' ];
+    eval { $self->cmd_quiet($cmd); };
+    die "Can't connect to destination address using public key\n" if $@;
+
+    if($self->{opts}->{migration_external}) {
+
+	#get remote nextvmid
+	eval {
+	    my $cmd = [@{$self->{rem_ssh}}, 'pvesh', 'get', '/cluster/nextid'];
+	    PVE::Tools::run_command($cmd, outfunc => sub {
+		my $line = shift;
+		if ($line =~ m/^(\d+)/) {
+		    $self->{opts}->{targetvmid} = $line;
+		}
+	    });
+	};
+        if (my $err = $@) {
+            $self->log('err', $err);
+            $self->{errors} = 1;
+            die $err;
+        }
+
+	die "can't find the next free vmid on remote cluster\n" if !$self->{opts}->{targetvmid};
+
+	#create vm
+	my $cmd = [@{$self->{rem_ssh}}, 'qm', 'create', $self->{opts}->{targetvmid}];
+
+	foreach my $opt (keys %{$conf}) {
+	    next if $opt =~ m/^(pending|snapshots|digest|parent)/;
+	    next if $opt =~ m/^(ide|scsi|virtio)(\d+)/;
+
+	    if ($opt =~ m/^(net)(\d+)/ && $self->{opts}->{targetbridge}) {
+		my $netid = "net$2";
+		my $d = PVE::QemuServer::parse_net($conf->{$netid});
+		$d->{bridge} = $self->{opts}->{targetbridge};
+		$conf->{$opt} = PVE::QemuServer::print_net($d);
+	    }
+
+	    die "can't migrate unused disk. please remove it before migrate\n" if $opt =~ m/^(unused)(\d+)/;
+	    push @$cmd , "-$opt", PVE::Tools::shellquote($conf->{$opt});
+	}
+
+	PVE::QemuServer::foreach_drive($conf, sub {
+	    my ($ds, $drive) = @_;
+
+	    if (PVE::QemuServer::drive_is_cdrom($drive, 1)) {
+		push @$cmd , "-$ds", PVE::Tools::shellquote($conf->{$ds});
+		return;
+	    }
+
+	    my $volid = $drive->{file};
+	    return if !$volid;
+
+	    my ($sid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
+	    return if !$sid;
+	    my $size = PVE::Storage::volume_size_info($self->{storecfg}, $volid, 5);
+	    die "can't get size\n" if !$size;
+	    $size = $size/1024/1024/1024;
+	    my $targetsid = $self->{opts}->{targetstorage} ? $self->{opts}->{targetstorage} : $sid;
+
+	    my $data = { %$drive };
+	    delete $data->{$_} for qw(index interface file size);
+	    my $drive_conf = "$targetsid:$size";
+            foreach my $drive_opt (keys %{$data}) {
+		$drive_conf .= ",$drive_opt=$data->{$drive_opt}";
+	    }
+
+	    push @$cmd , "-$ds", PVE::Tools::shellquote($drive_conf);
+	});
+
+	push @$cmd , '-lock', 'migrate';
+
+	eval{ PVE::Tools::run_command($cmd, outfunc => sub {}, errfunc => sub {}) };
+	if (my $err = $@) {
+	    $self->log('err', $err);
+	    $self->{errors} = 1;
+	    die $err;
+	}
+
+	return 1;
+    }
+
     my $vollist = PVE::QemuServer::get_vm_volumes($conf);
 
     my $need_activate = [];
@@ -253,11 +336,6 @@ sub prepare {
     # activate volumes
     PVE::Storage::activate_volumes($self->{storecfg}, $need_activate);
 
-    # test ssh connection
-    my $cmd = [ @{$self->{rem_ssh}}, '/bin/true' ];
-    eval { $self->cmd_quiet($cmd); };
-    die "Can't connect to destination address using public key\n" if $@;
-
     return $running;
 }
 
-- 
2.11.0




More information about the pve-devel mailing list