예제 #1
0
파일: vterm.py 프로젝트: tbreeds/pypowervm
def open_localhost_vnc_vterm(adapter, lpar_uuid, force=False):
    """Opens a VNC vTerm to a given LPAR.  Always binds to localhost.

    :param adapter: The adapter to drive the PowerVM API
    :param lpar_uuid: Partition UUID.
    :param force: (Optional, Default: False) If set to true will force the
                  console to be opened as VNC even if it is already opened
                  via some other means.
    :return: The VNC Port that the terminal is running on.
    """
    # This API can only run if local.
    if not adapter.traits.local_api:
        raise pvm_exc.ConsoleNotLocal()

    lpar_id = _get_lpar_id(adapter, lpar_uuid)

    def _run_mkvterm_cmd(lpar_uuid, force):
        cmd = ['mkvterm', '--id', str(lpar_id), '--vnc', '--local']
        ret_code, std_out, std_err = _run_proc(cmd)

        # If the vterm was already started, the mkvterm command will always
        # return an error message with a return code of 3.  However, there
        # are 2 scenarios here, one where it was started with the VNC option
        # previously, which we will get a valid port number back (which is
        # the good path scenario), and one where it was started out-of-band
        # where we will get no port.  If it is the out-of-band scenario and
        # they asked us to force the connection, then we will attempt to
        # terminate the old vterm session so we can start up one with VNC.
        if force and ret_code == 3 and not _parse_vnc_port(std_out):
            LOG.warning(
                _("Invalid output on vterm open.  Trying to reset the "
                  "vterm.  Error was %s"), std_err)
            close_vterm(adapter, lpar_uuid)
            ret_code, std_out, std_err = _run_proc(cmd)

        # The only error message that is fine is a return code of 3 that a
        # session is already started, where we got back the port back meaning
        # that it was started as VNC.  Else, raise up the error message.
        if ret_code != 0 and not (ret_code == 3 and _parse_vnc_port(std_out)):
            raise pvm_exc.VNCBasedTerminalFailedToOpen(err=std_err)

        # Parse the VNC Port out of the stdout returned from mkvterm
        return _parse_vnc_port(std_out)

    return _run_mkvterm_cmd(lpar_uuid, force)
예제 #2
0
def open_localhost_vnc_vterm(adapter, lpar_uuid):
    """Opens a VNC vTerm to a given LPAR.  Always binds to localhost.

    :param adapter: The adapter to drive the PowerVM API
    :param lpar_uuid: Partition UUID.
    :return: The VNC Port that the terminal is running on.
    """
    # This API can only run if local.
    if not adapter.traits.local_api:
        raise pvm_exc.ConsoleNotLocal()

    lpar_id = _get_lpar_id(adapter, lpar_uuid)

    cmd = ['mkvterm', '--id', str(lpar_id), '--vnc', '--local']
    std_out = subprocess.check_output(cmd)

    # The first line of the std_out should be the VNC port
    return int(std_out.splitlines()[0])
예제 #3
0
파일: vterm.py 프로젝트: tpeponas/pypowervm
def open_remotable_vnc_vterm(
        adapter, lpar_uuid, local_ip, remote_ips=None, vnc_path=None,
        use_x509_auth=False, ca_certs=None, server_cert=None, server_key=None,
        force=False):
    """Opens a VNC vTerm to a given LPAR.  Wraps in some validation.

    Must run on the management partition.

    :param adapter: The adapter to drive the PowerVM API
    :param lpar_uuid: Partition UUID.
    :param local_ip: The IP Address to bind the VNC server to.  This would be
                     the IP of the management network on the system.
    :param remote_ips: (Optional, Default: None) A binding to only accept
                       clients that are from a specific list of IP addresses
                       through. Default is None, and therefore will allow any
                       remote IP to connect.
    :param vnc_path: (Optional, Default: None) If provided, the vnc client must
                     pass in this path (in HTTP format) to connect to the
                     VNC server.

                     The path is in HTTP format.  So if the vnc_path is 'Test'
                     the first packet request into the VNC must be:
                     "CONNECT Test HTTP/1.1\r\n\r\n"

                     If the client passes in an invalid request, a 400 Bad
                     Request will be returned.  If the client sends in the
                     correct path a 200 OK will be returned.

                     If no vnc_path is specified, then no path is expected
                     to be passed in by the VNC client and it will listen
                     on the same remote port as local port.  If the path is
                     specified then it will listen on the on a single remote
                     port of 5901 and determine the LPAR based on this path.
    :param use_x509_auth: (Optional, Default: False) If enabled, uses X509
                          Authentication for the VNC sessions started for VMs.
    :param ca_certs: (Optional, Default: None) Path to CA certificate to
                     use for verifying VNC X509 Authentication.  Only used
                     if use_x509_auth is set to True.
    :param server_cert: (Optional, Default: None) Path to Server certificate
                        to use for verifying VNC X509 Authentication.  Only
                        used if use_x509_auth is set to True.
    :param server_key: (Optional, Default: None) Path to Server private key
                       to use for verifying VNC X509 Authentication.  Only
                       used if use_x509_auth is set to True.
    :param force: (Optional, Default: False) If set to true will force the
                  console to be opened as VNC even if it is already opened
                  via some other means.
    :return: The VNC Port that the terminal is running on.
    """
    # This API can only run if local.
    if not adapter.traits.local_api:
        raise pvm_exc.ConsoleNotLocal()

    # Open the VNC Port.  If already open, it will just return the same port,
    # so no harm re-opening.  The stdout will just print out the existing port.
    local_port = open_localhost_vnc_vterm(adapter, lpar_uuid, force=force)
    # If a VNC path is provided then we have a way to map an incoming
    # connection to a given LPAR and will use the single 5901 port, otherwise
    # we need to listen for remote connections on the same port as the local
    # one so we know which VNC session to forward the connection's data to
    remote_port = _REMOTE_PORT if vnc_path is not None else local_port
    _VNC_UUID_TO_LOCAL_PORT[lpar_uuid] = local_port

    # We will use a flag to the Socket Listener to tell it whether the
    # user provided us a VNC Path we should use to look up the UUID from
    if vnc_path is not None:
        verify_vnc_path = True
        _VNC_PATH_TO_UUID[vnc_path] = lpar_uuid
    else:
        verify_vnc_path = False

    # See if we have a VNC repeater already...if so, nothing to do.  If not,
    # start it up.
    with lock.lock('powervm_vnc_term'):
        if remote_port not in _VNC_REMOTE_PORT_TO_LISTENER:
            listener = _VNCSocketListener(
                adapter, remote_port, local_ip, verify_vnc_path,
                remote_ips=remote_ips)
            # If we are doing x509 Authentication, then setup the certificates
            if use_x509_auth:
                listener.set_x509_certificates(
                    ca_certs, server_cert, server_key)
            _VNC_REMOTE_PORT_TO_LISTENER[remote_port] = listener

            listener.start()

    return remote_port