mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-21 14:50:08 +03:00
Feature #1076: Add VNC support in SelfService.
When enabled in the occi server configuration file, UI users will be able to click the VNC icon that appears in the VM information. Then the websockets proxy will be set up, provided that the machine has been configured with the appropiate GRAPHICS section etc. This must be done in the OCCI templates, and cannot be done by the UI user. Wss sessions can be configured in the occi server configuration file. Unlike Sunstone, here they are transparent to the user and whenever they are enabled VNC sessions will be launched using wss:// automaticly. As such, it is not up to the user to choose the type of connection, and it fully depends on the server configuration. Additionally the install_novnc.sh script has been updated and improved. The install.sh has been updated too.
This commit is contained in:
parent
6bb9cb74a2
commit
4ccaf9704a
@ -1012,7 +1012,8 @@ OCCI_LIB_FILES="src/cloud/occi/lib/OCCIServer.rb \
|
||||
src/cloud/occi/lib/UserOCCI.rb \
|
||||
src/cloud/occi/lib/UserPoolOCCI.rb \
|
||||
src/cloud/occi/lib/ImageOCCI.rb \
|
||||
src/cloud/occi/lib/ImagePoolOCCI.rb"
|
||||
src/cloud/occi/lib/ImagePoolOCCI.rb \
|
||||
src/sunstone/OpenNebulaVNC.rb"
|
||||
|
||||
OCCI_LIB_CLIENT_FILES="src/cloud/occi/lib/OCCIClient.rb"
|
||||
|
||||
|
@ -7,35 +7,50 @@ if [ -z "$ONE_LOCATION" ]; then
|
||||
ONE_SHARE=/usr/share/one
|
||||
ONE_PUBLIC_SUNSTONE=/usr/lib/one/sunstone/public
|
||||
SUNSTONE_CONF=/etc/one/sunstone-server.conf
|
||||
ONE_PUBLIC_SELFSERVICE=/usr/lib/one/ruby/cloud/occi/ui/public
|
||||
SELFSERVICE_CONF=/etc/one/occi-server.conf
|
||||
else
|
||||
ONE_SHARE=$ONE_LOCATION/share
|
||||
ONE_PUBLIC_SUNSTONE=$ONE_LOCATION/lib/sunstone/public
|
||||
SUNSTONE_CONF=$ONE_LOCATION/etc/sunstone-server.conf
|
||||
ONE_PUBLIC_SELFSERVICE=$ONE_LOCATION/lib/ruby/cloud/occi/ui/public
|
||||
SELFSERVICE_CONF=$ONE_LOCATION/etc/occi-server.conf
|
||||
fi
|
||||
|
||||
echo "Downloading noVNC latest version..."
|
||||
mkdir -p $NOVNC_TMP
|
||||
wget -P $NOVNC_TMP --no-check-certificate http://github.com/kanaka/noVNC/tarball/master
|
||||
|
||||
cd $NOVNC_TMP
|
||||
curl -O -# -L http://github.com/kanaka/noVNC/tarball/master
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error downloading noVNC"
|
||||
echo "\nError downloading noVNC"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Extracting files to temporary folder..."
|
||||
tar=`ls -rt $NOVNC_TMP|tail -n1`
|
||||
tar -C $ONE_SHARE -mxvzf $NOVNC_TMP/$tar
|
||||
tar -C $ONE_SHARE -mxzf $NOVNC_TMP/$tar
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error untaring noVNC"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Moving files to OpenNebula $ONE_SHARE folder..."
|
||||
rm -rf $ONE_SHARE/noVNC
|
||||
dir=`ls -rt $ONE_SHARE|tail -n1`
|
||||
mv $ONE_SHARE/$dir $ONE_SHARE/noVNC
|
||||
|
||||
echo "Installing Sunstone client libraries in $ONE_PUBLIC_SUNSTONE..."
|
||||
mkdir -p $ONE_PUBLIC_SUNSTONE/vendor/noVNC
|
||||
mv $ONE_SHARE/noVNC/include/ $ONE_PUBLIC_SUNSTONE/vendor/noVNC/
|
||||
cp -r $ONE_SHARE/noVNC/include/ $ONE_PUBLIC_SUNSTONE/vendor/noVNC/
|
||||
|
||||
sed -i.bck "s%^\(:vnc_proxy_path: \).*$%\1$ONE_SHARE/$PROXY_PATH%" $SUNSTONE_CONF
|
||||
echo "Installing SelfService client libraries in $ONE_PUBLIC_SELFSERVICE..."
|
||||
mkdir -p $ONE_PUBLIC_SELFSERVICE/vendor/noVNC
|
||||
cp -r $ONE_SHARE/noVNC/include/ $ONE_PUBLIC_SELFSERVICE/vendor/noVNC/
|
||||
|
||||
#Update file permissions
|
||||
chmod +x $ONE_SHARE/noVNC/utils/launch.sh
|
||||
echo "Backing up and updating $SUNSTONE_CONF with new VNC proxy path..."
|
||||
sed -i.bck "s%^\(:vnc_proxy_path:\).*$%\1 $ONE_SHARE/$PROXY_PATH%" $SUNSTONE_CONF
|
||||
echo "Backing up and updating $SELFSERVICE_CONF with new VNC proxy path..."
|
||||
sed -i.bck "s%^\(:vnc_proxy_path:\).*$%\1 $ONE_SHARE/$PROXY_PATH%" $SELFSERVICE_CONF
|
||||
|
||||
echo "Installation successful"
|
@ -52,5 +52,26 @@
|
||||
:cpu: 8
|
||||
:memory: 8192
|
||||
|
||||
# Default language setting for Self-Service UI
|
||||
|
||||
#############################################################
|
||||
### SelfService UI Settings
|
||||
#############################################################
|
||||
|
||||
# Default language setting
|
||||
:lang: en_US
|
||||
|
||||
# VNC Configuration
|
||||
# vnc_enable: yes | no. Allow users to launch vnc sessions.
|
||||
# base_port: base_port + vnc_port of the VM is the port where the
|
||||
# proxy will listen for VNC session connections to that VM.
|
||||
# vnc_proxy_path: path to the websockets proxy (set by install_novnc.sh)
|
||||
# support_wss: no | yes | only. If yes or only provide path to cert and key.
|
||||
# "yes" means the proxy will accept both ws and wss connections.
|
||||
# vnc_proxy_cert: Certificate to encrypt wss connections.
|
||||
# vnc_proxy_key: Key for wss connections. Only necessary if not included in cert.
|
||||
:vnc_enable: no
|
||||
:vnc_proxy_base_port: 33876
|
||||
:vnc_proxy_path:
|
||||
:vnc_proxy_support_wss: no
|
||||
:vnc_proxy_cert:
|
||||
:vnc_proxy_key:
|
||||
|
@ -30,6 +30,8 @@ require 'ImagePoolOCCI'
|
||||
require 'UserOCCI'
|
||||
require 'UserPoolOCCI'
|
||||
|
||||
require 'OpenNebulaVNC'
|
||||
|
||||
require 'pp'
|
||||
|
||||
|
||||
@ -236,7 +238,6 @@ class OCCIServer < CloudServer
|
||||
return to_occi_xml(vm, 200)
|
||||
end
|
||||
|
||||
|
||||
# Deletes a COMPUTE resource
|
||||
# request:: _Hash_ hash containing the data of the request
|
||||
# [return] _String_,_Integer_ Delete confirmation msg or error,
|
||||
@ -505,4 +506,33 @@ class OCCIServer < CloudServer
|
||||
|
||||
return to_occi_xml(user, 200)
|
||||
end
|
||||
|
||||
############################################################################
|
||||
# VNC Methods
|
||||
############################################################################
|
||||
|
||||
def startvnc(id,config)
|
||||
vm = VirtualMachineOCCI.new(
|
||||
VirtualMachine.build_xml(id),
|
||||
@client)
|
||||
|
||||
rc = vm.info
|
||||
if OpenNebula.is_error?(rc)
|
||||
error = "Error starting VNC session, "
|
||||
error += "could not retrieve Virtual Machine"
|
||||
return [404,error]
|
||||
end
|
||||
|
||||
vnc_proxy = OpenNebulaVNC.new(config,{:json_errors => false})
|
||||
return vnc_proxy.start(vm)
|
||||
end
|
||||
|
||||
def stopvnc(pipe)
|
||||
begin
|
||||
OpenNebulaVNC.stop(pipe)
|
||||
rescue Exception => e
|
||||
return [500, e.message]
|
||||
end
|
||||
return [200,nil]
|
||||
end
|
||||
end
|
||||
|
@ -309,7 +309,19 @@ end
|
||||
## UI
|
||||
##############################################
|
||||
|
||||
post '/config' do
|
||||
get '/ui/config/:opt' do
|
||||
case params[:opt]
|
||||
when "lang" then session[:lang]
|
||||
when "wss"
|
||||
wss = settings.config[:vnc_proxy_support_wss]
|
||||
wss = (wss == true || wss == "yes" || wss == "only" ? "yes" : "no")
|
||||
return wss
|
||||
when "vnc" then settings.config[:vnc_enable] ? "yes" : "no"
|
||||
else [404, "Unknown configuration option"]
|
||||
end
|
||||
end
|
||||
|
||||
post '/ui/config' do
|
||||
begin
|
||||
body = JSON.parse(request.body.read)
|
||||
rescue
|
||||
@ -321,6 +333,7 @@ post '/config' do
|
||||
when "lang" then session[:lang]=value
|
||||
end
|
||||
end
|
||||
return 200
|
||||
end
|
||||
|
||||
get '/ui/login' do
|
||||
@ -355,3 +368,57 @@ post '/ui/upload' do
|
||||
result,rc = @occi_server.post_storage(request)
|
||||
treat_response(result,rc)
|
||||
end
|
||||
|
||||
post '/ui/startvnc/:id' do
|
||||
if !settings.config[:vnc_enable]
|
||||
return [403, "VNC sessions are disabled"]
|
||||
end
|
||||
|
||||
vm_id = params[:id]
|
||||
|
||||
vnc_hash = session['vnc']
|
||||
|
||||
if !vnc_hash
|
||||
session['vnc']= {}
|
||||
elsif vnc_hash[vm_id]
|
||||
#return existing information
|
||||
info = vnc_hash[vm_id].clone
|
||||
info.delete(:pipe)
|
||||
|
||||
return [200, info.to_json]
|
||||
end
|
||||
|
||||
rc = @occi_server.startvnc(vm_id, settings.config)
|
||||
|
||||
if rc[0] == 200
|
||||
info = rc[1]
|
||||
session['vnc'][vm_id] = info.clone
|
||||
info.delete(:pipe)
|
||||
|
||||
[200, info.to_json]
|
||||
else
|
||||
rc
|
||||
end
|
||||
end
|
||||
|
||||
post '/ui/stopvnc/:id' do
|
||||
if !settings.config[:vnc_enable]
|
||||
return [403, "VNC sessions are disabled"]
|
||||
end
|
||||
|
||||
vm_id = params[:id]
|
||||
vnc_hash = session['vnc']
|
||||
|
||||
if !vnc_hash || !vnc_hash[vm_id]
|
||||
msg = "It seems there is no VNC proxy running for this machine"
|
||||
return [403, msg]
|
||||
end
|
||||
|
||||
rc = @occi_server.stopvnc(vnc_hash[vm_id][:pipe])
|
||||
|
||||
if rc[0] == 200
|
||||
session['vnc'].delete(vm_id)
|
||||
end
|
||||
|
||||
rc
|
||||
end
|
||||
|
@ -45,7 +45,7 @@ function setLang(lang_str){
|
||||
if (('localStorage' in window) && (window['localStorage'] !== null)){
|
||||
localStorage['lang']=lang_str;
|
||||
};
|
||||
$.post('config',JSON.stringify({lang:lang_str}),function(){window.location.href = "./ui"});
|
||||
$.post('ui/config',JSON.stringify({lang:lang_str}),function(){window.location.href = "./ui"});
|
||||
};
|
||||
|
||||
$(document).ready(function(){
|
||||
|
@ -413,7 +413,7 @@ var OCCI = {
|
||||
params.data.body = '<DISK id="'+disk_id+'"><SAVE_AS name="'+im_name+'" /></DISK>';
|
||||
OCCI.Action.update(params,OCCI.VM.resource,"saveas");
|
||||
},
|
||||
/* "vnc" : function(params,startstop){
|
||||
"vnc" : function(params,startstop){
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
@ -423,7 +423,7 @@ var OCCI = {
|
||||
var action = OCCI.Helper.action(method);
|
||||
var request = OCCI.Helper.request(resource,method, id);
|
||||
$.ajax({
|
||||
url: "vm/" + id + "/" + method,
|
||||
url: "ui/" + method + "/" + id,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
success: function(response){
|
||||
@ -440,13 +440,16 @@ var OCCI = {
|
||||
},
|
||||
"stopvnc" : function(params){
|
||||
OCCI.VM.vnc(params,"stopvnc");
|
||||
|
||||
},
|
||||
/*
|
||||
"monitor" : function(params){
|
||||
OCCI.Action.monitor(params,OCCI.VM.resource,false);
|
||||
},
|
||||
"monitor_all" : function(params){
|
||||
OCCI.Action.monitor(params,OCCI.VM.resource,true);
|
||||
}*/
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
"Image": {
|
||||
|
@ -15,16 +15,19 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/*Virtual Machines tab plugin*/
|
||||
//var INCLUDE_URI = "vendor/noVNC/include/";
|
||||
var INCLUDE_URI = "vendor/noVNC/include/";
|
||||
//var VM_HISTORY_LENGTH = 40;
|
||||
|
||||
/*
|
||||
|
||||
function loadVNC(){
|
||||
var script = '<script src="vendor/noVNC/include/vnc.js"></script>';
|
||||
document.write(script);
|
||||
}
|
||||
loadVNC();
|
||||
var vnc_enable=false;
|
||||
var use_wss=false;
|
||||
|
||||
/*
|
||||
var vm_graphs = [
|
||||
{ title : tr("CPU"),
|
||||
monitor_resources : "cpu_usage",
|
||||
@ -264,7 +267,6 @@ var vm_actions = {
|
||||
error: onError
|
||||
},
|
||||
|
||||
/*
|
||||
"VM.startvnc" : {
|
||||
type: "single",
|
||||
call: OCCI.VM.startvnc,
|
||||
@ -280,6 +282,7 @@ var vm_actions = {
|
||||
notify: true
|
||||
},
|
||||
|
||||
/*
|
||||
"VM.monitor" : {
|
||||
type: "monitor",
|
||||
call : OCCI.VM.monitor,
|
||||
@ -540,6 +543,10 @@ function updateVMInfo(request,vm){
|
||||
<td class="key_td">'+tr("Memory")+'</td>\
|
||||
<td class="value_td">'+vm_info.MEMORY+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Launch VNC session")+'</td>\
|
||||
<td class="value_td">'+vncIcon(vm_info)+'</td>\
|
||||
</tr>\
|
||||
</tbody>\
|
||||
</table>\
|
||||
<div class="form_buttons">\
|
||||
@ -940,7 +947,7 @@ function setVMAutorefresh(){
|
||||
},INTERVAL+someTime());
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
function updateVNCState(rfb, state, oldstate, msg) {
|
||||
var s, sb, cad, klass;
|
||||
s = $D('VNC_status');
|
||||
@ -1016,7 +1023,7 @@ function setupVNC(){
|
||||
Sunstone.runAction("VM.stopvnc",id);
|
||||
});
|
||||
|
||||
$('.vnc',main_tabs_context).live("click",function(){
|
||||
$('.vnc').live("click",function(){
|
||||
//Which VM is it?
|
||||
var id = $(this).attr('vm_id');
|
||||
//Set attribute to dialog
|
||||
@ -1029,7 +1036,7 @@ function setupVNC(){
|
||||
|
||||
function vncCallback(request,response){
|
||||
rfb = new RFB({'target': $D('VNC_canvas'),
|
||||
'encrypt': false,
|
||||
'encrypt': use_wss,
|
||||
'true_color': true,
|
||||
'local_cursor': true,
|
||||
'shared': true,
|
||||
@ -1049,6 +1056,20 @@ function vncCallback(request,response){
|
||||
|
||||
}
|
||||
|
||||
function vncIcon(vm){
|
||||
var gr_icon;
|
||||
if (vnc_enable){
|
||||
gr_icon = '<a class="vnc" href="#" vm_id="'+vm.ID+'">';
|
||||
gr_icon += '<img src="images/vnc_on.png" alt=\"'+tr("Open VNC Session")+'\" /></a>';
|
||||
}
|
||||
else {
|
||||
gr_icon = '<img src="images/vnc_off.png" alt=\"'+tr("VNC Disabled")+'\" />';
|
||||
}
|
||||
return gr_icon;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
function vncIcon(vm){
|
||||
var graphics = vm.TEMPLATE.GRAPHICS;
|
||||
var state = vm.STATE;
|
||||
@ -1063,6 +1084,9 @@ function vncIcon(vm){
|
||||
return gr_icon;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
function vmMonitorError(req,error_json){
|
||||
var message = error_json.error.message;
|
||||
var info = req.request.data[0].monitor;
|
||||
@ -1070,9 +1094,9 @@ function vmMonitorError(req,error_json){
|
||||
var id_suffix = labels.replace(/,/g,'_');
|
||||
var id = '#vm_monitor_'+id_suffix;
|
||||
$('#vm_monitoring_tab '+id).html('<div style="padding-left:20px;">'+message+'</div>');
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// At this point the DOM is ready and the sunstone.js ready() has been run.
|
||||
$(document).ready(function(){
|
||||
@ -1102,7 +1126,7 @@ $(document).ready(function(){
|
||||
//setupCreateVMDialog();
|
||||
setupSaveasDialog();
|
||||
setVMAutorefresh();
|
||||
//setupVNC();
|
||||
setupVNC();
|
||||
|
||||
initCheckAllBoxes(dataTable_vMachines);
|
||||
tableCheckboxesListener(dataTable_vMachines);
|
||||
|
@ -49,16 +49,29 @@ var config_tab = {
|
||||
Sunstone.addMainTab('config_tab',config_tab);
|
||||
|
||||
$(document).ready(function(){
|
||||
if (lang)
|
||||
$('table#config_table #lang_sel option[value="'+lang+'"]').attr('selected','selected');
|
||||
$('table#config_table #lang_sel').change(function(){
|
||||
setLang($(this).val());
|
||||
});
|
||||
|
||||
$('#li_config_tab').click(function(){
|
||||
hideDialog();
|
||||
});
|
||||
|
||||
//Set lang to the right value
|
||||
if (lang)
|
||||
$('table#config_table #lang_sel option[value="'+lang+'"]').attr('selected','selected');
|
||||
|
||||
//Listen to changes in language
|
||||
$('table#config_table #lang_sel').change(function(){
|
||||
setLang($(this).val());
|
||||
});
|
||||
|
||||
//Vendor customization, change small logo
|
||||
$('div#logo img').attr('src',logo_small);
|
||||
|
||||
$.get('ui/config/vnc',function(response){
|
||||
if (response == "true" || response == "yes")
|
||||
vnc_enable=true; //defined in compute.js
|
||||
});
|
||||
|
||||
$.get('ui/config/wss', function(response){
|
||||
if (response == "true" || response == "yes")
|
||||
use_wss=true; //defined in compute.js
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user