[pve-devel] [PATCH 1/2] add spiceproxy api2

Alexandre Derumier aderumier at odiso.com
Fri Jun 21 10:32:02 CEST 2013


open a socat tunnel
return spice ticket

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

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 076356c..71b6e5b 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -1,8 +1,11 @@
+
 package PVE::API2::Qemu;
 
 use strict;
 use warnings;
 use Cwd 'abs_path';
+use JSON;
+use MIME::Base64;
 
 use PVE::Cluster qw (cfs_read_file cfs_write_file);;
 use PVE::SafeSyslog;
@@ -497,6 +500,7 @@ __PACKAGE__->register_method({
 	    { subdir => 'rrddata' },
 	    { subdir => 'monitor' },
 	    { subdir => 'snapshot' },
+	    { subdir => 'spiceproxy' },
 	    ];
 
 	return $res;
@@ -589,6 +593,86 @@ __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 $authpath = "/vms/$vmid";
+
+        my $ticket = PVE::AccessControl::assemble_spice_ticket($authuser, $authpath);
+
+        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 ($proxysocket, $proxyid) = PVE::Tools::next_spiceproxy_socket();
+
+	die "spice proxy socket is already in use\n" if -e $proxysocket;
+
+
+        my $realcmd = sub {
+            my $upid = shift;
+
+            syslog('info', "starting spice proxy $upid\n");
+
+	    my $cmd = ['/usr/bin/socat', '-d', '-d', "UNIX-LISTEN:$proxysocket,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/);
+	    };
+	    eval {
+		local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub { die "interrupted by signal\n"; };
+	    	#fixme : how to setup a connect wait timeout ?
+	    	PVE::Tools::run_command($cmd, errfunc => $parser, outfunc => sub{});
+	    };
+	    if ($@) {
+		unlink $proxysocket if -e $proxysocket;
+	    }
+        };
+
+        my $upid = $rpcenv->fork_worker('spiceproxy', $vmid, $authuser, $realcmd);
+
+
+	my $proxyname = `hostname -f` || PVE::INotify::nodename();
+	chomp $proxyname;
+
+	my $config = {};
+	$config->{type} = 'spice';
+	$config->{proxy} = "http://$proxyname:3128";
+	$config->{host} = $ticket;
+	$config->{port} = $proxyid;
+	return $config;
+
+    }});
 
 __PACKAGE__->register_method({
     name => 'vm_config',
-- 
1.7.10.4




More information about the pve-devel mailing list