]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/API2/Qemu.pm
use STDIN to pass spice ticket
[qemu-server.git] / PVE / API2 / Qemu.pm
index b371dc8c23f5eecbe30230d2ae2bafe4e5d092c7..1111970101dc6937ced35210cd126b0b58354fba 100644 (file)
@@ -3,6 +3,7 @@ package PVE::API2::Qemu;
 use strict;
 use warnings;
 use Cwd 'abs_path';
+use Net::SSLeay;
 
 use PVE::Cluster qw (cfs_read_file cfs_write_file);;
 use PVE::SafeSyslog;
@@ -1337,16 +1338,22 @@ __PACKAGE__->register_method({
        properties => {
            node => get_standard_option('pve-node'),
            vmid => get_standard_option('pve-vmid'),
+           proxy => {
+               description => "This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As resonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).",
+               type => 'string', format => 'dns-name',
+               optional => 1,
+           },
        },
     },
     returns => {
+       description => "Returned values can be directly passed to the 'remote-viewer' application.",
        additionalProperties => 1,
        properties => {
            type => { type => 'string' },
            password => { type => 'string' },
            proxy => { type => 'string' },
            host => { type => 'string' },
-           port => { type => 'integer' },
+           'tls-port' => { type => 'integer' },
        },
     },
     code => sub {
@@ -1358,39 +1365,38 @@ __PACKAGE__->register_method({
 
        my $vmid = $param->{vmid};
        my $node = $param->{node};
-
-        my $remip;
-
-       # Note: we currectly use "proxyto => 'node'", so this code will never trigger
-        if ($node ne 'localhost' && $node ne PVE::INotify::nodename()) {
-            $remip = PVE::Cluster::remote_node_ip($node);
-        }
+       my $proxy = $param->{proxy};
 
        my ($ticket, $proxyticket) = PVE::AccessControl::assemble_spice_ticket($authuser, $vmid, $node);
 
        my $timeout = 10;
 
-       # Note: this only works if VM is on local node
+       my $port = PVE::QemuServer::spice_port($vmid);
        PVE::QemuServer::vm_mon_cmd($vmid, "set_password", protocol => 'spice', password => $ticket);
        PVE::QemuServer::vm_mon_cmd($vmid, "expire_password", protocol => 'spice', time => "+30");
 
-       # allow access for group www-data to the spice socket,
-       # so that spiceproxy can access it
-       my $socket =  PVE::QemuServer::spice_socket($vmid);
-       my $gid = getgrnam('www-data') || die "getgrnam failed - $!\n";
-       chown 0, $gid, $socket;
-       chmod 0770, $socket;
+       if (!$proxy) {
+           my $host = `hostname -f` || PVE::INotify::nodename();
+           chomp $host;
+           $proxy = $host;
+       }
+
+       my $filename = "/etc/pve/local/pve-ssl.pem";
+       my $subject = PVE::QemuServer::read_x509_subject_spice($filename);
 
-       # fimxe: ??
-       my $host = `hostname -f` || PVE::INotify::nodename();
-       chomp $host;
+       my $cacert = PVE::Tools::file_get_contents("/etc/pve/pve-root-ca.pem", 8192);
+       $cacert =~ s/\n/\\n/g;
 
        return {
            type => 'spice',
-           host => $proxyticket,
-           proxy => "http://$host:3128",
-           port => 1, # not used for now
-           password => $ticket
+           title => "VM $vmid",
+           host => $proxyticket, # this break tls hostname verification, so we need to use 'host-subject'
+           proxy => "http://$proxy:3128",
+           'tls-port' => $port,
+           'host-subject' => $subject,
+           ca => $cacert,
+           password => $ticket,
+           'delete-this-file' => 1,
        };
     }});
 
@@ -1474,9 +1480,7 @@ __PACKAGE__->register_method({
 
        $status->{ha} = &$vm_is_ha_managed($param->{vmid});
 
-       if ($conf->{vga} && ($conf->{vga} eq 'qxl')) {
-           $status->{spice} = 1;
-       }
+       $status->{spice} = 1 if PVE::QemuServer::vga_conf_has_spice($conf->{vga});
 
        return $status;
     }});
@@ -1530,6 +1534,14 @@ __PACKAGE__->register_method({
        raise_param_exc({ migratedfrom => "Only root may use this option." })
            if $migratedfrom && $authuser ne 'root@pam';
 
+       # read spice ticket from STDIN
+       my $spice_ticket;
+       if ($stateuri && ($stateuri eq 'tcp') && $migratedfrom && ($rpcenv->{type} eq 'cli')) {
+           my $line = <>;
+           chomp $line;
+           $spice_ticket = $line if $line;
+       }
+
        my $storecfg = PVE::Storage::config();
 
        if (&$vm_is_ha_managed($vmid) && !$stateuri &&
@@ -1558,7 +1570,8 @@ __PACKAGE__->register_method({
 
                syslog('info', "start VM $vmid: $upid\n");
 
-               PVE::QemuServer::vm_start($storecfg, $vmid, $stateuri, $skiplock, $migratedfrom, undef, $machine);
+               PVE::QemuServer::vm_start($storecfg, $vmid, $stateuri, $skiplock, $migratedfrom, undef, 
+                                         $machine, $spice_ticket);
 
                return;
            };