implement openvz migrate

This commit is contained in:
Dietmar Maurer 2011-11-17 14:36:25 +01:00
parent c0ef5e6aab
commit 8350ac0022
6 changed files with 131 additions and 20 deletions

View File

@ -9,6 +9,8 @@ use Cwd 'abs_path';
use PVE::SafeSyslog;
use PVE::Tools qw(extract_param run_command);
use PVE::Exception qw(raise raise_param_exc);
use PVE::INotify;
use PVE::Cluster qw(cfs_lock_file cfs_read_file);
use PVE::Storage;
use PVE::RESTHandler;
@ -372,7 +374,7 @@ __PACKAGE__->register_method({
PVE::Cluster::log_msg('info', $user, "update CT $vmid: " . join(' ', @$changes));
PVE::Tools::run_command($cmd);
run_command($cmd);
};
PVE::OpenVZ::lock_container($vmid, $code);
@ -681,7 +683,7 @@ __PACKAGE__->register_method({
my $realcmd = sub {
my $cmd = ['vzctl', 'destroy', $vmid ];
PVE::Tools::run_command($cmd);
run_command($cmd);
};
return $rpcenv->fork_worker('vzdestroy', $vmid, $user, $realcmd);
@ -756,7 +758,7 @@ __PACKAGE__->register_method ({
'-timeout', $timeout, '-authpath', "/vms/$vmid",
'-perm', 'VM.Console', '-c', @$remcmd, @$shcmd];
PVE::Tools::run_command($cmd);
run_command($cmd);
return;
};
@ -913,7 +915,9 @@ __PACKAGE__->register_method({
my $cmd = ['vzctl', 'start', $vmid];
PVE::Tools::run_command($cmd);
run_command($cmd);
return;
};
return $rpcenv->fork_worker('vzstart', $vmid, $user, $realcmd);
@ -961,7 +965,7 @@ __PACKAGE__->register_method({
push @$cmd, '--fast' if $param->{fast};
PVE::Tools::run_command($cmd);
run_command($cmd);
return;
};
@ -971,4 +975,75 @@ __PACKAGE__->register_method({
return $upid;
}});
__PACKAGE__->register_method({
name => 'migrate_vm',
path => '{vmid}/migrate',
method => 'POST',
protected => 1,
proxyto => 'node',
description => "Migrate the container to another node. Creates a new migration task.",
parameters => {
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
vmid => get_standard_option('pve-vmid'),
target => get_standard_option('pve-node', { description => "Target node." }),
online => {
type => 'boolean',
description => "Use online/live migration.",
optional => 1,
},
},
},
returns => {
type => 'string',
description => "the task ID.",
},
code => sub {
my ($param) = @_;
my $rpcenv = PVE::RPCEnvironment::get();
my $user = $rpcenv->get_user();
my $target = extract_param($param, 'target');
my $localnode = PVE::INotify::nodename();
raise_param_exc({ target => "target is local node."}) if $target eq $localnode;
PVE::Cluster::check_cfs_quorum();
PVE::Cluster::check_node_exists($target);
my $targetip = PVE::Cluster::remote_node_ip($target);
my $vmid = extract_param($param, 'vmid');
# test if VM exists
PVE::OpenVZ::load_config($vmid);
# try to detect errors early
if (PVE::OpenVZ::check_running($vmid)) {
die "cant migrate running container without --online\n"
if !$param->{online};
}
my $realcmd = sub {
my $upid = shift;
my $cmd = ['/usr/sbin/vzmigrate'];
push @$cmd, '--online' if $param->{online};
push @$cmd, $targetip;
push @$cmd, $vmid;
run_command($cmd);
return;
};
my $upid = $rpcenv->fork_worker('vzmigrate', $vmid, $user, $realcmd);
return $upid;
}});
1;

View File

@ -72,6 +72,24 @@ sub check_mounted {
return (-d "$root/etc" || -d "$root/proc");
}
# warning: this is slow
sub check_running {
my ($vmid) = @_;
if (my $fh = new IO::File ("/proc/vz/vestat", "r")) {
while (defined (my $line = <$fh>)) {
if ($line =~ m/^\s*(\d+)\s+/) {
if ($vmid == $1) {
close($fh);
return 1;
}
}
}
close($fh);
}
return undef;
}
sub get_privatedir {
my ($conf, $vmid) = @_;

View File

@ -62,7 +62,7 @@ JSSRC= \
tree/ResourceTree.js \
panel/ConfigPanel.js \
grid/BackupView.js \
panel/LogView.js \
panel/LogView.js \
node/DNSEdit.js \
node/DNSView.js \
node/TimeView.js \
@ -76,7 +76,7 @@ JSSRC= \
node/Tasks.js \
node/Config.js \
qemu/StatusView.js \
qemu/Migrate.js \
window/Migrate.js \
qemu/Monitor.js \
qemu/Summary.js \
qemu/OSTypeEdit.js \

View File

@ -55,6 +55,18 @@ Ext.define('PVE.openvz.Config', {
}
});
var migrateBtn = Ext.create('Ext.Button', {
text: 'Migrate',
handler: function() {
var win = Ext.create('PVE.window.Migrate', {
vmtype: 'openvz',
nodename: nodename,
vmid: vmid
});
win.show();
}
});
var removeBtn = Ext.create('PVE.button.Button', {
text: 'Remove',
confirmMsg: 'Are you sure you want to remove VM ' +
@ -84,7 +96,8 @@ Ext.define('PVE.openvz.Config', {
title: "OpenVZ container " + vmid + descr +
" on node '" + nodename + "'",
hstateid: 'ovztab',
tbar: [ startBtn, stopBtn, shutdownBtn, removeBtn, consoleBtn ],
tbar: [ startBtn, stopBtn, shutdownBtn, migrateBtn,
removeBtn, consoleBtn ],
defaults: { statusStore: me.statusStore },
items: [
{

View File

@ -50,8 +50,10 @@ Ext.define('PVE.qemu.Config', {
var migrateBtn = Ext.create('Ext.Button', {
text: 'Migrate',
handler: function() {
var win = Ext.create('PVE.qemu.Migrate', {
pveSelNode: me.pveSelNode
var win = Ext.create('PVE.window.Migrate', {
vmtype: 'qemu',
nodename: nodename,
vmid: vmid
});
win.show();
}
@ -102,7 +104,8 @@ Ext.define('PVE.qemu.Config', {
title: "Virtual machine " + descr + "'KVM " + vmid +
"' on node '" + nodename + "'",
hstateid: 'kvmtab',
tbar: [ startBtn, stopBtn, migrateBtn, resetBtn, shutdownBtn, removeBtn, consoleBtn ],
tbar: [ startBtn, stopBtn, resetBtn, shutdownBtn,
migrateBtn, removeBtn, consoleBtn ],
defaults: { statusStore: me.statusStore },
items: [
{

View File

@ -1,13 +1,13 @@
Ext.define('PVE.qemu.Migrate', {
Ext.define('PVE.window.Migrate', {
extend: 'Ext.window.Window',
resizable: false,
migrate: function(vmid, nodename, target, online) {
migrate: function(target, online) {
var me = this;
PVE.Utils.API2Request({
params: { target: target, online: online },
url: '/nodes/' + nodename + '/qemu/' + vmid + "/migrate",
url: '/nodes/' + me.nodename + '/' + me.vmtype + '/' + me.vmid + "/migrate",
waitMsgTarget: me,
method: 'POST',
failure: function(response, opts) {
@ -28,16 +28,18 @@ Ext.define('PVE.qemu.Migrate', {
initComponent : function() {
var me = this;
var nodename = me.pveSelNode.data.node;
if (!nodename) {
if (!me.nodename) {
throw "no node name specified";
}
var vmid = me.pveSelNode.data.vmid;
if (!vmid) {
if (!me.vmid) {
throw "no VM ID specified";
}
if (!me.vmtype) {
throw "no VM type specified";
}
me.formPanel = Ext.create('Ext.form.Panel', {
bodyPadding: 10,
border: false,
@ -69,12 +71,12 @@ Ext.define('PVE.qemu.Migrate', {
text: 'Migrate',
handler: function() {
var values = form.getValues();
me.migrate(vmid, nodename, values.target, values.online);
me.migrate(values.target, values.online);
}
});
Ext.apply(me, {
title: "Migrate KVM " + vmid,
title: "Migrate VM " + me.vmid,
width: 350,
modal: true,
layout: 'auto',