Commit 2af1b905 authored by Dietmar Maurer's avatar Dietmar Maurer

include spiceterm

parent c6533543
......@@ -83,7 +83,7 @@ __PACKAGE__->register_method ({
path => 'version',
method => 'GET',
permissions => { user => 'all' },
description => "API version details",
description => "API version details. The result also includes the global datacenter confguration.",
parameters => {
additionalProperties => 0,
properties => {},
......@@ -99,6 +99,13 @@ __PACKAGE__->register_method ({
code => sub {
my ($resp, $param) = @_;
return PVE::pvecfg::version_info();
my $res = PVE::Cluster::cfs_read_file('datacenter.cfg');
my $vi = PVE::pvecfg::version_info();
foreach my $k (qw(version release repoid)) {
$res->{$k} = $vi->{$k};
}
return $res;
}});
1;
......@@ -119,6 +119,7 @@ __PACKAGE__->register_method ({
{ name => 'rrd' }, # fixme: remove?
{ name => 'rrddata' },# fixme: remove?
{ name => 'vncshell' },
{ name => 'spiceshell' },
{ name => 'time' },
{ name => 'dns' },
{ name => 'services' },
......@@ -767,6 +768,137 @@ __PACKAGE__->register_method ({
};
}});
__PACKAGE__->register_method ({
name => 'spiceshell',
path => 'spiceshell',
method => 'POST',
protected => 1,
proxyto => 'node',
permissions => {
description => "Restricted to users on realm 'pam'",
check => ['perm', '/nodes/{node}', [ 'Sys.Console' ]],
},
description => "Creates a spice shell.",
parameters => {
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
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,
},
upgrade => {
type => 'boolean',
description => "Run 'apt-get dist-upgrade' instead of normal shell.",
optional => 1,
default => 0,
},
},
},
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' },
'tls-port' => { type => 'integer' },
},
},
code => sub {
my ($param) = @_;
my $rpcenv = PVE::RPCEnvironment::get();
my $authuser = $rpcenv->get_user();
my ($user, undef, $realm) = PVE::AccessControl::verify_username($authuser);
raise_perm_exc("realm != pam") if $realm ne 'pam';
raise_perm_exc('user != root@pam') if $param->{upgrade} && $user ne 'root@pam';
my $node = $param->{node};
my $proxy = $param->{proxy};
if (!$proxy) {
my $host = `hostname -f` || PVE::INotify::nodename();
chomp $host;
$proxy = $host;
}
my $authpath = "/nodes/$node";
my ($ticket, $proxyticket) = PVE::AccessControl::assemble_spice_ticket($authuser, 0, $node);
my $filename = "/etc/pve/local/pve-ssl.pem";
my $subject = PVE::QemuServer::read_x509_subject_spice($filename);
my $cacert = PVE::Tools::file_get_contents("/etc/pve/pve-root-ca.pem", 8192);
$cacert =~ s/\n/\\n/g;
my $port = PVE::Tools::next_spice_port();
my $shcmd;
if ($user eq 'root@pam') {
if ($param->{upgrade}) {
my $upgradecmd = "pveupgrade --shell";
$shcmd = [ '/bin/bash', '-c', $upgradecmd ];
} else {
$shcmd = [ '/bin/bash', '-l' ];
}
} else {
$shcmd = [ '/bin/login' ];
}
my $timeout = 10;
my $cmd = ['/usr/bin/spiceterm', '--port', $port, '--addr', '127.0.0.1',
'--timeout', $timeout, '--authpath', $authpath,
'--permissions', 'Sys.Console', '--', @$shcmd];
my $realcmd = sub {
my $upid = shift;
syslog ('info', "starting spiceterm $upid\n");
my $cmdstr = join (' ', @$cmd);
syslog ('info', "launch command: $cmdstr");
eval {
foreach my $k (keys %ENV) {
next if $k eq 'PATH' || $k eq 'TERM' || $k eq 'USER' || $k eq 'HOME';
delete $ENV{$k};
}
$ENV{PWD} = '/';
$ENV{SPICE_TICKET} = $ticket;
PVE::Tools::run_command($cmd, errmsg => "spiceterm failed");
};
if (my $err = $@) {
syslog ('err', $err);
}
return;
};
my $upid = $rpcenv->fork_worker('spiceshell', "", $user, $realcmd);
PVE::Tools::wait_for_vnc_port($port);
return {
type => 'spice',
title => "Shell on '$node'",
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,
};
}});
__PACKAGE__->register_method({
name => 'dns',
path => 'dns',
......
......@@ -3,7 +3,7 @@ Version: @VERSION@-@PACKAGERELEASE@
Section: admin
Priority: optional
Architecture: amd64
Depends: perl (>= 5.10.0-19), libtimedate-perl, libauthen-pam-perl, libintl-perl, rsync, libjson-perl, liblockfile-simple-perl, vncterm, qemu-server (>= 1.1-1), libwww-perl (>= 6.04-1), libnet-http-perl (>= 6.06-1), libhttp-daemon-perl, wget, libnet-dns-perl, vlan, ifenslave-2.6 (>= 1.1.0-10), liblinux-inotify2-perl, debconf (>= 0.5) | debconf-2.0, netcat-traditional, pve-cluster (>= 1.0-29), libpve-common-perl, libpve-storage-perl, libterm-readline-gnu-perl, libpve-access-control (>= 3.0-2), libio-socket-ssl-perl, libfilesys-df-perl, libfile-readbackwards-perl, libfile-sync-perl, redhat-cluster-pve, resource-agents-pve, fence-agents-pve, cstream, postfix | mail-transport-agent, libxml-parser-perl, lzop, dtach, libanyevent-perl, liburi-perl, logrotate, libanyevent-http-perl, apt-transport-https, libapt-pkg-perl, libcrypt-ssleay-perl, liblwp-protocol-https-perl
Depends: perl (>= 5.10.0-19), libtimedate-perl, libauthen-pam-perl, libintl-perl, rsync, libjson-perl, liblockfile-simple-perl, vncterm, qemu-server (>= 1.1-1), libwww-perl (>= 6.04-1), libnet-http-perl (>= 6.06-1), libhttp-daemon-perl, wget, libnet-dns-perl, vlan, ifenslave-2.6 (>= 1.1.0-10), liblinux-inotify2-perl, debconf (>= 0.5) | debconf-2.0, netcat-traditional, pve-cluster (>= 1.0-29), libpve-common-perl, libpve-storage-perl, libterm-readline-gnu-perl, libpve-access-control (>= 3.0-2), libio-socket-ssl-perl, libfilesys-df-perl, libfile-readbackwards-perl, libfile-sync-perl, redhat-cluster-pve, resource-agents-pve, fence-agents-pve, cstream, postfix | mail-transport-agent, libxml-parser-perl, lzop, dtach, libanyevent-perl, liburi-perl, logrotate, libanyevent-http-perl, apt-transport-https, libapt-pkg-perl, libcrypt-ssleay-perl, liblwp-protocol-https-perl, spiceterm
Conflicts: netcat-openbsd, vzdump
Replaces: vzdump
Provides: vzdump
......
......@@ -250,6 +250,18 @@ Ext.define('PVE.Utils', { statics: {
return data;
},
render_console_viewer: function(value) {
if (!value) {
return PVE.Utils.defaultText + ' (Java VNC Applet)';
} else if (value === 'applet') {
return 'Java VNC Applet';
} else if (value === 'vv') {
return 'SPICE (remote-viewer)';
} else {
return value;
}
},
language_map: {
zh_CN: 'Chinese',
ca: 'Catalan',
......@@ -507,6 +519,7 @@ Ext.define('PVE.Utils', { statics: {
vncproxy: [ 'VM/CT', gettext('Console') ],
spiceproxy: [ 'VM/CT', gettext('Console') + ' (Spice)' ],
vncshell: [ '', gettext('Shell') ],
spiceshell: [ '', gettext('Shell') + ' (Spice)' ],
qmsnapshot: [ 'VM', gettext('Snapshot') ],
qmrollback: [ 'VM', gettext('Rollback') ],
qmdelsnapshot: [ 'VM', gettext('Delete Snapshot') ],
......@@ -911,6 +924,31 @@ Ext.define('PVE.Utils', { statics: {
nw.focus();
},
defaultViewer: function(){
return PVE.VersionInfo.console || 'applet';
},
openSpiceViewer: function(url, params){
PVE.Utils.API2Request({
url: url,
params: params,
method: 'POST',
failure: function(response, opts){
Ext.Msg.alert('Error', response.htmlStatus);
},
success: function(response, opts){
var raw = "[virt-viewer]\n";
Ext.Object.each(response.result.data, function(k, v) {
raw += k + "=" + v + "\n";
});
var url = 'data:application/x-virt-viewer;charset=UTF-8,' +
encodeURIComponent(raw);
window.open(url, "_top");
}
});
},
// comp.setLoading() is buggy in ExtJS 4.0.7, so we
// use el.mask() instead
setErrorMask: function(comp, msg) {
......
......@@ -45,6 +45,35 @@ Ext.define('PVE.dc.KeyboardEdit', {
}
});
Ext.define('PVE.dc.ConsoleViewerEdit', {
extend: 'PVE.window.Edit',
initComponent : function() {
var me = this;
var data = [];
Ext.Array.each(['', 'applet', 'vv'], function(value) {
data.push([value, PVE.Utils.render_console_viewer(value)]);
});
Ext.applyIf(me, {
subject: gettext('Console Viewer'),
items: {
xtype: 'pveKVComboBox',
name: 'console',
data: data,
value: '',
fieldLabel: gettext('Console Viewer')
}
});
me.callParent();
me.load();
}
});
Ext.define('PVE.dc.OptionView', {
extend: 'PVE.grid.ObjectGrid',
alias: ['widget.pveDcOptionView'],
......@@ -75,6 +104,12 @@ Ext.define('PVE.dc.OptionView', {
}
return value;
}
},
console: {
header: gettext('Console Viewer'),
editor: 'PVE.dc.ConsoleViewerEdit',
required: true,
renderer: PVE.Utils.render_console_viewer
}
};
......
......@@ -51,13 +51,12 @@ Ext.define('PVE.node.Config', {
text: gettext('Shell'),
disabled: !caps.nodes['Sys.Console'],
handler: function() {
var url = Ext.urlEncode({
console: 'shell',
node: nodename
});
var nw = window.open("?" + url, '_blank',
"innerWidth=745,innerheight=427");
nw.focus();
if (PVE.Utils.defaultViewer() === 'vv') {
var params = { proxy: window.location.hostname };
PVE.Utils.openSpiceViewer('/nodes/' + nodename + '/spiceshell', params);
} else {
PVE.Utils.openConoleWindow('shell', undefined, nodename);
}
}
});
......
......@@ -145,10 +145,10 @@ Ext.define('PVE.qemu.Config', {
text: gettext('Console'),
disabled: !caps.vms['VM.Console'],
handler: function() {
if (spice) {
openSpiceConsole(vmid, nodename, vmname);
} else {
if (PVE.VersionInfo.console === 'applet' || !spice) {
PVE.Utils.openConoleWindow('kvm', vmid, nodename, vmname);
} else {
openSpiceConsole(vmid, nodename, vmname);
}
},
menu: new Ext.menu.Menu({
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment