]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/API2/Qemu.pm
add scsi disk hotplug/unplug
[qemu-server.git] / PVE / API2 / Qemu.pm
index cd63cfba4c07a3177259adad326a2d2517d4c627..518a98244ca1a8596ae39014e7e4124a1b9c9af4 100644 (file)
@@ -150,16 +150,18 @@ __PACKAGE__->register_method({
                die "pipe requires cli environment\n" 
                    && $rpcenv->{type} ne 'cli';
            } else {
+               my $path;
                if (PVE::Storage::parse_volume_id($archive, 1)) {
-                   $archive = PVE::Storage::path($storecfg, $archive);
+                   $path = PVE::Storage::path($storecfg, $archive);
                } else {
                    raise_param_exc({ archive => "Only root can pass arbitrary paths." }) 
                        if $user ne 'root@pam';
 
-                   $archive = abs_path($archive);
+                   $path = abs_path($archive);
                }
-               die "can't find file '$archive'\n" if ! -f $archive;
-           } 
+               die "can't find archive file '$archive'\n" if !($path && -f $path);
+               $archive = $path;
+           }
        }
 
        my $restorefn = sub {
@@ -264,6 +266,7 @@ __PACKAGE__->register_method({
            { subdir => 'migrate' },
            { subdir => 'rrd' },
            { subdir => 'rrddata' },
+           { subdir => 'monitor' },
            ];
        
        return $res;
@@ -530,7 +533,7 @@ __PACKAGE__->register_method({
                } 
                next if !defined($conf->{$opt});
                if (PVE::QemuServer::valid_drivename($opt)) {
-                   PVE::QemuServer::vm_devicedel($vmid, $conf, $opt);
+                   PVE::QemuServer::vm_deviceunplug($vmid, $conf, $opt);
                    my $drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt});
                    if (PVE::QemuServer::drive_is_cdrom($drive)) {
                        $cdchange->{$opt} = undef;
@@ -619,6 +622,10 @@ __PACKAGE__->register_method({
        my $storecfg = PVE::Storage::config(); 
 
        my $realcmd = sub {
+           my $upid = shift;
+
+           syslog('info', "destroy VM $vmid: $upid\n");
+
            PVE::QemuServer::vm_destroy($storecfg, $vmid, $skiplock);
        };
 
@@ -694,11 +701,14 @@ __PACKAGE__->register_method({
        my $rpcenv = PVE::RPCEnvironment::get();
 
        my $user = $rpcenv->get_user();
-       my $ticket = PVE::AccessControl::assemble_ticket($user);
 
        my $vmid = $param->{vmid};
        my $node = $param->{node};
 
+       my $authpath = "/vms/$vmid";
+
+       my $ticket = PVE::AccessControl::assemble_vnc_ticket($user, $authpath);
+
        $sslcert = PVE::Tools::file_get_contents("/etc/pve/pve-root-ca.pem", 8192)
            if !$sslcert;
 
@@ -706,7 +716,7 @@ __PACKAGE__->register_method({
 
        my $remip;
        
-       if ($node ne PVE::INotify::nodename()) {
+       if ($node ne 'localhost' && $node ne PVE::INotify::nodename()) {
            $remip = PVE::Cluster::remote_node_ip($node);
        }
 
@@ -804,9 +814,17 @@ __PACKAGE__->register_method({
        # test if VM exists
        my $conf = PVE::QemuServer::load_config($param->{vmid});
 
-       my $vmstatus =  PVE::QemuServer::vmstatus($param->{vmid});
+       my $vmstatus = PVE::QemuServer::vmstatus($param->{vmid});
+       my $status = $vmstatus->{$param->{vmid}};
+
+       my $cc = PVE::Cluster::cfs_read_file('cluster.conf');
+       if (PVE::Cluster::cluster_conf_lookup_pvevm($cc, 0, $param->{vmid}, 1)) {
+           $status->{ha} = 1;
+       } else {
+           $status->{ha} = 0;
+       }
 
-       return $vmstatus->{$param->{vmid}};
+       return $status;
     }});
 
 __PACKAGE__->register_method({
@@ -880,6 +898,12 @@ __PACKAGE__->register_method({
                type => 'integer',
                minimum => 0,
                optional => 1,
+           },
+           keepActive => {
+               description => "Do not decativate storage volumes.",
+               type => 'boolean',
+               optional => 1,
+               default => 0,
            }
        },
     },
@@ -901,27 +925,19 @@ __PACKAGE__->register_method({
        raise_param_exc({ skiplock => "Only root may use this option." }) 
            if $skiplock && $user ne 'root@pam';
 
+       my $keepActive = extract_param($param, 'keepActive');
+       raise_param_exc({ keepActive => "Only root may use this option." }) 
+           if $keepActive && $user ne 'root@pam';
+
+       my $storecfg = PVE::Storage::config();
+
        my $realcmd = sub {
            my $upid = shift;
 
            syslog('info', "stop VM $vmid: $upid\n");
 
-           PVE::QemuServer::vm_stop($vmid, $skiplock);
-
-           my $pid = PVE::QemuServer::check_running ($vmid);
-
-           if ($pid && $param->{timeout}) {
-               print "waiting until VM $vmid stopps (PID $pid)\n";
-
-               my $count = 0;
-               while (($count < $param->{timeout}) && 
-                      PVE::QemuServer::check_running($vmid)) {
-                   $count++;
-                   sleep 1;
-               }
-
-               die "wait failed - got timeout\n" if PVE::QemuServer::check_running($vmid);
-           }
+           PVE::QemuServer::vm_stop($storecfg, $vmid, $skiplock, 0, 
+                                    $param->{timeout}, 0, 1, $keepActive);
 
            return;
        };
@@ -962,11 +978,11 @@ __PACKAGE__->register_method({
        raise_param_exc({ skiplock => "Only root may use this option." }) 
            if $skiplock && $user ne 'root@pam';
 
+       die "VM $vmid not running\n" if !PVE::QemuServer::check_running($vmid);
+
        my $realcmd = sub {
            my $upid = shift;
 
-           syslog('info', "reset VM $vmid: $upid\n");
-
            PVE::QemuServer::vm_reset($vmid, $skiplock);
 
            return;
@@ -993,6 +1009,18 @@ __PACKAGE__->register_method({
                type => 'integer',
                minimum => 0,
                optional => 1,
+           },
+           forceStop => {
+               description => "Make sure the VM stops.",
+               type => 'boolean',
+               optional => 1,
+               default => 0,
+           },
+           keepActive => {
+               description => "Do not decativate storage volumes.",
+               type => 'boolean',
+               optional => 1,
+               default => 0,
            }
        },
     },
@@ -1014,27 +1042,19 @@ __PACKAGE__->register_method({
        raise_param_exc({ skiplock => "Only root may use this option." }) 
            if $skiplock && $user ne 'root@pam';
 
+       my $keepActive = extract_param($param, 'keepActive');
+       raise_param_exc({ keepActive => "Only root may use this option." }) 
+           if $keepActive && $user ne 'root@pam';
+
+       my $storecfg = PVE::Storage::config();
+
        my $realcmd = sub {
            my $upid = shift;
 
            syslog('info', "shutdown VM $vmid: $upid\n");
 
-           PVE::QemuServer::vm_shutdown($vmid, $skiplock);
-
-           my $pid = PVE::QemuServer::check_running ($vmid);
-
-           if ($pid && $param->{timeout}) {
-               print "waiting until VM $vmid stopps (PID $pid)\n";
-
-               my $count = 0;
-               while (($count < $param->{timeout}) && 
-                      PVE::QemuServer::check_running($vmid)) {
-                   $count++;
-                   sleep 1;
-               }
-
-               die "wait failed - got timeout\n" if PVE::QemuServer::check_running($vmid);
-           }
+           PVE::QemuServer::vm_stop($storecfg, $vmid, $skiplock, 0, $param->{timeout}, 
+                                    1, $param->{forceStop}, $keepActive);
 
            return;
        };
@@ -1075,6 +1095,8 @@ __PACKAGE__->register_method({
        raise_param_exc({ skiplock => "Only root may use this option." }) 
            if $skiplock && $user ne 'root@pam';
 
+       die "VM $vmid not running\n" if !PVE::QemuServer::check_running($vmid);
+
        my $realcmd = sub {
            my $upid = shift;
 
@@ -1121,6 +1143,8 @@ __PACKAGE__->register_method({
        raise_param_exc({ skiplock => "Only root may use this option." }) 
            if $skiplock && $user ne 'root@pam';
 
+       die "VM $vmid not running\n" if !PVE::QemuServer::check_running($vmid);
+
        my $realcmd = sub {
            my $upid = shift;
 
@@ -1223,12 +1247,16 @@ __PACKAGE__->register_method({
 
        my $vmid = extract_param($param, 'vmid');
 
-       raise_param_exc({ force => "Only root may use this option." }) if $user ne 'root@pam';
+       raise_param_exc({ force => "Only root may use this option." }) 
+           if $param->{force} && $user ne 'root@pam';
 
        # test if VM exists
-       PVE::QemuServer::load_config($vmid);
+       my $conf = PVE::QemuServer::load_config($vmid);
 
        # try to detect errors early
+
+       PVE::QemuServer::check_lock($conf);
+
        if (PVE::QemuServer::check_running($vmid)) {
            die "cant migrate running VM without --online\n" 
                if !$param->{online};
@@ -1237,7 +1265,7 @@ __PACKAGE__->register_method({
        my $realcmd = sub {
            my $upid = shift;
 
-           PVE::QemuMigrate::migrate($target, $targetip, $vmid, $param->{online}, $param->{force});
+           PVE::QemuMigrate->migrate($target, $targetip, $vmid, $param);
        };
 
        my $upid = $rpcenv->fork_worker('qmigrate', $vmid, $user, $realcmd);
@@ -1245,4 +1273,39 @@ __PACKAGE__->register_method({
        return $upid;
     }});
 
+__PACKAGE__->register_method({
+    name => 'monitor', 
+    path => '{vmid}/monitor', 
+    method => 'POST',
+    protected => 1,
+    proxyto => 'node',
+    description => "Execute Qemu monitor commands.",
+    parameters => {
+       additionalProperties => 0,
+       properties => {
+           node => get_standard_option('pve-node'),
+           vmid => get_standard_option('pve-vmid'),
+           command => {
+               type => 'string',
+               description => "The monitor command.",
+           }
+       },
+    },
+    returns => { type => 'string'},
+    code => sub {
+       my ($param) = @_;
+
+       my $vmid = $param->{vmid};
+
+       my $conf = PVE::QemuServer::load_config ($vmid); # check if VM exists
+
+       my $res = '';
+       eval {
+           $res = PVE::QemuServer::vm_monitor_command($vmid, $param->{command});
+       };
+       $res = "ERROR: $@" if $@;
+
+       return $res;
+    }});
+
 1;