1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-11 05:17:41 +03:00

Merge branch 'feature-1370'

This commit is contained in:
Ruben S. Montero 2013-03-06 12:43:07 +01:00
commit c560d389f0
8 changed files with 293 additions and 42 deletions

View File

@ -49,7 +49,13 @@ usage() {
}
#-------------------------------------------------------------------------------
TEMP_OPT=`getopt -o hkrlcsou:g:d: -n 'install.sh' -- "$@"`
PARAMETERS="hkrlcsou:g:d:"
if [ $(getopt --version | tr -d " ") = "--" ]; then
TEMP_OPT=`getopt $PARAMETERS "$@"`
else
TEMP_OPT=`getopt -o $PARAMETERS -n 'install.sh' -- "$@"`
fi
if [ $? != 0 ] ; then
usage
@ -685,7 +691,8 @@ RUBY_LIB_FILES="src/mad/ruby/ActionManager.rb \
src/vnm_mad/one_vnm.rb \
src/mad/ruby/Ganglia.rb \
src/oca/ruby/deprecated/OpenNebula.rb \
src/oca/ruby/opennebula.rb"
src/oca/ruby/opennebula.rb \
src/sunstone/OpenNebulaVNC.rb"
#-------------------------------------------------------------------------------
# Ruby auth library files, to be installed under $LIB_LOCATION/ruby/opennebula
@ -1396,9 +1403,10 @@ ETC_CLIENT_FILES="src/cli/etc/group.default"
#-----------------------------------------------------------------------------
SUNSTONE_FILES="src/sunstone/sunstone-server.rb \
src/sunstone/OpenNebulaVNC.rb"
src/sunstone/config.ru"
SUNSTONE_BIN_FILES="src/sunstone/bin/sunstone-server"
SUNSTONE_BIN_FILES="src/sunstone/bin/sunstone-server \
src/sunstone/bin/novnc-server"
SUNSTONE_ETC_FILES="src/sunstone/etc/sunstone-server.conf \
src/sunstone/etc/sunstone-plugins.yaml"

View File

