Commit 99d0a3cc authored by Sébastien Luttringer's avatar Sébastien Luttringer
Browse files

Add vnc command

parent 12496070
Loading
Loading
Loading
Loading

cccli/commands/vnc.py

0 → 100644
+84 −0
Original line number Diff line number Diff line
#!/usr/bin/env python
#coding=utf8

'''
CloudControl vnc command
'''

from cccli.command import TqlCommand
from cccli.exception import *
from cccli.tunnel import Forward
import os
import subprocess
import threading

class VNCViewer(threading.Thread):
    '''
    This object handle the launching of a vnc viewer.
    It handle reading exit code and close the dedicated forward
    '''

    def __init__(self, viewver, cli, host_id, dest_ip, dest_port):
        threading.Thread.__init__(self)
        self.viewer = viewver
        self.cli = cli
        self.rpc = cli.rpc
        self.host_id = host_id
        self.dest_ip = dest_ip
        self.dest_port = dest_port

    def run(self):
        '''Thread entry point'''
        # create forward
        fwd = Forward(self.rpc, self.host_id,
                      "127.0.0.1", 0,
                      self.dest_ip, self.dest_port)
        self.cli.forwards[fwd.id] = fwd
        fwd.start()
        # run vncviewer
        onull = open(os.devnull, "w+")
        proc = subprocess.Popen("%s '%s::%s'" % (self.viewer,
                                                 fwd.source_ip,
                                                 fwd.source_port),
                                shell=True, close_fds=True,
                                stdin=onull, stdout=onull, stderr=onull)
        proc.wait()
        del self.cli.forwards[fwd.id]

class Command_vnc(TqlCommand):
    '''Start a vnc on a vm'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.remove_option("--direct")
        self.remove_option("--quiet")
        self.add_option("--viewer", default="vncviewer",
                        help="define a custom vncviewer binary")
        self.tql_filter = "&r=vm&status=running"

    def __call__(self, argv):
        # args parse
        self.parse_args(argv)
        if len(self.args) != 1:
            raise cmdBadArgument()
        # list vm and get parent and vncport tag
        tql = self.args[0]
        tql += "&vncport"
        tql += "&p"
        ans = self.rpccall("list", tql, _status=False, _direct=True)
        if len(ans["objects"]) == 0:
            raise cmdError("No selected object")
        for vm in ans["objects"]:
            host_id = vm["p"]
            dest_port = int(vm["vncport"])
            # check if we have the right to forward on this hypervisor
            ans2 = self.rpc.call("list", "id:%s" % host_id, method="forward")
            if len(ans2["objects"]) == 0:
                self.printer.warn("You cannot forward on host %s" % host_id)
                continue
            # launch a vncviewer
            VNCViewer(self.options.viewer, self.cli,
                      host_id, "127.0.0.1", dest_port).start()

    def remote_functions(self):
        return set(("forward",))