mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-16 22:50:10 +03:00
parent
89379d9ffb
commit
0b5453a234
19
install.sh
19
install.sh
@ -951,9 +951,6 @@ RUBY_LIB_FILES="src/mad/ruby/ActionManager.rb \
|
||||
src/mad/ruby/ssh_stream.rb \
|
||||
src/vnm_mad/one_vnm.rb \
|
||||
src/oca/ruby/opennebula.rb \
|
||||
src/sunstone/OpenNebulaVNC.rb \
|
||||
src/sunstone/opennebula_guac.rb \
|
||||
src/sunstone/opennebula_vmrc.rb \
|
||||
src/sunstone/OpenNebulaAddons.rb \
|
||||
src/vmm_mad/remotes/vcenter/vcenter_driver.rb \
|
||||
src/vmm_mad/remotes/nsx/nsx_driver.rb \
|
||||
@ -2477,12 +2474,16 @@ SUNSTONE_ETC_VIEW_MIXED="src/sunstone/etc/sunstone-views/mixed/admin.yaml \
|
||||
src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml"
|
||||
|
||||
SUNSTONE_MODELS_FILES="src/sunstone/models/OpenNebulaJSON.rb \
|
||||
src/sunstone/models/SunstoneServer.rb \
|
||||
src/sunstone/models/SunstoneViews.rb \
|
||||
src/sunstone/models/OpenNebula2FA/SunstoneWebAuthn.rb \
|
||||
src/sunstone/models/OpenNebula2FA/sunstone_qr_code.rb \
|
||||
src/sunstone/models/OpenNebula2FA/sunstone_optp.rb \
|
||||
src/sunstone/models/OpenNebula2FA/sunstone_2f_auth.rb"
|
||||
src/sunstone/models/SunstoneServer.rb \
|
||||
src/sunstone/models/SunstoneViews.rb \
|
||||
src/sunstone/models/sunstone_vm_helper.rb \
|
||||
src/sunstone/models/sunstone_vnc.rb \
|
||||
src/sunstone/models/sunstone_guac.rb \
|
||||
src/sunstone/models/sunstone_vmrc.rb \
|
||||
src/sunstone/models/OpenNebula2FA/SunstoneWebAuthn.rb \
|
||||
src/sunstone/models/OpenNebula2FA/sunstone_qr_code.rb \
|
||||
src/sunstone/models/OpenNebula2FA/sunstone_optp.rb \
|
||||
src/sunstone/models/OpenNebula2FA/sunstone_2f_auth.rb"
|
||||
|
||||
SUNSTONE_MODELS_JSON_FILES="src/sunstone/models/OpenNebulaJSON/HostJSON.rb \
|
||||
src/sunstone/models/OpenNebulaJSON/ImageJSON.rb \
|
||||
|
@ -240,7 +240,10 @@ AllCops:
|
||||
- src/sunstone/test/spec/host_spec.rb
|
||||
- src/sunstone/test/spec/user_spec.rb
|
||||
- src/sunstone/OpenNebulaAddons.rb
|
||||
- src/sunstone/OpenNebulaVNC.rb
|
||||
- src/sunstone/models/sunstone_vnc.rb
|
||||
- src/sunstone/models/sunstone_guac.rb
|
||||
- src/sunstone/models/sunstone_vmrc.rb
|
||||
- src/sunstone/models/sunstone_vm_helper.rb
|
||||
- src/sunstone/models/OpenNebulaJSON.rb
|
||||
- src/sunstone/models/SunstoneViews.rb
|
||||
- src/sunstone/models/SunstoneServer.rb
|
||||
|
@ -25,6 +25,7 @@ if !ONE_LOCATION
|
||||
SHARE_LOCATION = '/usr/share/one'
|
||||
ETC_LOCATION = '/etc/one'
|
||||
RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
|
||||
SUNSTONE_ROOT_DIR = '/usr/lib/one/sunstone'
|
||||
GEMS_LOCATION = '/usr/share/one/gems'
|
||||
else
|
||||
VAR_LOCATION = ONE_LOCATION + '/var'
|
||||
@ -32,13 +33,13 @@ else
|
||||
SHARE_LOCATION = ONE_LOCATION + '/share'
|
||||
ETC_LOCATION = ONE_LOCATION + '/etc'
|
||||
RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
|
||||
SUNSTONE_ROOT_DIR = ONE_LOCATION + '/lib/sunstone'
|
||||
GEMS_LOCATION = ONE_LOCATION + '/share/gems'
|
||||
end
|
||||
|
||||
VNC_LOG = LOG_LOCATION + "/novnc.log"
|
||||
CONFIGURATION_FILE = ETC_LOCATION + "/sunstone-server.conf"
|
||||
PLUGIN_CONFIGURATION_FILE = ETC_LOCATION + "/sunstone-plugins.yaml"
|
||||
SUNSTONE_ROOT_DIR = File.dirname(__FILE__)
|
||||
|
||||
if File.directory?(GEMS_LOCATION)
|
||||
$LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
|
||||
@ -53,7 +54,7 @@ $LOAD_PATH << SUNSTONE_ROOT_DIR + '/models'
|
||||
|
||||
require 'logger'
|
||||
require 'yaml'
|
||||
require 'OpenNebulaVNC'
|
||||
require 'sunstone_vnc'
|
||||
|
||||
$log=Logger.new(VNC_LOG)
|
||||
|
||||
@ -65,7 +66,7 @@ rescue Exception => e
|
||||
exit 1
|
||||
end
|
||||
|
||||
vnc=OpenNebulaVNC.new(conf, $log)
|
||||
vnc=SunstoneVNC.new(conf, $log)
|
||||
|
||||
if ARGV[0]
|
||||
res=case ARGV[0].downcase.to_sym
|
||||
|
@ -19,9 +19,10 @@ require 'CloudServer'
|
||||
require 'OpenNebulaJSON'
|
||||
include OpenNebulaJSON
|
||||
|
||||
require 'OpenNebulaVNC'
|
||||
require 'opennebula_guac'
|
||||
require 'opennebula_vmrc'
|
||||
require 'sunstone_vnc'
|
||||
require 'sunstone_guac'
|
||||
require 'sunstone_vmrc'
|
||||
require 'sunstone_vm_helper'
|
||||
require 'OpenNebulaAddons'
|
||||
require 'OpenNebulaJSON/JSONUtils'
|
||||
#include JSONUtils
|
||||
|
@ -109,7 +109,7 @@ GUAC_STATES = [
|
||||
]
|
||||
|
||||
# Class for Guacamole connection configuration
|
||||
class OpenNebulaGuac
|
||||
class SunstoneGuac
|
||||
|
||||
attr_reader :proxy_port
|
||||
|
||||
@ -159,6 +159,9 @@ class OpenNebulaGuac
|
||||
return error(400, 'Fireedge_key is not available')
|
||||
end
|
||||
|
||||
info = SunstoneVMHelper.get_remote_info(vm_resource)
|
||||
encode_info = Base64.encode64(info.to_json)
|
||||
|
||||
data = encrypt_data(
|
||||
{
|
||||
'connection' => {
|
||||
@ -174,7 +177,7 @@ class OpenNebulaGuac
|
||||
}
|
||||
)
|
||||
|
||||
[200, { :token => data }.to_json]
|
||||
[200, { :token => data, :info => encode_info }.to_json]
|
||||
end
|
||||
|
||||
private
|
88
src/sunstone/models/sunstone_vm_helper.rb
Normal file
88
src/sunstone/models/sunstone_vm_helper.rb
Normal file
@ -0,0 +1,88 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2020, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||
# not use this file except in compliance with the License. You may obtain #
|
||||
# a copy of the License at #
|
||||
# #
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||
# #
|
||||
# Unless required by applicable law or agreed to in writing, software #
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||
# See the License for the specific language governing permissions and #
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
module SunstoneVMHelper
|
||||
|
||||
class << self
|
||||
|
||||
def state_to_str(id, lcm_id)
|
||||
id = id.to_i
|
||||
state_str = VirtualMachine::VM_STATE[id]
|
||||
|
||||
if state_str == 'ACTIVE'
|
||||
lcm_id = lcm_id.to_i
|
||||
return VirtualMachine::LCM_STATE[lcm_id]
|
||||
end
|
||||
|
||||
return state_str
|
||||
end
|
||||
|
||||
def get_ips(vm)
|
||||
ips = []
|
||||
|
||||
vm_nics = []
|
||||
|
||||
if !vm['TEMPLATE']['NIC'].nil?
|
||||
vm_nics = [vm['TEMPLATE']['NIC']].flatten
|
||||
end
|
||||
|
||||
if !vm['TEMPLATE']['PCI'].nil?
|
||||
vm_nics = [vm_nics, vm['TEMPLATE']['PCI']].flatten
|
||||
end
|
||||
|
||||
vm_nics.each do |nic|
|
||||
%w[IP EXTERNAL_IP IP6_GLOBAL IP6_ULA IP6
|
||||
VROUTER_IP VROUTER_IP6_GLOBAL VROUTER_IP6_ULA].each do |attr|
|
||||
if nic.key?(attr)
|
||||
ips.push(nic[attr])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
VirtualMachine::EXTERNAL_IP_ATTRS.each do |attr|
|
||||
external_ip = vm['MONITORING'][attr]
|
||||
|
||||
if !external_ip.nil? && !ips.include?(external_ip)
|
||||
ips.push(external_ip)
|
||||
end
|
||||
end
|
||||
|
||||
return ips
|
||||
end
|
||||
|
||||
|
||||
def get_remote_info(vm_resource)
|
||||
vm = vm_resource.to_hash['VM']
|
||||
|
||||
service_id = vm['USER_TEMPLATE']['SERVICE_ID']
|
||||
|
||||
info = {
|
||||
:id => vm['ID'],
|
||||
:name => vm['NAME'],
|
||||
:state => state_to_str(vm['STATE'], vm['LCM_STATE']),
|
||||
:start_time => vm['STIME'],
|
||||
:networks => get_ips(vm)
|
||||
}
|
||||
|
||||
info[:service_id] = service_id if service_id
|
||||
|
||||
return info
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -107,7 +107,7 @@ VMRC_STATES = [
|
||||
]
|
||||
|
||||
# Class for necessary VMRC ticket creation
|
||||
class OpenNebulaVMRC
|
||||
class SunstoneVMRC
|
||||
|
||||
attr_reader :proxy_port
|
||||
|
@ -103,7 +103,7 @@ VNC_STATES = [
|
||||
#68, #HOTPLUG_SAVEAS_STOPPED
|
||||
]
|
||||
|
||||
class OpenNebulaVNC
|
||||
class SunstoneVNC
|
||||
|
||||
attr_reader :proxy_port
|
||||
|
||||
@ -243,10 +243,13 @@ class OpenNebulaVNC
|
||||
return error(500, "Cannot create VNC proxy token")
|
||||
end
|
||||
|
||||
info = SunstoneVMHelper.get_remote_info(vm_resource)
|
||||
encode_info = Base64.encode64(info.to_json)
|
||||
|
||||
info = {
|
||||
:password => vnc_pw,
|
||||
:token => random_str,
|
||||
:vm_name => vm_resource['NAME']
|
||||
:info => encode_info
|
||||
}
|
||||
|
||||
return [200, info.to_json]
|
@ -17,7 +17,8 @@
|
||||
define(function(require) {
|
||||
require('spice-main');
|
||||
|
||||
var host = null, port = null;
|
||||
var UtilsConnection = require("utils/info-connection/utils");
|
||||
|
||||
var sc;
|
||||
|
||||
function spice_set_cookie(name, value, days) {
|
||||
@ -41,10 +42,16 @@ define(function(require) {
|
||||
}
|
||||
|
||||
function connect() {
|
||||
var host, port, password, scheme = "ws://", uri;
|
||||
var info = spice_query_var('info', undefined);
|
||||
var info_decode = UtilsConnection.decodeInfoConnection(info);
|
||||
UtilsConnection.printInfoConnection($('.SPICE_info'), info_decode)
|
||||
|
||||
if (info_decode && info_decode.name) {
|
||||
document.title = info_decode.name
|
||||
}
|
||||
|
||||
// By default, use the host and port of server that served this file
|
||||
host = spice_query_var('host', window.location.hostname);
|
||||
var host = spice_query_var('host', window.location.hostname);
|
||||
|
||||
// Note that using the web server port only makes sense
|
||||
// if your web server has a reverse proxy to relay the WebSocket
|
||||
@ -57,20 +64,21 @@ define(function(require) {
|
||||
default_port = 443;
|
||||
}
|
||||
}
|
||||
port = spice_query_var('port', default_port);
|
||||
|
||||
var scheme = "ws://"
|
||||
if (window.location.protocol == 'https:') {
|
||||
scheme = "wss://";
|
||||
}
|
||||
|
||||
// If a token variable is passed in, set the parameter in a cookie.
|
||||
// This is used by nova-spiceproxy.
|
||||
token = spice_query_var('token', null);
|
||||
var token = spice_query_var('token', null);
|
||||
if (token) {
|
||||
spice_set_cookie('token', token, 1)
|
||||
}
|
||||
|
||||
password = spice_query_var('password', '');
|
||||
path = spice_query_var('path', 'websockify');
|
||||
var password = spice_query_var('password', '');
|
||||
var port = spice_query_var('port', default_port);
|
||||
|
||||
if ((!host) || (!port)) {
|
||||
console.log("must specify host and port in URL");
|
||||
@ -81,7 +89,7 @@ define(function(require) {
|
||||
sc.stop();
|
||||
}
|
||||
|
||||
uri = scheme + host + ":" + port + "?token=" + token;
|
||||
var uri = scheme + host + ":" + port + "?token=" + token;
|
||||
|
||||
try {
|
||||
sc = new SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
|
||||
@ -91,7 +99,6 @@ define(function(require) {
|
||||
alert(e.toString());
|
||||
disconnect();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function disconnect() {
|
||||
|
@ -17,8 +17,10 @@
|
||||
define(function(require) {
|
||||
require("jquery");
|
||||
require("jquery-ui");
|
||||
|
||||
var WMKS = require("wmks");
|
||||
var Config = require("sunstone-config");
|
||||
var UtilsConnection = require("utils/info-connection/utils");
|
||||
|
||||
var _wmks;
|
||||
var _is_encrypted = "";
|
||||
|
||||
@ -38,16 +40,6 @@ define(function(require) {
|
||||
setStatus("Something went wrong, connection is closed", "Failed");
|
||||
}
|
||||
}
|
||||
|
||||
function desktopNameChange(name) {
|
||||
if (e.detail.name) {
|
||||
setStatus(null, "VMRC " + _wmks.connectionState + " (" + _is_encrypted + ") to: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
function credentialsRequired(e) {
|
||||
setStatus("Something went wrong, more credentials must be given to continue", "Failed");
|
||||
}
|
||||
|
||||
function sendCtrlAltDel() {
|
||||
if (_wmks) { _wmks.sendCAD(); }
|
||||
@ -95,7 +87,14 @@ define(function(require) {
|
||||
var host = getQueryVariable("host");
|
||||
var port = getQueryVariable("port");
|
||||
var ticket = getQueryVariable("ticket");
|
||||
var vm_name = getQueryVariable("name");
|
||||
|
||||
var info = spice_query_var('info', undefined);
|
||||
var info_decode = UtilsConnection.decodeInfoConnection(info);
|
||||
UtilsConnection.printInfoConnection($('.VMRC_info'), info_decode)
|
||||
|
||||
if (info_decode && info_decode.name) {
|
||||
document.title = info_decode.name
|
||||
}
|
||||
|
||||
if (window.location.protocol === "https:") {
|
||||
URL = "wss";
|
||||
@ -120,7 +119,7 @@ define(function(require) {
|
||||
try{
|
||||
_wmks = WMKS.createWMKS("wmksContainer", {})
|
||||
.register(WMKS.CONST.Events.CONNECTION_STATE_CHANGE,
|
||||
function (event, data) {
|
||||
function (_, data) {
|
||||
if (typeof cons !== 'undefined' && data.state == cons.ConnectionState.CONNECTED) {
|
||||
console.log("connection state change : connected");
|
||||
}
|
||||
@ -129,9 +128,9 @@ define(function(require) {
|
||||
|
||||
_wmks.eventHandlers["connectionstatechange"].push(connected);
|
||||
_wmks.eventHandlers["disconnect"] = disconnectedFromServer;
|
||||
_wmks.vm_name = info_decode && info_decode.name;
|
||||
|
||||
_wmks.connect(URL);
|
||||
_wmks["vm_name"] = vm_name;
|
||||
}catch(err){
|
||||
setStatus("Something went wrong, connection is closed", "Failed");
|
||||
console.log("error start VMRC ", err);
|
||||
|
@ -15,11 +15,12 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
define(function(require) {
|
||||
var RFB = require("vnc-rfb").default;
|
||||
var Config = require("sunstone-config");
|
||||
var UtilsConnection = require("utils/info-connection/utils");
|
||||
|
||||
var RFB = require("vnc-rfb").default;
|
||||
var _rfb;
|
||||
var _is_encrypted = "";
|
||||
var _vm_name;
|
||||
|
||||
function setStatus(message="", status=""){
|
||||
$(".NOVNC_message").text(message);
|
||||
@ -27,12 +28,12 @@ define(function(require) {
|
||||
}
|
||||
|
||||
function connected(){
|
||||
setStatus(null, "VNC " + _rfb._rfb_connection_state + " (" + _is_encrypted + ") to: " + (_vm_name || _rfb._fb_name));
|
||||
setStatus(null, "VNC " + _rfb._rfb_connection_state + " (" + _is_encrypted + ") to: " + _rfb._fb_name);
|
||||
}
|
||||
|
||||
function disconnectedFromServer(e){
|
||||
if (e.detail.clean) {
|
||||
setStatus(null, "VNC " + _rfb._rfb_connection_state + " (" + _is_encrypted + ") to: " + (_vm_name || _rfb._fb_name));
|
||||
setStatus(null, "VNC " + _rfb._rfb_connection_state + " (" + _is_encrypted + ") to: " + _rfb._fb_name);
|
||||
} else {
|
||||
setStatus("Something went wrong, connection is closed", "Failed");
|
||||
}
|
||||
@ -40,7 +41,7 @@ define(function(require) {
|
||||
|
||||
function desktopNameChange(e) {
|
||||
if (e.detail.name) {
|
||||
setStatus(null, "VNC " + _rfb._rfb_connection_state + " (" + _is_encrypted + ") to: " + (_vm_name || e.detail.name));
|
||||
setStatus(null, "VNC " + _rfb._rfb_connection_state + " (" + _is_encrypted + ") to: " + e.detail.name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,13 +128,20 @@ define(function(require) {
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
token = window.token;
|
||||
|
||||
var URL = "";
|
||||
var proxy_host = window.location.hostname;
|
||||
var proxy_port = Config.vncProxyPort;
|
||||
var token = getQueryVariable("token");
|
||||
var password = getQueryVariable("password");
|
||||
_vm_name = getQueryVariable("title") || undefined;
|
||||
|
||||
var info = getQueryVariable('info') || undefined;
|
||||
var info_decode = UtilsConnection.decodeInfoConnection(info);
|
||||
UtilsConnection.printInfoConnection($('.NOVNC_info'), info_decode)
|
||||
|
||||
if (info_decode && info_decode.name) {
|
||||
document.title = info_decode.name
|
||||
}
|
||||
|
||||
var rfbConfig = password? { "credentials": { "password": password } } : {};
|
||||
|
||||
|
@ -147,11 +147,49 @@ define(function(require) {
|
||||
},
|
||||
"STATES": STATES,
|
||||
"filterDoneServices": _filterDoneServices,
|
||||
"getService": _getService,
|
||||
"getName": function(id){
|
||||
return OpenNebulaAction.getName(id, CACHE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
function _promiseGetService({ id, success, async = true } = {}) {
|
||||
return $.ajax({
|
||||
url: 'service/' + id,
|
||||
type: 'GET',
|
||||
success: success,
|
||||
async: async
|
||||
});
|
||||
}
|
||||
|
||||
function _getServiceById({ services, id } = {}) {
|
||||
return Array.isArray(services) &&
|
||||
services.find(function(service) {
|
||||
return service && service[RESOURCE] && service[RESOURCE].ID === id
|
||||
});
|
||||
}
|
||||
|
||||
function _getService(id) {
|
||||
if (!id) return undefined;
|
||||
|
||||
var service = undefined;
|
||||
var cache = OpenNebulaAction.cache(CACHE_NAME);
|
||||
|
||||
if (cache && cache.data) {
|
||||
service = _getServiceById({ services: cache.data, id: id })
|
||||
}
|
||||
|
||||
if (!service || service.length === 0) {
|
||||
_promiseGetService({
|
||||
id: id,
|
||||
async: false,
|
||||
success: function(res) { service = res }
|
||||
})
|
||||
}
|
||||
|
||||
return service ? service[RESOURCE] : undefined
|
||||
}
|
||||
|
||||
function _filterDoneServices(services) {
|
||||
return $.grep(services, function(service) {
|
||||
return service.DOCUMENT.TEMPLATE.BODY.state !== STATES.DONE;
|
||||
|
@ -29,6 +29,9 @@
|
||||
</span>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="large-12 columns">
|
||||
<div class="guac_info"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="guacamole-display" class="guacamole-display"></div>
|
||||
</div>
|
||||
|
@ -19,19 +19,24 @@
|
||||
<div class="large-12 columns">
|
||||
<h3 class="subheader" id="spice_dialog">
|
||||
{{tr "SPICE"}}
|
||||
<span id="vnc_buttons">
|
||||
<a id="open_in_a_new_window_spice" href="" target="_blank" title="{{tr "Open in a new window"}}"> <i class="fas fa-external-link-alt detach-spice-icon"/></a>
|
||||
<span id="vnc_buttons" class="right">
|
||||
<a class="button" id="open_in_a_new_window_spice" href="#" target="_blank" title="{{tr "Open in a new window"}}">
|
||||
<i class="fas fa-external-link-alt detach-spice-icon"/>
|
||||
</a>
|
||||
<button class="button secondary" data-close aria-label="{{tr "Close modal"}}" aria-label="{{tr "Close modal"}}">
|
||||
<i class="fas fa-times-circle"></i>
|
||||
</button>
|
||||
</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="large-12 columns">
|
||||
<div class="SPICE_info"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="reveal-body" style="width:100%; overflow-x:auto">
|
||||
<div id="spice-area">
|
||||
<div id="spice-area" style="text-align: center; background: rgb(40, 40, 40);">
|
||||
<div id="spice-screen" class="spice-screen"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="message-div" class="spice-message" hidden></div>
|
||||
<button class="close-button" data-close aria-label="{{tr "Close modal"}}" type="button">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -20,18 +20,21 @@
|
||||
<h5 class="subheader" id="vmrc_dialog">
|
||||
<span id="VMRC_status"></span>
|
||||
<span id="VMRC_buttons" class="right">
|
||||
<button class="button alert" value="Send CtrlAltDel"
|
||||
id="sendCtrlAltDelButton">{{tr "Send CtrlAltDel"}}</button>
|
||||
<a class="button" id="open_in_a_new_window" href="" target="_blank" title="{{tr "Open in a new window"}}">
|
||||
<button class="button alert" id="sendCtrlAltDelButton">
|
||||
{{tr "Send CtrlAltDel"}}
|
||||
</button>
|
||||
<a class="button" id="open_in_a_new_window" href="#" target="_blank" title="{{tr "Open in a new window"}}">
|
||||
<i class="fas fa-external-link-alt detach-vmrc-icon" />
|
||||
</a>
|
||||
<button class="button secondary" data-close aria-label="{{tr "Close modal"}}" type="button"
|
||||
title="Close VMRC">
|
||||
<button class="button secondary" data-close aria-label="{{tr "Close modal"}}" title="{{tr "Close VMRC"}}">
|
||||
<i class="fas fa-times-circle"></i>
|
||||
</button>
|
||||
</span>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="large-12 columns">
|
||||
<div class="VMRC_info"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="reveal-body text-center" style="width:100%; overflow-x:auto">
|
||||
<div id="wmksContainer" style="position:absolute;width:100%;height:100%; left:0em"></div>
|
||||
|
@ -15,21 +15,26 @@
|
||||
{{! -------------------------------------------------------------------------- }}
|
||||
|
||||
<div id="{{dialogId}}" class="reveal full" data-reveal>
|
||||
<div class="row text-center">
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<h5 class="subheader" id="vnc_dialog">
|
||||
<span id="VNC_status"></span>
|
||||
<span id="VNC_buttons" class="right">
|
||||
<button class="button alert" value="Send CtrlAltDel" id="sendCtrlAltDelButton">{{tr "Send CtrlAltDel"}}</button>
|
||||
<a class="button" id="open_in_a_new_window" href="" target="_blank" title="{{tr "Open in a new window"}}">
|
||||
<button class="button alert" id="sendCtrlAltDelButton">
|
||||
{{tr "Send CtrlAltDel"}}
|
||||
</button>
|
||||
<a class="button" id="open_in_a_new_window" href="#" target="_blank" title="{{tr "Open in a new window"}}">
|
||||
<i class="fas fa-external-link-alt detach-vnc-icon"/>
|
||||
</a>
|
||||
<button class="button secondary" data-close aria-label="{{tr "Close modal"}}" type="button" title="Close VNC">
|
||||
<button class="button secondary" data-close aria-label="{{tr "Close modal"}}" title="{{tr "Close VNC"}}">
|
||||
<i class="fas fa-times-circle"></i>
|
||||
</button>
|
||||
</span>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="large-12 columns">
|
||||
<div class="NOVNC_info"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="reveal-body text-center" style="width:100%; overflow-x:auto">
|
||||
<div id="VNC_canvas" width="640px">
|
||||
|
@ -22,6 +22,7 @@ define(function(require) {
|
||||
var Config = require("sunstone-config");
|
||||
var Notifier = require("utils/notifier");
|
||||
var Locale = require("utils/locale");
|
||||
var UtilsConnection = require("utils/info-connection/utils");
|
||||
|
||||
/**
|
||||
* CONSTRUCTOR
|
||||
@ -74,7 +75,9 @@ define(function(require) {
|
||||
|
||||
var tunnel = new Guacamole.WebSocketTunnel(wsprotocol + '//' + host + ':' + port + '/fireedge/guacamole')
|
||||
var guac = this._client = new Guacamole.Client(tunnel);
|
||||
var vm_name = response.vm_name || "";
|
||||
|
||||
var info_decode = UtilsConnection.decodeInfoConnection(response.info);
|
||||
UtilsConnection.printInfoConnection($('.guac_info'), info_decode)
|
||||
|
||||
// Client display
|
||||
this._display = $("#guacamole-display");
|
||||
@ -97,19 +100,19 @@ define(function(require) {
|
||||
guac.onstatechange = function(state) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
setStatus("Client IDLE to: " + vm_name);
|
||||
setStatus('Client IDLE');
|
||||
setLoading(true);
|
||||
break;
|
||||
case 1:
|
||||
setStatus("Client CONNECTING to: " + vm_name);
|
||||
setStatus('Client CONNECTING');
|
||||
setLoading(true);
|
||||
break;
|
||||
case 2:
|
||||
setStatus("Client WAITING to: " + vm_name);
|
||||
setStatus('Client WAITING');
|
||||
setLoading(true);
|
||||
break;
|
||||
case 3:
|
||||
setStatus("Client CONNECTED to: " + vm_name);
|
||||
setStatus('Client CONNECTED');
|
||||
setLoading(false);
|
||||
setTimeout(function() {
|
||||
rescale(that);
|
||||
@ -117,15 +120,15 @@ define(function(require) {
|
||||
}, 100);
|
||||
break;
|
||||
case 4:
|
||||
setStatus("Client DISCONNECTING to: " + vm_name);
|
||||
setStatus('Client DISCONNECTING');
|
||||
setLoading(true);
|
||||
break;
|
||||
case 5:
|
||||
setStatus("Client DISCONNECTED to: " + vm_name);
|
||||
setStatus('Client DISCONNECTED');
|
||||
setLoading(false);
|
||||
break;
|
||||
default:
|
||||
setStatus("Client ERROR to: " + vm_name);
|
||||
setStatus('Client ERROR');
|
||||
setLoading(false);
|
||||
break;
|
||||
}
|
||||
|
83
src/sunstone/public/app/utils/info-connection/info.hbs
Normal file
83
src/sunstone/public/app/utils/info-connection/info.hbs
Normal file
@ -0,0 +1,83 @@
|
||||
{{! -------------------------------------------------------------------------- }}
|
||||
{{! Copyright 2002-2021, OpenNebula Project, OpenNebula Systems }}
|
||||
{{! }}
|
||||
{{! Licensed under the Apache License, Version 2.0 (the "License"); you may }}
|
||||
{{! not use this file except in compliance with the License. You may obtain }}
|
||||
{{! a copy of the License at }}
|
||||
{{! }}
|
||||
{{! http://www.apache.org/licenses/LICENSE-2.0 }}
|
||||
{{! }}
|
||||
{{! Unless required by applicable law or agreed to in writing, software }}
|
||||
{{! distributed under the License is distributed on an "AS IS" BASIS, }}
|
||||
{{! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }}
|
||||
{{! See the License for the specific language governing permissions and }}
|
||||
{{! limitations under the License. }}
|
||||
{{! -------------------------------------------------------------------------- }}
|
||||
|
||||
<div style="
|
||||
color: #000000;
|
||||
font-weight: 300;
|
||||
line-height: 1.4;
|
||||
font-size: 1.3rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
margin: 1rem 0;
|
||||
">
|
||||
<div style="
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex-grow: 1;
|
||||
">
|
||||
{{!-- STATE --}}
|
||||
<span title="{{state}}" class="badge {{stateClass}}" style="min-width: auto;font-size: inherit;"></span>
|
||||
|
||||
{{!-- ID - NAME --}}
|
||||
<span>#{{ id }} - {{ name }}</span>
|
||||
|
||||
{{!-- SERVICE --}}
|
||||
{{#if service }}
|
||||
<span>(Part of: {{ service.NAME }})</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
|
||||
{{!-- START TIME --}}
|
||||
<div>
|
||||
<span>Started on: {{ humanizeTime start_time }}</span>
|
||||
</div>
|
||||
|
||||
{{!-- NETWORKS --}}
|
||||
{{#ifEquals networks.length 0 }}
|
||||
{{!-- dont render when if 0 --}}
|
||||
{{else}}
|
||||
<div>
|
||||
{{#ifEquals networks.length 1 }}
|
||||
<span>
|
||||
{{#each networks}} {{#if @first}} {{ this }} {{/if}} {{/each}}
|
||||
</span>
|
||||
{{else}}
|
||||
<ul class="dropdown menu ips-dropdown" data-dropdown-menu>
|
||||
<li>
|
||||
<a style="color: #000000">
|
||||
{{#each networks}} {{#if @first}} {{ this }} {{/if}} {{/each}}
|
||||
</a>
|
||||
<ul class="menu" style="
|
||||
max-height: 10em;
|
||||
max-width: 12em;
|
||||
overflow-y: auto;
|
||||
">
|
||||
{{#each networks}}
|
||||
<li>
|
||||
<a style="color:gray">{{ this }}</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
{{/ifEquals}}
|
||||
</div>
|
||||
{{/ifEquals}}
|
||||
</div>
|
57
src/sunstone/public/app/utils/info-connection/utils.js
Normal file
57
src/sunstone/public/app/utils/info-connection/utils.js
Normal file
@ -0,0 +1,57 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
define(function(require) {
|
||||
require('foundation')
|
||||
|
||||
var OpenNebulaVM = require('opennebula/vm');
|
||||
var OpenNebulaService = require('opennebula/service');
|
||||
|
||||
var TemplateInfo = require('hbs!./info');
|
||||
|
||||
function printInfoConnection(context, info) {
|
||||
context.empty()
|
||||
info && context.append(TemplateInfo(info))
|
||||
$('.ips-dropdown').foundation()
|
||||
}
|
||||
|
||||
function decodeInfoConnection(info_encode) {
|
||||
if (!info_encode) return undefined
|
||||
|
||||
try {
|
||||
var json = atob(info_encode)
|
||||
var info = JSON.parse(json)
|
||||
|
||||
// state class
|
||||
var stateId = OpenNebulaVM.STATES[info.state]
|
||||
var lcmStateId = OpenNebulaVM.LCM_STATES[info.state]
|
||||
var stateClass = OpenNebulaVM.stateClass(stateId) || OpenNebulaVM.lcmStateClass(lcmStateId)
|
||||
|
||||
// get service from cache or sync
|
||||
var service = OpenNebulaService.getService(info.service_id)
|
||||
|
||||
return $.extend(info, { stateClass, service })
|
||||
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
'printInfoConnection': printInfoConnection,
|
||||
'decodeInfoConnection': decodeInfoConnection
|
||||
}
|
||||
});
|
@ -44,6 +44,8 @@ define(function(require) {
|
||||
tr("November"), tr("December"));
|
||||
|
||||
function tr(str) {
|
||||
if (typeof locale === 'undefined') return str;
|
||||
|
||||
var tmp = locale[str];
|
||||
if (tmp == null || tmp == "") {
|
||||
tmp = str;
|
||||
|
@ -16,8 +16,9 @@
|
||||
|
||||
define(function(require) {
|
||||
require('spice-main');
|
||||
|
||||
var Config = require('sunstone-config');
|
||||
var Notifier = require('utils/notifier');
|
||||
var UtilsConnection = require("utils/info-connection/utils");
|
||||
|
||||
var _lock = false;
|
||||
var _sc;
|
||||
@ -42,14 +43,16 @@ define(function(require) {
|
||||
_lock = false;
|
||||
}
|
||||
|
||||
function spice_error(e) {
|
||||
function spice_error() {
|
||||
disconnect();
|
||||
}
|
||||
|
||||
function disconnect() {
|
||||
if (_sc) {
|
||||
_sc.stop();
|
||||
}
|
||||
try {
|
||||
if (_sc) {
|
||||
_sc.stop();
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function agent_connected(sc) {
|
||||
@ -60,26 +63,26 @@ define(function(require) {
|
||||
}
|
||||
|
||||
function spiceCallback(response) {
|
||||
var host, port, password, scheme = "ws://", uri, token, vm_name;
|
||||
|
||||
var scheme = "ws://";
|
||||
if (Config.vncWSS == "yes") {
|
||||
scheme = "wss://";
|
||||
}
|
||||
|
||||
host = window.location.hostname;
|
||||
port = Config.vncProxyPort;
|
||||
password = response["password"];
|
||||
token = response["token"];
|
||||
vm_name = response["vm_name"];
|
||||
var host = window.location.hostname;
|
||||
var port = Config.vncProxyPort;
|
||||
var password = response["password"];
|
||||
var token = response["token"];
|
||||
|
||||
var info = response.info;
|
||||
var info_decode = UtilsConnection.decodeInfoConnection(info);
|
||||
UtilsConnection.printInfoConnection($('.SPICE_info'), info_decode)
|
||||
|
||||
if ((!host) || (!port)) {
|
||||
console.log("must specify host and port in URL");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_sc) {
|
||||
_sc.stop();
|
||||
}
|
||||
disconnect()
|
||||
|
||||
uri = scheme + host + ":" + port + "?token=" + token;
|
||||
|
||||
@ -88,7 +91,7 @@ define(function(require) {
|
||||
message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected});
|
||||
}
|
||||
catch (e) {
|
||||
spice_error(e)
|
||||
disconnect()
|
||||
}
|
||||
|
||||
var url = "spice?";
|
||||
@ -97,7 +100,7 @@ define(function(require) {
|
||||
url += "&token=" + token;
|
||||
url += "&password=" + password;
|
||||
url += "&encrypt=" + config['user_config']['vnc_wss'];
|
||||
url += "&title=" + vm_name;
|
||||
url += "&info=" + info;
|
||||
|
||||
$("#open_in_a_new_window_spice").attr('href', url);
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
define(function (require) {
|
||||
var WMKS = require("wmks");
|
||||
var Config = require("sunstone-config");
|
||||
var UtilsConnection = require("utils/info-connection/utils");
|
||||
|
||||
var _lock = false;
|
||||
var _wmks;
|
||||
var _is_encrypted = "";
|
||||
@ -59,19 +61,7 @@ define(function (require) {
|
||||
}
|
||||
}
|
||||
|
||||
function desktopNameChange(e) {
|
||||
if (e.detail.name) {
|
||||
setStatus(null, "VMRC " + _wmks.connectionState + " (" + _is_encrypted + ") to: " /*+ e.detail.name*/);
|
||||
}
|
||||
}
|
||||
|
||||
function credentialsRequired(e) {
|
||||
setStatus("Something went wrong, more credentials must be given to continue", "Failed");
|
||||
}
|
||||
|
||||
function render(ticket, host_vmrc, port_vmrc, response){
|
||||
var URL = "";
|
||||
|
||||
var hostname = window.location.hostname;
|
||||
var port = window.location.port;
|
||||
var protocol = window.location.protocol;
|
||||
@ -79,14 +69,19 @@ define(function (require) {
|
||||
var fireedge_host = fireedge_endpoint.split(":")[0];
|
||||
var fireedge_port = fireedge_endpoint.split(":")[1];
|
||||
|
||||
var info = response.info;
|
||||
var info_decode = UtilsConnection.decodeInfoConnection(info);
|
||||
UtilsConnection.printInfoConnection($('.VMRC_info'), info_decode)
|
||||
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
|
||||
// Content of response.data
|
||||
var ticket = ticket ? ticket : urlParams.get('ticket');
|
||||
var host_vmrc = host_vmrc ? host_vmrc : urlParams.get('host');
|
||||
var port_vmrc = port_vmrc ? port_vmrc : urlParams.get('port');
|
||||
var ticket = ticket || urlParams.get('ticket');
|
||||
var host_vmrc = host_vmrc || urlParams.get('host');
|
||||
var port_vmrc = port_vmrc || urlParams.get('port');
|
||||
|
||||
var URL = "";
|
||||
if (protocol === "https:") {
|
||||
URL = "wss";
|
||||
_is_encrypted ="encrypted";
|
||||
@ -97,20 +92,21 @@ define(function (require) {
|
||||
|
||||
URL += "://" + fireedge_endpoint + "/";
|
||||
|
||||
var re = new RegExp("^(ws|wss):\\/\\/[\\w\\D]*?\\/", "gi");
|
||||
var link = URL.replace(re, protocol + "//" + hostname + ":" + port + "fireedge/vmrc?");
|
||||
var regex = new RegExp("^(ws|wss):\\/\\/[\\w\\D]*?\\/", "gi");
|
||||
var link = URL.replace(regex, protocol + "//" + hostname + ":" + port + "fireedge/vmrc?");
|
||||
|
||||
URL += "fireedge/vmrc/" + ticket;
|
||||
link += "host=" + fireedge_host;
|
||||
link += "&port=" + fireedge_port;
|
||||
link += "&ticket=" + ticket;
|
||||
link += "&info=" + info;
|
||||
|
||||
try {
|
||||
_wmks = WMKS.createWMKS("wmksContainer", {})
|
||||
_wmks = WMKS.createWMKS('wmksContainer', {})
|
||||
.register(WMKS.CONST.Events.CONNECTION_STATE_CHANGE,
|
||||
function (event, data) {
|
||||
if (typeof cons !== 'undefined' && data.state == cons.ConnectionState.CONNECTED) {
|
||||
console.log("connection state change : connected");
|
||||
function (_, data) {
|
||||
if (data.state === WMKS.CONST.ConnectionState.CONNECTED) {
|
||||
console.log("connection state change: connected");
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -119,9 +115,9 @@ define(function (require) {
|
||||
_wmks.eventHandlers["disconnect"] = disconnectedFromServer;
|
||||
|
||||
_wmks.connect(URL);
|
||||
_wmks["vm_name"] = response.vm_name ? response.vm_name:"";
|
||||
link += "&name=" + _wmks["vm_name"];
|
||||
|
||||
$("#VMRC_buttons #open_in_a_new_window").attr("href",link);
|
||||
|
||||
} catch (err) {
|
||||
setStatus("Something went wrong, connection is closed", "Failed");
|
||||
console.log("error start VMRC ", err);
|
||||
@ -129,14 +125,13 @@ define(function (require) {
|
||||
}
|
||||
|
||||
function vmrcCallback(response) {
|
||||
if (response.data){
|
||||
|
||||
render(response.data.ticket,
|
||||
if (response.data) {
|
||||
render(
|
||||
response.data.ticket,
|
||||
response.data.host,
|
||||
response.data.port,
|
||||
response);
|
||||
|
||||
|
||||
response
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,14 +15,15 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
define(function(require) {
|
||||
var RFB = require("vnc-rfb").default;
|
||||
var Config = require("sunstone-config");
|
||||
var UtilsConnection = require("utils/info-connection/utils");
|
||||
|
||||
var RFB = require("vnc-rfb").default;
|
||||
var _lock = false;
|
||||
var _rfb;
|
||||
var _message = "";
|
||||
var _status = "Loading";
|
||||
var _is_encrypted = "";
|
||||
var _vm_name;
|
||||
|
||||
return {
|
||||
"lockStatus": lockStatus,
|
||||
@ -51,14 +52,14 @@ define(function(require) {
|
||||
$(".NOVNC_message").text(_message);
|
||||
$("#VNC_status").text(_status);
|
||||
}
|
||||
|
||||
|
||||
function connected(){
|
||||
setStatus(null, "VNC " + _rfb._rfb_connection_state + " (" + _is_encrypted + ") to: " + (_vm_name || _rfb._fb_name));
|
||||
setStatus(null, "VNC " + _rfb._rfb_connection_state + " (" + _is_encrypted + ") to: " + _rfb._fb_name);
|
||||
}
|
||||
|
||||
function disconnectedFromServer(e){
|
||||
if (e.detail.clean) {
|
||||
setStatus(null, "VNC " + _rfb._rfb_connection_state + " (" + _is_encrypted + ") to: " + (_vm_name || _rfb._fb_name));
|
||||
setStatus(null, "VNC " + _rfb._rfb_connection_state + " (" + _is_encrypted + ") to: " + _rfb._fb_name);
|
||||
} else {
|
||||
setStatus("Something went wrong, connection is closed", "Failed");
|
||||
}
|
||||
@ -76,15 +77,20 @@ define(function(require) {
|
||||
|
||||
function vncCallback(response) {
|
||||
var URL = "";
|
||||
var proxy_host = window.location.hostname;
|
||||
var proxy_port = Config.vncProxyPort;
|
||||
var pw = response["password"];
|
||||
var token = response["token"];
|
||||
var vm_name = _vm_name = response["vm_name"];
|
||||
|
||||
var pw = response.password;
|
||||
var token = response.token;
|
||||
|
||||
var info_decode = UtilsConnection.decodeInfoConnection(response.info);
|
||||
UtilsConnection.printInfoConnection($('.NOVNC_info'), info_decode)
|
||||
|
||||
var proxy_host = window.location.hostname;
|
||||
var protocol = window.location.protocol;
|
||||
var hostname = window.location.hostname;
|
||||
var port = window.location.port;
|
||||
var rfbConfig = pw? { "credentials": { "password": pw } } : {};
|
||||
|
||||
var rfbConfig = pw ? { "credentials": { "password": pw } } : {};
|
||||
|
||||
if (protocol === "https:") {
|
||||
URL = "wss";
|
||||
@ -99,7 +105,7 @@ define(function(require) {
|
||||
URL += "&port=" + proxy_port;
|
||||
URL += "&token=" + token;
|
||||
URL += "&encrypt=" + Config.vncWSS;
|
||||
URL += "&title=" + vm_name;
|
||||
URL += "&info=" + response.info;
|
||||
|
||||
if (!Config.requestVNCPassword) {
|
||||
URL += "&password=" + pw;
|
||||
|
@ -36,8 +36,6 @@ html {
|
||||
#noVNC_password {
|
||||
width: 150px;
|
||||
}
|
||||
#noVNC_encrypt {
|
||||
}
|
||||
#noVNC_path {
|
||||
width: 100px;
|
||||
}
|
||||
@ -85,11 +83,7 @@ html {
|
||||
}
|
||||
|
||||
#noVNC_status {
|
||||
font-size: 12px;
|
||||
padding-top: 4px;
|
||||
height:32px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#noVNC_settings_menu {
|
||||
@ -114,7 +108,6 @@ html {
|
||||
height: 36px;
|
||||
}
|
||||
#noVNC_screen {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
height: 100%;
|
||||
@ -395,10 +388,8 @@ html {
|
||||
}
|
||||
|
||||
#noVNC_status {
|
||||
z-index: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
#showExtraKeysButton { display: none; }
|
||||
@ -414,7 +405,6 @@ html {
|
||||
position: relative;
|
||||
width: auto;
|
||||
float: left;
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,13 +8,18 @@ body
|
||||
|
||||
* { margin: 0; }
|
||||
|
||||
#spice-area
|
||||
{
|
||||
main {
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
}
|
||||
|
||||
#spice-area {
|
||||
display: flex;
|
||||
background-color: rgb(40, 40, 40);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.spice-screen
|
||||
{
|
||||
min-height: 600px;
|
||||
|
@ -258,13 +258,13 @@ if $conf[:webauthn_avail]
|
||||
end
|
||||
|
||||
#start VNC proxy
|
||||
$vnc = OpenNebulaVNC.new($conf, logger)
|
||||
$vnc = SunstoneVNC.new($conf, logger)
|
||||
|
||||
#init Guacamole server
|
||||
$guac = OpenNebulaGuac.new(logger)
|
||||
$guac = SunstoneGuac.new(logger)
|
||||
|
||||
#init VMRC server
|
||||
$vmrc = OpenNebulaVMRC.new(logger)
|
||||
$vmrc = SunstoneVMRC.new(logger)
|
||||
|
||||
configure do
|
||||
set :run, false
|
||||
@ -709,10 +709,10 @@ get '/vnc' do
|
||||
erb :login
|
||||
else
|
||||
erb :vnc, :locals => {
|
||||
:logos_conf => $conf[:locals][:logos_conf],
|
||||
:oned_conf => $conf[:locals][:oned_conf],
|
||||
:support => $conf[:locals][:support],
|
||||
:upgrade => $conf[:locals][:upgrade]
|
||||
:logos_conf => $conf[:locals][:logos_conf],
|
||||
:oned_conf => $conf[:locals][:oned_conf],
|
||||
:support => $conf[:locals][:support],
|
||||
:upgrade => $conf[:locals][:upgrade]
|
||||
}
|
||||
end
|
||||
end
|
||||
@ -723,10 +723,10 @@ get '/vmrc' do
|
||||
erb :login
|
||||
else
|
||||
erb :vmrc, :locals => {
|
||||
:logos_conf => $conf[:locals][:logos_conf],
|
||||
:oned_conf => $conf[:locals][:oned_conf],
|
||||
:support => $conf[:locals][:support],
|
||||
:upgrade => $conf[:locals][:upgrade]
|
||||
:logos_conf => $conf[:locals][:logos_conf],
|
||||
:oned_conf => $conf[:locals][:oned_conf],
|
||||
:support => $conf[:locals][:support],
|
||||
:upgrade => $conf[:locals][:upgrade]
|
||||
}
|
||||
end
|
||||
end
|
||||
@ -736,8 +736,12 @@ get '/spice' do
|
||||
if !authorized?
|
||||
erb :login
|
||||
else
|
||||
params[:title] = CGI::escape(params[:title])
|
||||
erb :spice
|
||||
erb :spice, :locals => {
|
||||
:logos_conf => $conf[:locals][:logos_conf],
|
||||
:oned_conf => $conf[:locals][:oned_conf],
|
||||
:support => $conf[:locals][:support],
|
||||
:upgrade => $conf[:locals][:upgrade]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -26,36 +26,81 @@
|
||||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<head>
|
||||
<!-- Stylesheets -->
|
||||
<link rel="stylesheet" type="text/css" href="css/app.css" title="plain">
|
||||
<link rel="stylesheet" type="text/css" href="css/spice-custom.css" />
|
||||
</head>
|
||||
|
||||
<title><%= params['title']%></title>
|
||||
<link rel="stylesheet" type="text/css" href="css/spice-custom.css" />
|
||||
<script src="dist/console/spice.js?v=<%= OpenNebula::VERSION %>"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div style="background: #f7f7f7; border-bottom: 1px solid #dfdfdf; padding: 10px 0px 15px 0px">
|
||||
<div id="noVNC_status_bar" class="noVNC_status_bar" style="margin-top: 0px;">
|
||||
<table border=0 width="100%"><tr>
|
||||
<td width="1%" >
|
||||
<img src="images/one_small_logo.png" style="height:40px; vertical-align:top; margin-left: 30px">
|
||||
</td>
|
||||
<td><div id="message-div" class="spice-message"></div></td>
|
||||
</tr></table>
|
||||
</div>
|
||||
<body>
|
||||
<main>
|
||||
<div style="background: #f7f7f7; padding: 1.5em 1.5em 0.8em;">
|
||||
<div style="max-width: 1250px; margin: 0 auto;">
|
||||
<div id="noVNC_status_bar" class="noVNC_status_bar" style="display: flex; align-items: center;">
|
||||
<img src="images/one_small_logo.png" style="height:40px;">
|
||||
<h5 id="message-div" class="spice-message"></h5>
|
||||
</div>
|
||||
<div class="SPICE_info"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="spice-area">
|
||||
<div id="spice-screen" class="spice-screen"></div>
|
||||
</div>
|
||||
<div id="spice-area">
|
||||
<div id="spice-screen" class="spice-screen"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="debug-div">
|
||||
<!-- If DUMPXXX is turned on, dumped images will go here -->
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div id="debug-div">
|
||||
<!-- If DUMPXXX is turned on, dumped images will go here -->
|
||||
</div>
|
||||
|
||||
</body>
|
||||
<script src="dist/console/spice.js?v=<%= OpenNebula::VERSION %>"></script>
|
||||
<% view = $views_config.view(session[:user], session[:user_gname], session[:default_view]) %>
|
||||
<script type="text/javascript">
|
||||
var csrftoken = '<%= session[:csrftoken] %>';
|
||||
var view = JSON.parse('<%= view.to_json %>')
|
||||
var available_views = JSON.parse('["<%=
|
||||
$views_config.available_views(session[:user], session[:user_gname]).join('","')
|
||||
%>"]')
|
||||
var all_labels = JSON.parse('["<%=
|
||||
$views_config.get_all_labels(session[:user_gname]).join('","')
|
||||
%>"]')
|
||||
var all_views = JSON.parse('["<%=
|
||||
$views_config.get_all_views.join('","')
|
||||
%>"]')
|
||||
if ('<%= $conf[:addons] %>'){
|
||||
var addons = JSON.parse('<%= $conf[:addons].to_json %>');
|
||||
}
|
||||
var config = {
|
||||
'user_config' : {
|
||||
'lang' : '<%= session[:lang] %>',
|
||||
'vnc_wss' : '<%= session[:vnc_wss] %>',
|
||||
'table_order' : '<%= session[:table_order] %>',
|
||||
'default_view' : '<%= session[:default_view] %>',
|
||||
'page_length' : '<%= session[:page_length] %>'
|
||||
},
|
||||
'system_config' : {
|
||||
'marketplace_url' : '<%= $conf[:marketplace_url] %>',
|
||||
'vnc_request_password' : <%= $conf[:vnc_request_password] || false %>,
|
||||
'vnc_proxy_port' : '<%= $vnc.proxy_port %>',
|
||||
'vnc_client_port' : '<%= $conf[:vnc_client_port] %>',
|
||||
'max_upload_file_size' : <%= $conf[:max_upload_file_size] ? $conf[:max_upload_file_size] : "undefined" %>
|
||||
},
|
||||
'view' : view,
|
||||
'available_views' : available_views,
|
||||
'all_labels' : all_labels,
|
||||
'all_views' : all_views,
|
||||
'user_id' : '<%= session[:user_id] %>',
|
||||
'user_gid' : '<%= session[:user_gid] %>',
|
||||
'display_name' : '<%= session[:display_name] %>',
|
||||
'zone_name' : '<%= session[:zone_name] %>',
|
||||
'zone_id' : '<%= session[:zone_id] %>',
|
||||
'federation_mode' : '<%= session[:federation_mode] %>',
|
||||
'vm_logos' : <%= logos_conf.to_json %>,
|
||||
'oned_conf' : <%= oned_conf.to_json %>,
|
||||
'support' : <%= support.to_json %>,
|
||||
'upgrade' : <%= upgrade.to_json %>,
|
||||
'mode' : '<%= session[:mode] %>'
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,97 +1,89 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><%= params['vm_name']%></title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<link rel="apple-touch-startup-image" href="images/screen_320x460.png" />
|
||||
<link rel="apple-touch-icon" href="images/screen_57x57.png">
|
||||
<!-- Stylesheets -->
|
||||
<link rel="stylesheet" type="text/css" href="css/novnc-custom.css" title="plain">
|
||||
<% view = $views_config.view(session[:user], session[:user_gname], session[:default_view]) %>
|
||||
<script type="text/javascript">
|
||||
var csrftoken = '<%= session[:csrftoken] %>';
|
||||
var view = JSON.parse('<%= view.to_json %>')
|
||||
var available_views = JSON.parse('["<%=
|
||||
$views_config.available_views(session[:user], session[:user_gname]).join('","')
|
||||
%>"]')
|
||||
var all_labels = JSON.parse('["<%=
|
||||
$views_config.get_all_labels(session[:user_gname]).join('","')
|
||||
%>"]')
|
||||
var all_views = JSON.parse('["<%=
|
||||
$views_config.get_all_views.join('","')
|
||||
%>"]')
|
||||
if ('<%= $conf[:addons] %>'){
|
||||
var addons = JSON.parse('<%= $conf[:addons].to_json %>');
|
||||
}
|
||||
var config = {
|
||||
'user_config' : {
|
||||
'lang' : '<%= session[:lang] %>',
|
||||
'vnc_wss' : '<%= session[:vnc_wss] %>',
|
||||
'table_order' : '<%= session[:table_order] %>',
|
||||
'default_view' : '<%= session[:default_view] %>',
|
||||
'page_length' : '<%= session[:page_length] %>'
|
||||
},
|
||||
'system_config' : {
|
||||
'marketplace_url' : '<%= $conf[:marketplace_url] %>',
|
||||
'vnc_request_password' : <%= $conf[:vnc_request_password] || false %>,
|
||||
'vnc_proxy_port' : '<%= $vnc.proxy_port %>',
|
||||
'vnc_client_port' : '<%= $conf[:vnc_client_port] %>',
|
||||
'max_upload_file_size' : <%= $conf[:max_upload_file_size] ? $conf[:max_upload_file_size] : "undefined" %>
|
||||
},
|
||||
'view' : view,
|
||||
'available_views' : available_views,
|
||||
'all_labels' : all_labels,
|
||||
'all_views' : all_views,
|
||||
'user_id' : '<%= session[:user_id] %>',
|
||||
'user_gid' : '<%= session[:user_gid] %>',
|
||||
'display_name' : '<%= session[:display_name] %>',
|
||||
'zone_name' : '<%= session[:zone_name] %>',
|
||||
'zone_id' : '<%= session[:zone_id] %>',
|
||||
'federation_mode' : '<%= session[:federation_mode] %>',
|
||||
'vm_logos' : <%= logos_conf.to_json %>,
|
||||
'oned_conf' : <%= oned_conf.to_json %>,
|
||||
'support' : <%= support.to_json %>,
|
||||
'upgrade' : <%= upgrade.to_json %>,
|
||||
'mode' : '<%= session[:mode] %>'
|
||||
};
|
||||
</script>
|
||||
<script src="dist/console/vnc.js?v=<%= OpenNebula::VERSION %>"></script>
|
||||
</head>
|
||||
<body style="margin: 0px;">
|
||||
<div id="noVNC_screen">
|
||||
<div style="background: #f7f7f7; border-bottom: 1px solid #dfdfdf; padding: 10px 0px 15px 0px">
|
||||
<div id="noVNC_status_bar" class="noVNC_status_bar" style="margin-top: 0px;">
|
||||
<table border=0 width="100%">
|
||||
<tr>
|
||||
<td width="1%" >
|
||||
<img src="images/one_small_logo.png" style="height:40px; vertical-align:top; margin-left: 30px"></td>
|
||||
<td>
|
||||
<div id="noVNC_status" style="position: relative; height: auto; color: #000;">Loading</div>
|
||||
</td>
|
||||
<td width="1%" >
|
||||
<div id="noVNC_buttons" style="margin-right: 30px">
|
||||
<input type=button value="Send CtrlAltDel"
|
||||
id="sendCtrlAltDelButton">
|
||||
<span id="noVNC_xvp_buttons">
|
||||
<input type=button value="Shutdown"
|
||||
id="xvpShutdownButton">
|
||||
<input type=button value="Reboot"
|
||||
id="xvpRebootButton">
|
||||
<input type=button value="Reset"
|
||||
id="xvpResetButton"></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<link rel="apple-touch-startup-image" href="images/screen_320x460.png" />
|
||||
<link rel="apple-touch-icon" href="images/screen_57x57.png">
|
||||
<!-- Stylesheets -->
|
||||
<link rel="stylesheet" type="text/css" href="css/app.css" title="plain">
|
||||
<link rel="stylesheet" type="text/css" href="css/novnc-custom.css" title="plain">
|
||||
</head>
|
||||
<body>
|
||||
<div id="noVNC_screen">
|
||||
<div style="background: #f7f7f7; padding: 1.5em 1.5em 0.8em;">
|
||||
<div style="max-width: 1250px; margin: 0 auto;">
|
||||
<div id="noVNC_status_bar" class="noVNC_status_bar" style="display: flex; align-items: center;">
|
||||
<img src="images/one_small_logo.png" style="height:40px;">
|
||||
<h5 id="noVNC_status" style="position: relative;">Loading</h5>
|
||||
<div id="noVNC_buttons">
|
||||
<button class="button alert" id="sendCtrlAltDelButton">Send CtrlAltDel</button>
|
||||
<span id="noVNC_xvp_buttons">
|
||||
<input type=button value="Shutdown" id="xvpShutdownButton">
|
||||
<input type=button value="Reboot" id="xvpRebootButton">
|
||||
<input type=button value="Reset" id="xvpResetButton">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="VNC_canvas" width="640px" height="20px">
|
||||
<div class="NOVNC_message"></div>
|
||||
</div>
|
||||
<div class="NOVNC_info"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
<div id="VNC_canvas" width="640px" height="20px">
|
||||
<div class="NOVNC_message"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="dist/console/vnc.js?v=<%= OpenNebula::VERSION %>"></script>
|
||||
<% view = $views_config.view(session[:user], session[:user_gname], session[:default_view]) %>
|
||||
<script type="text/javascript">
|
||||
var csrftoken = '<%= session[:csrftoken] %>';
|
||||
var view = JSON.parse('<%= view.to_json %>')
|
||||
var available_views = JSON.parse('["<%=
|
||||
$views_config.available_views(session[:user], session[:user_gname]).join('","')
|
||||
%>"]')
|
||||
var all_labels = JSON.parse('["<%=
|
||||
$views_config.get_all_labels(session[:user_gname]).join('","')
|
||||
%>"]')
|
||||
var all_views = JSON.parse('["<%=
|
||||
$views_config.get_all_views.join('","')
|
||||
%>"]')
|
||||
if ('<%= $conf[:addons] %>'){
|
||||
var addons = JSON.parse('<%= $conf[:addons].to_json %>');
|
||||
}
|
||||
var config = {
|
||||
'user_config' : {
|
||||
'lang' : '<%= session[:lang] %>',
|
||||
'vnc_wss' : '<%= session[:vnc_wss] %>',
|
||||
'table_order' : '<%= session[:table_order] %>',
|
||||
'default_view' : '<%= session[:default_view] %>',
|
||||
'page_length' : '<%= session[:page_length] %>'
|
||||
},
|
||||
'system_config' : {
|
||||
'marketplace_url' : '<%= $conf[:marketplace_url] %>',
|
||||
'vnc_request_password' : <%= $conf[:vnc_request_password] || false %>,
|
||||
'vnc_proxy_port' : '<%= $vnc.proxy_port %>',
|
||||
'vnc_client_port' : '<%= $conf[:vnc_client_port] %>',
|
||||
'max_upload_file_size' : <%= $conf[:max_upload_file_size] ? $conf[:max_upload_file_size] : "undefined" %>
|
||||
},
|
||||
'view' : view,
|
||||
'available_views' : available_views,
|
||||
'all_labels' : all_labels,
|
||||
'all_views' : all_views,
|
||||
'user_id' : '<%= session[:user_id] %>',
|
||||
'user_gid' : '<%= session[:user_gid] %>',
|
||||
'display_name' : '<%= session[:display_name] %>',
|
||||
'zone_name' : '<%= session[:zone_name] %>',
|
||||
'zone_id' : '<%= session[:zone_id] %>',
|
||||
'federation_mode' : '<%= session[:federation_mode] %>',
|
||||
'vm_logos' : <%= logos_conf.to_json %>,
|
||||
'oned_conf' : <%= oned_conf.to_json %>,
|
||||
'support' : <%= support.to_json %>,
|
||||
'upgrade' : <%= upgrade.to_json %>,
|
||||
'mode' : '<%= session[:mode] %>'
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user