@ -124,6 +124,24 @@ function set_downloader_args {
echo "$HASHES $5 $6"
}
#------------------------------------------------------------------------------
# Gets the size in bytes of a file
# @param $1 - Path to the image
# @return size of the image in bytes
#------------------------------------------------------------------------------
function file_size {
stat --version &> /dev/null
if [ $? = 0 ]; then
STAT_CMD="stat -c %s"
else
STAT_CMD="stat -f %z"
fi
$STAT_CMD "$*"
}
#-------------------------------------------------------------------------------
# Computes the size of an image
# @param $1 - Path to the image
@ -156,7 +174,7 @@ function fs_size {
SIZE=`du -sb "$1" | cut -f1`
error=$?
else
SIZE=`stat -c %s "$1"`
SIZE=$(file_size "$1")
error=$?
fi
;;

View File

@ -27,9 +27,10 @@ class OpenNebulaVNC
attr_reader :proxy_port
def initialize(config, logger, opts={
:json_errors => true,
:token_folder_name => 'sunstone_vnc_tokens'})
def initialize(config, logger, options = {})
opts={ :json_errors => true,
:token_folder_name => 'sunstone_vnc_tokens'}.merge(options)
@pipe = nil
@token_folder = File.join(VAR_LOCATION, opts[:token_folder_name])
@proxy_path = config[:vnc_proxy_path]
@ -38,6 +39,8 @@ class OpenNebulaVNC
@wss = config[:vnc_proxy_support_wss]
@lock_file = config[:lock_file] || '/tmp/novnc.lock'
if (@wss == "yes") || (@wss == "only") || (@wss == true)
@enable_wss = true
@cert = config[:vnc_proxy_cert]
@ -48,21 +51,24 @@ class OpenNebulaVNC
@options = opts
@logger = logger
begin
Dir.mkdir(@token_folder)
rescue Exception => e
@logger.error "Cannot create token folder"
@logger.error e.message
end
end
def start
if @proxy_path == nil || @proxy_path.empty?
@logger.info "VNC proxy not configured"
return
if is_running?
message="VNC server already running"
STDERR.puts message
@logger.info message
return false
end
if @proxy_path == nil || @proxy_path.empty?
@logger.error "VNC proxy not configured"
return false
end
create_token_dir
proxy_options = "--target-config=#{@token_folder} "
if @enable_wss
@ -75,16 +81,31 @@ class OpenNebulaVNC
begin
@logger.info { "Starting VNC proxy: #{cmd}" }
@pipe = IO.popen(cmd,'r')
pid=start_daemon(cmd, 'VNC_LOG')
rescue Exception => e
@logger.error e.message
return
return false
end
File.write(@lock_file, pid)
sleep 1
if !is_running?
message="Error starting VNC proxy"
STDERR.puts message
@logger.error message
File.delete(@lock_file) if File.exist?(@lock_file)
return false
end
true
end
def proxy(vm_resource)
# Check configurations and VM attributes
if !@pipe
if !is_running?
return error(400, "VNC Proxy is not running")
end
@ -121,12 +142,6 @@ class OpenNebulaVNC
:token => random_str,
}
# Delete token soon after
Thread.new do
sleep TOKEN_EXPIRE_SECONDS
delete_token(token_file)
end
return [200, info.to_json]
end
@ -140,16 +155,40 @@ class OpenNebulaVNC
end
end
def stop
if !@pipe then return end
@logger.info "Killing VNC proxy"
Process.kill('TERM',@pipe.pid)
@pipe.close
begin
Dir.rmdir(@token_folder)
rescue => e
@logger.error "Error deleting token folder"
@logger.error e.message
def stop(force=false)
pid=get_pid
if pid
@logger.info "Killing VNC proxy"
signal=(force ? 'KILL' : 'TERM')
Process.kill(signal ,pid)
sleep 1
if is_running?
message="VNC server is still running"
STDERR.puts message
logger.error message
return false
end
delete_token_dir
else
message="VNC server is not running"
@logger.info message
STDERR.puts message
end
true
end
def status
if is_running?
STDOUT.puts "VNC is running"
true
else
STDOUT.puts "VNC is NOT running"
false
end
end
@ -163,4 +202,56 @@ class OpenNebulaVNC
end
end
def create_token_dir
delete_token_dir
begin
Dir.mkdir(@token_folder) if !File.exist?(@token_folder)
rescue Exception => e
@logger.error "Cannot create token folder"
@logger.error e.message
end
end
def delete_token_dir
if File.exist?(@token_folder)
begin
Dir.glob("#{@token_folder}/*").each do |file|
File.delete(file)
end
Dir.rmdir(@token_folder)
rescue => e
@logger.error "Error deleting token folder"
@logger.error e.message
end
end
end
def is_running?
if File.exist?(@lock_file)
pid=File.read(@lock_file).strip
if system("ps #{pid} 1> /dev/null")
return pid.to_i
end
@logger.info "Deleting stale lock file"
File.delete(@lock_file)
end
false
end
alias_method :get_pid, :is_running?
def start_daemon(cmd, log)
pid=spawn(*cmd.split(" "),
:pgroup => true,
:in => :close,
[:out, :err] => [log, "a"],
:close_others => true )
Process.detach(pid)
pid
end
end

87
src/sunstone/bin/novnc-server Executable file
View File

@ -0,0 +1,87 @@
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
ONE_LOCATION = ENV["ONE_LOCATION"]
if !ONE_LOCATION
LOG_LOCATION = "/var/log/one"
LOCK_LOCATION = "/var/lock/one"
VAR_LOCATION = "/var/lib/one"
ETC_LOCATION = "/etc/one"
RUBY_LIB_LOCATION = "/usr/lib/one/ruby"
else
VAR_LOCATION = ONE_LOCATION + "/var"
LOCK_LOCATION = ONE_LOCATION + "/var"
LOG_LOCATION = ONE_LOCATION + "/var"
ETC_LOCATION = ONE_LOCATION + "/etc"
RUBY_LIB_LOCATION = ONE_LOCATION+"/lib/ruby"
end
VNC_LOCK = LOCK_LOCATION + "/novnc.lock"
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__)
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+'/cloud'
$: << SUNSTONE_ROOT_DIR
$: << SUNSTONE_ROOT_DIR+'/models'
require 'logger'
require 'yaml'
require 'OpenNebulaVNC'
$log=Logger.new(VNC_LOG)
begin
conf = YAML.load_file(CONFIGURATION_FILE)
rescue Exception => e
STDERR.puts "Error parsing config file #{CONFIGURATION_FILE}: #{e.message}"
exit 1
end
vnc=OpenNebulaVNC.new(conf, $log)
if ARGV[0]
res=case ARGV[0].downcase.to_sym
when :start
vnc.start
when :stop
vnc.stop(ARGV[1]=='--force')
when :restart
vnc.stop
sleep 1
vnc.start
when :status
vnc.status
end
if !res
STDERR.puts "Error, check #{VNC_LOG}"
exit(-1)
end
else
exit(-1)
end

