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

        if !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'].downcase != "vnc"
            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']
        }

        return [200, info]
    end
start() click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 106
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.size > 0
        proxy_options << " --ssl-only" if @wss == "only"
    end

    if @proxy_ipv6
        proxy_options << " -6"
    end

    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

    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

    STDOUT.puts "VNC proxy started"

    true
end
status() click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 248
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 214
def stop(force=false)
    pid=get_pid

    if pid
        @logger.info "Killing VNC proxy"

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

        sleep 1

        begin
            Process.getpgid(pid)

            Process.kill('KILL', pid)
        rescue
        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 268
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
delete_token_dir() click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 278
def delete_token_dir
    if File.exist?(@token_folder)
        begin
            Dir.glob("#{@token_folder}/*").each do |file|
                File.delete(file)
            end
        rescue => 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 260
def error(code, msg)
    if @options[:json_errors]
        return [code,OpenNebula::Error.new(msg).to_json]
    else
        return [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 291
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
Also aliased as: get_pid
spawn(*args) click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 308
def spawn(*args)
    fork {
        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
start_daemon(cmd, log) click to toggle source
# File lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb, line 325
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