create a tunnel with socat.

then call "qm spiceticket" to remote host to generate the ticket. (ticket is 
returned with json)

fixme:

- Each spice connections need 4 channels,so socat use fork.
  They are no  concurrent connection limit in current debian socat.
  Last socat version have a max-worker option.

- I don't known how to close socat if connection is not established

Signed-off-by: Alexandre Derumier <aderum...@odiso.com>
---
 PVE/API2/Qemu.pm |   82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 62e8d0d..ebf502a 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -1,8 +1,10 @@
+
 package PVE::API2::Qemu;
 
 use strict;
 use warnings;
 use Cwd 'abs_path';
+use JSON;
 
 use PVE::Cluster qw (cfs_read_file cfs_write_file);;
 use PVE::SafeSyslog;
@@ -639,6 +641,7 @@ __PACKAGE__->register_method({
            { subdir => 'rrddata' },
            { subdir => 'monitor' },
            { subdir => 'snapshot' },
+           { subdir => 'spiceproxy' },
            ];
 
        return $res;
@@ -731,6 +734,85 @@ __PACKAGE__->register_method({
            "pve2-vm/$param->{vmid}", $param->{timeframe}, $param->{cf});
     }});
 
+__PACKAGE__->register_method({
+    name => 'spiceproxy',
+    path => '{vmid}/spiceproxy',
+    method => 'GET',
+    protected => 1,
+    permissions => {
+        check => ['perm', '/vms/{vmid}', [ 'VM.Console' ]],
+    },
+    description => "Create a proxy for spice socket and return spice config",
+    parameters => {
+       additionalProperties => 0,
+       properties => {
+           node => get_standard_option('pve-node'),
+           vmid => get_standard_option('pve-vmid'),
+       },
+    },
+    returns => { type => 'object' },
+    code => sub {
+       my ($param) = @_;
+
+        my $node = extract_param($param, 'node');
+        my $vmid = extract_param($param, 'vmid');
+
+        my $rpcenv = PVE::RPCEnvironment::get();
+        my $authuser = $rpcenv->get_user();
+
+        my $remip;
+
+        if ($node ne 'localhost' && $node ne PVE::INotify::nodename()) {
+            $remip = PVE::Cluster::remote_node_ip($node);
+        }
+
+       my $socket = PVE::QemuServer::spice_socket($vmid);
+       my $port = PVE::Tools::next_vnc_port();
+
+        my $realcmd = sub {
+            my $upid = shift;
+
+            syslog('info', "starting spice proxy $upid\n");
+
+           #socat 1.7.2.1 support max-children, we need 4 channels for spice. 
(debian package is too old)
+           #my $cmd = ['/usr/bin/socat', '-d', '-d', 
"TCP-LISTEN:$port,reuseaddr,fork,max-children=4"];
+
+           my $cmd = ['/usr/bin/socat', '-d', '-d', 
"TCP-LISTEN:$port,reuseaddr,fork"];
+           my $remotesocket = $remip ? "EXEC:'ssh root@$remip socat STDIO 
UNIX-CONNECT:$socket'" : "UNIX-CONNECT:$socket";
+           push @$cmd, $remotesocket;
+
+           my $parser = sub {
+               my $line = shift;
+               print $line."\n";
+               die "Client is disconnect" if ($line =~ /exiting with status 
0/);
+           };
+
+           #fixme : how to setup a connect wait timeout ?
+           PVE::Tools::run_command($cmd, errfunc => $parser, outfunc => sub{});
+
+            return;
+        };
+
+        my $upid = $rpcenv->fork_worker('spiceproxy', $vmid, $authuser, 
$realcmd);
+
+
+        my $remcmd = $remip ? ['/usr/bin/ssh', '-T', '-o', 'BatchMode=yes', 
$remip] : [];
+       my $qmcmd = [@$remcmd, "/usr/sbin/qm", 'spiceticket', $vmid];
+       my $qmstr = join(' ', @$qmcmd);
+       my $out = "";
+       PVE::Tools::run_command($qmstr, outfunc => sub { $out .= shift; });
+
+       my $config = from_json($out);
+       my $proxyname = `hostname -f` || PVE::INotify::nodename();
+       chomp $proxyname;
+
+       $config->{type} = 'spice';
+       $config->{proxy} = "http://$proxyname:3128";;
+       $config->{host} = 'localhost';
+       $config->{port} = $port;
+       return $config;
+
+    }});
 
 __PACKAGE__->register_method({
     name => 'vm_config',
-- 
1.7.10.4

_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to