View File

@ -24,6 +24,7 @@ if [ -z "$ONE_LOCATION" ]; then
SUNSTONE_LOG=/var/log/one/sunstone.log
SUNSTONE_LOG_ERROR=/var/log/one/sunstone.error
SUNSTONE_CONF=/etc/one/sunstone-server.conf
NOVNC_SERVER=/usr/bin/novnc-server
else
SUNSTONE_PID=$ONE_LOCATION/var/sunstone.pid
SUNSTONE_SERVER=$ONE_LOCATION/lib/sunstone/sunstone-server.rb
@ -31,6 +32,7 @@ else
SUNSTONE_LOG=$ONE_LOCATION/var/sunstone.log
SUNSTONE_LOG_ERROR=$ONE_LOCATION/var/sunstone.error
SUNSTONE_CONF=$ONE_LOCATION/etc/sunstone-server.conf
NOVNC_SERVER=$ONE_LOCATION/bin/novnc-server
fi
setup()
@ -65,6 +67,13 @@ start()
exit 1
fi
# Start novnc server
$NOVNC_SERVER start
if [ "$?" != "0" ]; then
echo "Could not start novnc server" 1>&2
fi
# Start the sunstone daemon
touch $SUNSTONE_LOCK_FILE
ruby $SUNSTONE_SERVER > $SUNSTONE_LOG 2>$SUNSTONE_LOG_ERROR &
@ -95,6 +104,9 @@ start()
#
stop()
{
# Stop novnc server
$NOVNC_SERVER stop
if [ ! -f $SUNSTONE_PID ]; then
echo "Couldn't find sunstone-server process pid."
exit 1

12
src/sunstone/config.ru Executable file
View File

@ -0,0 +1,12 @@
# If you are using self contained installation set this variable to the
# install location
#ENV['ONE_LOCATION']='/path/to/OpenNebula/install'
WITH_RACKUP=true
$: << '.'
require 'sunstone-server'
run Sinatra::Application

View File

@ -31,6 +31,16 @@
:host: 127.0.0.1
:port: 9869
# Place where to store sessions, this value can be memory or memcache
# Use memcache when starting multiple server processes, for example,
# with passenger
:sessions: memory
# Memcache configuration
:memcache_host: localhost
:memcache_port: 11211
:memcache_namespace: opennebula.sunstone
################################################################################
# Log
################################################################################

View File

@ -80,7 +80,23 @@ set :config, conf
set :bind, settings.config[:host]
set :port, settings.config[:port]
use Rack::Session::Pool, :key => 'sunstone'
case settings.config[:sessions]
when 'memory'
use Rack::Session::Pool, :key => 'sunstone'
when 'memcache'
memcache_server=settings.config[:memcache_host]+':'<<
settings.config[:memcache_port].to_s
STDERR.puts memcache_server
use Rack::Session::Memcache,
:memcache_server => memcache_server,
:namespace => settings.config[:memcache_namespace]
else
STDERR.puts "Wrong value for :sessions in configuration file"
exit(-1)
end
# Enable logger
@ -104,10 +120,6 @@ set :cloud_auth, cloud_auth
configure do
set :run, false
set :vnc, OpenNebulaVNC.new(conf, settings.logger)
settings.vnc.start()
Kernel.at_exit do
settings.vnc.stop
end
end
##############################################################################
@ -396,4 +408,5 @@ post '/:resource/:id/action' do
request.body.read)
end
Sinatra::Application.run!
Sinatra::Application.run! if(!defined?(WITH_RACKUP))