open a socat tunnel return spice ticket Signed-off-by: Alexandre Derumier <aderum...@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 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel