class OpenNebulaVNC

Attributes

proxy_port[R]

Public Class Methods

new(config, logger, options = {}) click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 59
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   = File.join(SHARE_LOCATION, 'websockify/websocketproxy.py')
  @proxy_port   = config[:vnc_proxy_port]

  @proxy_ipv6   = config[:vnc_proxy_ipv6]

  @wss = config[:vnc_proxy_support_wss]

  @lock_file = NOVNC_LOCK_FILE

  if (@wss == 'yes') || (@wss == 'only') || (@wss == true)
    @enable_wss = true
    @cert       = config[:vnc_proxy_cert]
    @key        = config[:vnc_proxy_key]
  else
    @enable_wss = false
  end
  @options = opts
  @logger = logger
end

Public Instance Methods

delete_token(filename) click to toggle source

Delete proxy token file

# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 182
def delete_token(filename)
  File.delete(File.join(@token_folder, filename))
rescue StandardError => e
  @logger.error "Error deleting token file for VM #{vm_id}"
  @logger.error e.message
end
proxy(vm_resource) click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 135
def proxy(vm_resource)
  # Check configurations and VM attributes
  # if !is_running?
  #    return error(400, "VNC Proxy is not running")
  # end

  unless VNC_STATES.include?(vm_resource['LCM_STATE'])
    return error(400, "Wrong state (#{vm_resource['LCM_STATE']}) to open a VNC session")
  end

  if vm_resource['TEMPLATE/GRAPHICS/TYPE'].nil? ||
     !vm_resource['TEMPLATE/GRAPHICS/TYPE'].casecmp('vnc').zero?
    return error(400, 'VM has no VNC configured')
  end

  # Proxy data
  host     = vm_resource['HISTORY_RECORDS/HISTORY[last()]/HOSTNAME']
  vnc_port = vm_resource['TEMPLATE/GRAPHICS/PORT']
  vnc_pw = vm_resource['TEMPLATE/GRAPHICS/PASSWD']

  # Generate token random_str: host:port
  random_str = rand(36**20).to_s(36) # random string a-z0-9 length 20
  token = "#{random_str}: #{host}:#{vnc_port}"
  token_file = 'one-' + vm_resource['ID']

  # Create token file

  begin
          f = File.open(File.join(@token_folder, token_file), 'w')
          f.write(token)
          f.close
  rescue Exception => e
    #            @logger.error e.message
    return error(500, 'Cannot create VNC proxy token')
        end

  info = {
    :proxy_port => '29876',
    :password => vnc_pw,
    :token => random_str,
    :vm_name => vm_resource['NAME']
  }

  [200, info]
end
start() click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 85
def start
  if is_running?
    message = 'VNC server already running'
    STDERR.puts message
    @logger.info message
    return false
  end

  create_token_dir

  proxy_options = "--target-config=#{@token_folder} "

  if @enable_wss
    proxy_options << " --cert #{@cert}"
    proxy_options << " --key #{@key}" if @key && !@key.empty?
    proxy_options << ' --ssl-only' if @wss == 'only'
  end

  proxy_options << ' -6' if @proxy_ipv6

  cmd = "python #{@proxy_path} #{proxy_options} #{@proxy_port}"

  begin
    @logger.info { "Starting VNC proxy: #{cmd}" }
    pid = start_daemon(cmd, VNC_LOG)
  rescue Exception => e
    @logger.error e.message
    return false
  end

  File.open(@lock_file, 'w') do |f|
    f.write(pid.to_s)
  end

  sleep 1

  unless 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

  STDOUT.puts 'VNC proxy started'

  true
end
status() click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 223
def status
  if is_running?
    STDOUT.puts 'VNC is running'
    true
  else
    STDOUT.puts 'VNC is NOT running'
    false
  end
end
stop(force = false) click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 189
def stop(force = false)
  pid = get_pid

  if pid
    @logger.info 'Killing VNC proxy'

    force ? signal = 'KILL' : signal = 'TERM'
    Process.kill(signal, pid)

    sleep 1

    begin
      Process.getpgid(pid)

      Process.kill('KILL', pid)
    rescue StandardError
    end

    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

Private Instance Methods

create_token_dir() click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 243
def create_token_dir
  delete_token_dir
  begin
    Dir.mkdir(@token_folder) unless File.exist?(@token_folder)
  rescue Exception => e
    @logger.error 'Cannot create token folder'
    @logger.error e.message
  end
end
delete_token_dir() click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 253
def delete_token_dir
  if File.exist?(@token_folder)
    begin
        Dir.glob("#{@token_folder}/*").each do |file|
          File.delete(file)
        end
    rescue StandardError => e
      @logger.error 'Error deleting token folder'
      @logger.error e.message
      end
  end
end
error(code, msg) click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 235
def error(code, msg)
  if @options[:json_errors]
    [code, OpenNebula::Error.new(msg).to_json]
  else
    [code, msg]
  end
end
get_pid()
Alias for: is_running?
is_running?() click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 266
def is_running?
  if File.exist?(@lock_file)
    pid = File.read(@lock_file).strip

    return pid.to_i if system("ps #{pid} 1> /dev/null")

    @logger.info 'Deleting stale lock file'
    File.delete(@lock_file)
  end

  false
end
Also aliased as: get_pid
spawn(*args) click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 281
def spawn(*args)
  fork do
    command = args[0..-2]

    # Close stdin and point out and err to log file
    $stdin.close
    $stdout.reopen(VNC_LOG, 'a')
    $stderr.reopen(VNC_LOG, 'a')

    # Detach process from the parent
    Process.setsid

    exec(*command)
  end
end
start_daemon(cmd, log) click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 298
def start_daemon(cmd, log)
  options = {
    :pgroup => true,
    :in => :close,
    [:out, :err] => [log, 'a'],
    :close_others => true
  }

  params = cmd.split(' ') + [options]
  pid = spawn(*params)

  Process.detach(pid)

  pid
end