[pve-devel] [PATCH 2/3] api2 : add spiceproxy
Alexandre Derumier
aderumier at odiso.com
Wed Apr 10 13:08:10 CEST 2013
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 <aderumier at 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
More information about the pve-devel
mailing list