Merge "Remove 'nova-xvpvncproxy'"
This commit is contained in:
commit
1fed6bd934
|
@ -783,12 +783,11 @@ Server Consoles
|
||||||
Server Consoles can also be supplied after server launched. There are several
|
Server Consoles can also be supplied after server launched. There are several
|
||||||
server console services available. First, users can get the console output
|
server console services available. First, users can get the console output
|
||||||
from the specified server and can limit the lines of console text by setting
|
from the specified server and can limit the lines of console text by setting
|
||||||
the length. Second, users can access multiple types of remote consoles. The
|
the length. Secondly, users can access multiple types of remote consoles. The
|
||||||
user can use novnc, xvpvnc, rdp-html5, spice-html5, serial, and webmks(start
|
user can use ``novnc``, ``rdp-html5``, ``spice-html5``, ``serial``, and
|
||||||
from microversion 2.8) through either the OpenStack dashboard or the command
|
``webmks`` (starting from microversion 2.8) through either the OpenStack
|
||||||
line. Refer to :nova-doc:`Configure remote console access
|
dashboard or the command line. Refer to :nova-doc:`Configure remote console
|
||||||
<admin/remote-console-access.html>`. Specifically for Xenserver, it provides
|
access <admin/remote-console-access.html>`.
|
||||||
the ability to create, delete, detail, list specified server vnc consoles.
|
|
||||||
|
|
||||||
Server networks
|
Server networks
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -5284,7 +5284,7 @@ os-getVNCConsole:
|
||||||
type: object
|
type: object
|
||||||
os-getVNCConsole-type:
|
os-getVNCConsole-type:
|
||||||
description: |
|
description: |
|
||||||
The type of VNC console. The valid values are ``novnc`` and ``xvpvnc``.
|
The type of VNC console. The only valid value is ``novnc``.
|
||||||
in: body
|
in: body
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
@ -5833,7 +5833,7 @@ remote_console_protocol:
|
||||||
type: string
|
type: string
|
||||||
remote_console_type:
|
remote_console_type:
|
||||||
description: |
|
description: |
|
||||||
The type of remote console. The valid values are ``novnc``, ``xvpvnc``,
|
The type of remote console. The valid values are ``novnc``,
|
||||||
``rdp-html5``, ``spice-html5``, ``serial``, and ``webmks``. The type
|
``rdp-html5``, ``spice-html5``, ``serial``, and ``webmks``. The type
|
||||||
``webmks`` is added since Microversion ``2.8``.
|
``webmks`` is added since Microversion ``2.8``.
|
||||||
in: body
|
in: body
|
||||||
|
|
|
@ -175,9 +175,6 @@ Gets a VNC console for a server.
|
||||||
|
|
||||||
Specify the ``os-getVNCConsole`` action in the request body.
|
Specify the ``os-getVNCConsole`` action in the request body.
|
||||||
|
|
||||||
The supported connection types are ``novnc``, ``xvpvnc``. Such as connect
|
|
||||||
with ``novnc``, set ``type`` parameter to ``novnc``.
|
|
||||||
|
|
||||||
Normal response codes: 200
|
Normal response codes: 200
|
||||||
|
|
||||||
Error response codes: badRequest(400), unauthorized(401), forbidden(403), itemNotFound(404),
|
Error response codes: badRequest(400), unauthorized(401), forbidden(403), itemNotFound(404),
|
||||||
|
|
|
@ -17,9 +17,7 @@ The API provides a unified request for creating a remote console. The user can
|
||||||
get a URL to connect the console from this API. The URL includes the token
|
get a URL to connect the console from this API. The URL includes the token
|
||||||
which is used to get permission to access the console. Servers may support
|
which is used to get permission to access the console. Servers may support
|
||||||
different console protocols. To return a remote console using a specific
|
different console protocols. To return a remote console using a specific
|
||||||
protocol, such as RDP, set the ``protocol`` parameter to ``rdp``. For the same
|
protocol, such as RDP, set the ``protocol`` parameter to ``rdp``.
|
||||||
protocol, there may be different connection types such as ``vnc protocol and
|
|
||||||
novnc type`` or ``vnc protocol and xvpvnc type``.
|
|
||||||
|
|
||||||
Normal response codes: 200
|
Normal response codes: 200
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@ redirectmatch 301 ^/nova/([^/]+)/man/nova-scheduler.html$ /nova/$1/cli/nova-sche
|
||||||
redirectmatch 301 ^/nova/([^/]+)/man/nova-serialproxy.html$ /nova/$1/cli/nova-serialproxy.html
|
redirectmatch 301 ^/nova/([^/]+)/man/nova-serialproxy.html$ /nova/$1/cli/nova-serialproxy.html
|
||||||
redirectmatch 301 ^/nova/([^/]+)/man/nova-spicehtml5proxy.html$ /nova/$1/cli/nova-spicehtml5proxy.html
|
redirectmatch 301 ^/nova/([^/]+)/man/nova-spicehtml5proxy.html$ /nova/$1/cli/nova-spicehtml5proxy.html
|
||||||
redirectmatch 301 ^/nova/([^/]+)/man/nova-status.html$ /nova/$1/cli/nova-status.html
|
redirectmatch 301 ^/nova/([^/]+)/man/nova-status.html$ /nova/$1/cli/nova-status.html
|
||||||
redirectmatch 301 ^/nova/([^/]+)/man/nova-xvpvncproxy.html$ /nova/$1/cli/nova-xvpvncproxy.html
|
|
||||||
redirectmatch 301 ^/nova/([^/]+)/notifications.html$ /nova/$1/reference/notifications.html
|
redirectmatch 301 ^/nova/([^/]+)/notifications.html$ /nova/$1/reference/notifications.html
|
||||||
redirectmatch 301 ^/nova/([^/]+)/placement.html$ /nova/$1/user/placement.html
|
redirectmatch 301 ^/nova/([^/]+)/placement.html$ /nova/$1/user/placement.html
|
||||||
redirectmatch 301 ^/nova/([^/]+)/placement_dev.html$ /nova/$1/contributor/placement.html
|
redirectmatch 301 ^/nova/([^/]+)/placement_dev.html$ /nova/$1/contributor/placement.html
|
||||||
|
|
|
@ -526,68 +526,6 @@ For example, to configure this via a ``nova.conf`` file:
|
||||||
mksproxy_base_url = https://127.0.0.1:6090/
|
mksproxy_base_url = https://127.0.0.1:6090/
|
||||||
|
|
||||||
|
|
||||||
XVP-based VNC console
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
VNC is a graphical console with wide support among many hypervisors and
|
|
||||||
clients. Xen VNC Proxy (XVP) provides VNC support via a simple Java client.
|
|
||||||
|
|
||||||
.. deprecated:: 19.0.0
|
|
||||||
|
|
||||||
:program:`nova-xvpvnxproxy` is deprecated since 19.0.0 (Stein) and will be
|
|
||||||
removed in an upcoming release.
|
|
||||||
|
|
||||||
Configuration
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
To enable the XVP VNC console service, you must configure both the
|
|
||||||
:program:`nova-xvpvncproxy` service and the :program:`nova-compute` service.
|
|
||||||
Most options are defined in the :oslo.config:group:`vnc` group.
|
|
||||||
|
|
||||||
The :program:`nova-xvpvncproxy` service accepts the following options.
|
|
||||||
|
|
||||||
- :oslo.config:option:`daemon`
|
|
||||||
- :oslo.config:option:`ssl_only`
|
|
||||||
- :oslo.config:option:`source_is_ipv6`
|
|
||||||
- :oslo.config:option:`cert`
|
|
||||||
- :oslo.config:option:`key`
|
|
||||||
- :oslo.config:option:`web`
|
|
||||||
- :oslo.config:option:`vnc.xvpvncproxy_host`
|
|
||||||
- :oslo.config:option:`vnc.xvpvncproxy_port`
|
|
||||||
|
|
||||||
For example, to configure this via a ``nova-xvpvncproxy.conf`` file:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[vnc]
|
|
||||||
xvpvncproxy_host = 0.0.0.0
|
|
||||||
xvpvncproxy_port = 6081
|
|
||||||
|
|
||||||
The :program:`nova-compute` service requires the following options to configure
|
|
||||||
XVP-based VNC support.
|
|
||||||
|
|
||||||
- :oslo.config:option:`vnc.enabled`
|
|
||||||
- :oslo.config:option:`vnc.xvpvncproxy_base_url`
|
|
||||||
- :oslo.config:option:`vnc.server_listen`
|
|
||||||
- :oslo.config:option:`vnc.server_proxyclient_address`
|
|
||||||
- :oslo.config:option:`vnc.keymap`
|
|
||||||
|
|
||||||
For example, to configure this via a ``nova.conf`` file:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[vnc]
|
|
||||||
enabled = True
|
|
||||||
xvpvncproxy_base_url = http://IP_ADDRESS:6081/console
|
|
||||||
server_listen = 127.0.0.1
|
|
||||||
server_proxyclient_address = 127.0.0.1
|
|
||||||
keymap = en-us
|
|
||||||
|
|
||||||
Replace ``IP_ADDRESS`` with the IP address from which the proxy is accessible
|
|
||||||
by the outside world. For example, this may be the management interface IP
|
|
||||||
address of the controller or the VIP.
|
|
||||||
|
|
||||||
|
|
||||||
.. _about-nova-consoleauth:
|
.. _about-nova-consoleauth:
|
||||||
|
|
||||||
About ``nova-consoleauth``
|
About ``nova-consoleauth``
|
||||||
|
@ -602,13 +540,6 @@ outlined below could leverage. Token authentication was moved to the database in
|
||||||
Frequently Asked Questions
|
Frequently Asked Questions
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
- **Q: What is the difference between ``nova-xvpvncproxy`` and
|
|
||||||
``nova-novncproxy``?**
|
|
||||||
|
|
||||||
A: ``nova-xvpvncproxy``, which ships with OpenStack Compute, is a proxy that
|
|
||||||
supports a simple Java client. ``nova-novncproxy`` uses noVNC to provide VNC
|
|
||||||
support through a web browser.
|
|
||||||
|
|
||||||
- **Q: I want VNC support in the OpenStack dashboard. What services do I
|
- **Q: I want VNC support in the OpenStack dashboard. What services do I
|
||||||
need?**
|
need?**
|
||||||
|
|
||||||
|
@ -634,7 +565,6 @@ Frequently Asked Questions
|
||||||
# These flags help construct a connection data structure
|
# These flags help construct a connection data structure
|
||||||
server_proxyclient_address=192.168.1.2
|
server_proxyclient_address=192.168.1.2
|
||||||
novncproxy_base_url=http://172.24.1.1:6080/vnc_auto.html
|
novncproxy_base_url=http://172.24.1.1:6080/vnc_auto.html
|
||||||
xvpvncproxy_base_url=http://172.24.1.1:6081/console
|
|
||||||
|
|
||||||
# This is the address where the underlying vncserver (not the proxy)
|
# This is the address where the underlying vncserver (not the proxy)
|
||||||
# will listen for connections.
|
# will listen for connections.
|
||||||
|
@ -642,11 +572,11 @@ Frequently Asked Questions
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
``novncproxy_base_url`` and ``xvpvncproxy_base_url`` use a public IP; this
|
``novncproxy_base_url`` uses a public IP; this is the URL that is
|
||||||
is the URL that is ultimately returned to clients, which generally do not
|
ultimately returned to clients, which generally do not have access to your
|
||||||
have access to your private network. Your PROXYSERVER must be able to
|
private network. Your PROXYSERVER must be able to reach
|
||||||
reach ``server_proxyclient_address``, because that is the address over
|
``server_proxyclient_address``, because that is the address over which the
|
||||||
which the VNC connection is proxied.
|
VNC connection is proxied.
|
||||||
|
|
||||||
- **Q: My noVNC does not work with recent versions of web browsers. Why?**
|
- **Q: My noVNC does not work with recent versions of web browsers. Why?**
|
||||||
|
|
||||||
|
|
|
@ -75,14 +75,3 @@ are documented for completeness and debugging if something goes wrong.
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
nova-rootwrap
|
nova-rootwrap
|
||||||
|
|
||||||
Deprecated Services
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
The following services are deprecated in nova. They should not be used in new
|
|
||||||
deployments, but are documented for existing ones.
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
nova-xvpvncproxy
|
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
================
|
|
||||||
nova-xvpvncproxy
|
|
||||||
================
|
|
||||||
|
|
||||||
----------------------------
|
|
||||||
XVP VNC Console Proxy Server
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
:Author: openstack@lists.openstack.org
|
|
||||||
:Copyright: OpenStack Foundation
|
|
||||||
:Manual section: 1
|
|
||||||
:Manual group: cloud computing
|
|
||||||
|
|
||||||
Synopsis
|
|
||||||
========
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
nova-xvpvncproxy [options]
|
|
||||||
|
|
||||||
Description
|
|
||||||
===========
|
|
||||||
|
|
||||||
:program:`nova-xvpvncproxy` is a server daemon that serves the Nova XVP VNC
|
|
||||||
Console Proxy service, which provides an XVP-based VNC Console Proxy for use
|
|
||||||
with the Xen hypervisor.
|
|
||||||
|
|
||||||
.. deprecated:: 19.0.0
|
|
||||||
|
|
||||||
:program:`nova-xvpvnxproxy` is deprecated since 19.0.0 (Stein) and will be
|
|
||||||
removed in an upcoming release.
|
|
||||||
|
|
||||||
Options
|
|
||||||
=======
|
|
||||||
|
|
||||||
**General options**
|
|
||||||
|
|
||||||
Files
|
|
||||||
=====
|
|
||||||
|
|
||||||
* ``/etc/nova/nova.conf``
|
|
||||||
* ``/etc/nova/policy.json``
|
|
||||||
* ``/etc/nova/rootwrap.conf``
|
|
||||||
* ``/etc/nova/rootwrap.d/``
|
|
||||||
|
|
||||||
See Also
|
|
||||||
========
|
|
||||||
|
|
||||||
* :nova-doc:`OpenStack Nova <>`
|
|
||||||
|
|
||||||
Bugs
|
|
||||||
====
|
|
||||||
|
|
||||||
* Nova bugs are managed at `Launchpad <https://bugs.launchpad.net/nova>`__
|
|
|
@ -93,7 +93,6 @@ _man_pages = [
|
||||||
('nova-serialproxy', u'Cloud controller fabric'),
|
('nova-serialproxy', u'Cloud controller fabric'),
|
||||||
('nova-spicehtml5proxy', u'Cloud controller fabric'),
|
('nova-spicehtml5proxy', u'Cloud controller fabric'),
|
||||||
('nova-status', u'Cloud controller fabric'),
|
('nova-status', u'Cloud controller fabric'),
|
||||||
('nova-xvpvncproxy', u'Cloud controller fabric'),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
man_pages = [
|
man_pages = [
|
||||||
|
|
|
@ -61,15 +61,6 @@ OpenStack Compute consists of the following areas and their components:
|
||||||
Provides a proxy for accessing running instances through a SPICE connection.
|
Provides a proxy for accessing running instances through a SPICE connection.
|
||||||
Supports browser-based HTML5 client.
|
Supports browser-based HTML5 client.
|
||||||
|
|
||||||
``nova-xvpvncproxy`` daemon
|
|
||||||
Provides a proxy for accessing running instances through a VNC connection.
|
|
||||||
Supports an OpenStack-specific Java client.
|
|
||||||
|
|
||||||
.. deprecated:: 19.0.0
|
|
||||||
|
|
||||||
:program:`nova-xvpvnxproxy` is deprecated since 19.0.0 (Stein) and will be
|
|
||||||
removed in an upcoming release.
|
|
||||||
|
|
||||||
The queue
|
The queue
|
||||||
A central hub for passing messages between daemons. Usually implemented with
|
A central hub for passing messages between daemons. Usually implemented with
|
||||||
`RabbitMQ <https://www.rabbitmq.com/>`__ but
|
`RabbitMQ <https://www.rabbitmq.com/>`__ but
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
/nova/latest/man/nova-serialproxy.html 301 /nova/latest/cli/nova-serialproxy.html
|
/nova/latest/man/nova-serialproxy.html 301 /nova/latest/cli/nova-serialproxy.html
|
||||||
/nova/latest/man/nova-spicehtml5proxy.html 301 /nova/latest/cli/nova-spicehtml5proxy.html
|
/nova/latest/man/nova-spicehtml5proxy.html 301 /nova/latest/cli/nova-spicehtml5proxy.html
|
||||||
/nova/latest/man/nova-status.html 301 /nova/latest/cli/nova-status.html
|
/nova/latest/man/nova-status.html 301 /nova/latest/cli/nova-status.html
|
||||||
/nova/latest/man/nova-xvpvncproxy.html 301 /nova/latest/cli/nova-xvpvncproxy.html
|
|
||||||
/nova/latest/notifications.html 301 /nova/latest/reference/notifications.html
|
/nova/latest/notifications.html 301 /nova/latest/reference/notifications.html
|
||||||
/nova/latest/placement.html 301 /nova/latest/user/placement.html
|
/nova/latest/placement.html 301 /nova/latest/user/placement.html
|
||||||
/nova/latest/placement_dev.html 301 /nova/latest/contributor/placement.html
|
/nova/latest/placement_dev.html 301 /nova/latest/contributor/placement.html
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
# Copyright (c) 2010 OpenStack Foundation
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
"""XVP VNC Console Proxy Server."""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from oslo_log import log as logging
|
|
||||||
from oslo_reports import guru_meditation_report as gmr
|
|
||||||
from oslo_reports import opts as gmr_opts
|
|
||||||
|
|
||||||
import nova.conf
|
|
||||||
from nova import config
|
|
||||||
from nova import service
|
|
||||||
from nova import version
|
|
||||||
from nova.vnc import xvp_proxy
|
|
||||||
|
|
||||||
CONF = nova.conf.CONF
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
config.parse_args(sys.argv)
|
|
||||||
logging.setup(config.CONF, "nova")
|
|
||||||
gmr_opts.set_defaults(CONF)
|
|
||||||
|
|
||||||
gmr.TextGuruMeditation.setup_autorun(version, conf=CONF)
|
|
||||||
|
|
||||||
wsgi_server = xvp_proxy.get_wsgi_server()
|
|
||||||
service.serve(wsgi_server)
|
|
||||||
service.wait()
|
|
|
@ -6636,8 +6636,6 @@ class ComputeManager(manager.Manager):
|
||||||
# For essex, novncproxy_base_url must include the full path
|
# For essex, novncproxy_base_url must include the full path
|
||||||
# including the html file (like http://myhost/vnc_auto.html)
|
# including the html file (like http://myhost/vnc_auto.html)
|
||||||
access_url_base = CONF.vnc.novncproxy_base_url
|
access_url_base = CONF.vnc.novncproxy_base_url
|
||||||
elif console_type == 'xvpvnc':
|
|
||||||
access_url_base = CONF.vnc.xvpvncproxy_base_url
|
|
||||||
else:
|
else:
|
||||||
raise exception.ConsoleTypeInvalid(console_type=console_type)
|
raise exception.ConsoleTypeInvalid(console_type=console_type)
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,6 @@ from nova.conf import vnc
|
||||||
from nova.conf import workarounds
|
from nova.conf import workarounds
|
||||||
from nova.conf import wsgi
|
from nova.conf import wsgi
|
||||||
from nova.conf import xenserver
|
from nova.conf import xenserver
|
||||||
from nova.conf import xvp
|
|
||||||
from nova.conf import zvm
|
from nova.conf import zvm
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
@ -119,7 +118,6 @@ vnc.register_opts(CONF)
|
||||||
workarounds.register_opts(CONF)
|
workarounds.register_opts(CONF)
|
||||||
wsgi.register_opts(CONF)
|
wsgi.register_opts(CONF)
|
||||||
xenserver.register_opts(CONF)
|
xenserver.register_opts(CONF)
|
||||||
xvp.register_opts(CONF)
|
|
||||||
zvm.register_opts(CONF)
|
zvm.register_opts(CONF)
|
||||||
|
|
||||||
remote_debug.register_cli_opts(CONF)
|
remote_debug.register_cli_opts(CONF)
|
||||||
|
|
|
@ -115,90 +115,6 @@ Related options:
|
||||||
* novncproxy_port
|
* novncproxy_port
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
cfg.HostAddressOpt(
|
|
||||||
'xvpvncproxy_host',
|
|
||||||
default='0.0.0.0',
|
|
||||||
deprecated_group='DEFAULT',
|
|
||||||
deprecated_for_removal=True,
|
|
||||||
deprecated_since='19.0.0',
|
|
||||||
deprecated_reason="""
|
|
||||||
The ``nova-xvpvnxproxy`` service is deprecated and will be removed in an
|
|
||||||
upcoming release.
|
|
||||||
""",
|
|
||||||
help="""
|
|
||||||
IP address or hostname that the XVP VNC console proxy should bind to.
|
|
||||||
|
|
||||||
The VNC proxy is an OpenStack component that enables compute service
|
|
||||||
users to access their instances through VNC clients. Xen provides
|
|
||||||
the Xenserver VNC Proxy, or XVP, as an alternative to the
|
|
||||||
websocket-based noVNC proxy used by Libvirt. In contrast to noVNC,
|
|
||||||
XVP clients are Java-based.
|
|
||||||
|
|
||||||
This option sets the private address to which the XVP VNC console proxy
|
|
||||||
service should bind to.
|
|
||||||
|
|
||||||
Related options:
|
|
||||||
|
|
||||||
* xvpvncproxy_port
|
|
||||||
* xvpvncproxy_base_url
|
|
||||||
"""),
|
|
||||||
|
|
||||||
cfg.PortOpt(
|
|
||||||
'xvpvncproxy_port',
|
|
||||||
default=6081,
|
|
||||||
deprecated_group='DEFAULT',
|
|
||||||
deprecated_for_removal=True,
|
|
||||||
deprecated_since='19.0.0',
|
|
||||||
deprecated_reason="""
|
|
||||||
The ``nova-xvpvnxproxy`` service is deprecated and will be removed in an
|
|
||||||
upcoming release.
|
|
||||||
""",
|
|
||||||
help="""
|
|
||||||
Port that the XVP VNC console proxy should bind to.
|
|
||||||
|
|
||||||
The VNC proxy is an OpenStack component that enables compute service
|
|
||||||
users to access their instances through VNC clients. Xen provides
|
|
||||||
the Xenserver VNC Proxy, or XVP, as an alternative to the
|
|
||||||
websocket-based noVNC proxy used by Libvirt. In contrast to noVNC,
|
|
||||||
XVP clients are Java-based.
|
|
||||||
|
|
||||||
This option sets the private port to which the XVP VNC console proxy
|
|
||||||
service should bind to.
|
|
||||||
|
|
||||||
Related options:
|
|
||||||
|
|
||||||
* xvpvncproxy_host
|
|
||||||
* xvpvncproxy_base_url
|
|
||||||
"""),
|
|
||||||
|
|
||||||
cfg.URIOpt(
|
|
||||||
'xvpvncproxy_base_url',
|
|
||||||
default='http://127.0.0.1:6081/console',
|
|
||||||
deprecated_group='DEFAULT',
|
|
||||||
deprecated_for_removal=True,
|
|
||||||
deprecated_since='19.0.0',
|
|
||||||
deprecated_reason="""
|
|
||||||
The ``nova-xvpvnxproxy`` service is deprecated and will be removed in an
|
|
||||||
upcoming release.
|
|
||||||
""",
|
|
||||||
help="""
|
|
||||||
Public URL address of XVP VNC console proxy.
|
|
||||||
|
|
||||||
The VNC proxy is an OpenStack component that enables compute service
|
|
||||||
users to access their instances through VNC clients. Xen provides
|
|
||||||
the Xenserver VNC Proxy, or XVP, as an alternative to the
|
|
||||||
websocket-based noVNC proxy used by Libvirt. In contrast to noVNC,
|
|
||||||
XVP clients are Java-based.
|
|
||||||
|
|
||||||
This option sets the public base URL to which client systems will
|
|
||||||
connect. XVP clients can use this address to connect to the XVP
|
|
||||||
instance and, by extension, the VNC sessions.
|
|
||||||
|
|
||||||
Related options:
|
|
||||||
|
|
||||||
* xvpvncproxy_host
|
|
||||||
* xvpvncproxy_port
|
|
||||||
"""),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
CLI_OPTS = [
|
CLI_OPTS = [
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
# Copyright 2016 OpenStack Foundation
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from oslo_config import cfg
|
|
||||||
|
|
||||||
from nova.conf import paths
|
|
||||||
|
|
||||||
xvp_group = cfg.OptGroup(
|
|
||||||
'xvp',
|
|
||||||
title='XVP options',
|
|
||||||
help="""
|
|
||||||
Configuration options for XVP.
|
|
||||||
|
|
||||||
xvp (Xen VNC Proxy) is a proxy server providing password-protected VNC-based
|
|
||||||
access to the consoles of virtual machines hosted on Citrix XenServer.
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
xvp_opts = [
|
|
||||||
cfg.StrOpt('console_xvp_conf_template',
|
|
||||||
default=paths.basedir_def('nova/console/xvp.conf.template'),
|
|
||||||
deprecated_group='DEFAULT',
|
|
||||||
help='XVP conf template'),
|
|
||||||
cfg.StrOpt('console_xvp_conf',
|
|
||||||
default='/etc/xvp.conf',
|
|
||||||
deprecated_group='DEFAULT',
|
|
||||||
help='Generated XVP conf file'),
|
|
||||||
cfg.StrOpt('console_xvp_pid',
|
|
||||||
default='/var/run/xvp.pid',
|
|
||||||
deprecated_group='DEFAULT',
|
|
||||||
help='XVP master process pid file'),
|
|
||||||
cfg.StrOpt('console_xvp_log',
|
|
||||||
default='/var/log/xvp.log',
|
|
||||||
deprecated_group='DEFAULT',
|
|
||||||
help='XVP log file'),
|
|
||||||
cfg.PortOpt('console_xvp_multiplex_port',
|
|
||||||
default=5900,
|
|
||||||
deprecated_group='DEFAULT',
|
|
||||||
help='Port for XVP to multiplex VNC connections on'),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def register_opts(conf):
|
|
||||||
conf.register_group(xvp_group)
|
|
||||||
conf.register_opts(xvp_opts, group=xvp_group)
|
|
||||||
|
|
||||||
|
|
||||||
def list_opts():
|
|
||||||
return {
|
|
||||||
xvp_group: xvp_opts
|
|
||||||
}
|
|
|
@ -11,12 +11,11 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
:mod:`nova.console` -- Console Proxy to set up VM console access
|
:mod:`nova.console` -- Wrappers around console proxies
|
||||||
(i.e. with xvp)
|
======================================================
|
||||||
=====================================================
|
|
||||||
|
|
||||||
.. automodule:: nova.console
|
.. automodule:: nova.console
|
||||||
:platform: Unix
|
:platform: Unix
|
||||||
:synopsis: Wrapper around console proxies such as xvp to set up
|
:synopsis: Wrapper around console proxies such as noVNC to set up
|
||||||
multitenant VM console access
|
multi-tenant VM console access.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
# One time password use with time window
|
|
||||||
OTP ALLOW IPCHECK HTTP 60
|
|
||||||
{% if multiplex_port %}
|
|
||||||
MULTIPLEX {{ multiplex_port }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% for pool in pools %}
|
|
||||||
POOL {{ pool.address }}
|
|
||||||
DOMAIN {{ pool.address }}
|
|
||||||
MANAGER root {{ pool.password }}
|
|
||||||
HOST {{ pool.address }}
|
|
||||||
VM - dummy 0123456789ABCDEF
|
|
||||||
{% for console in pool.console %}
|
|
||||||
VM {% if multiplex_port %}-{% else %}{{ console.port }} # {{ console.instance_name }} {{ console.password|pass_encode }}{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% endfor %}
|
|
|
@ -1,183 +0,0 @@
|
||||||
# Copyright (c) 2010 OpenStack Foundation
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
"""XVP (Xenserver VNC Proxy) driver."""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import signal
|
|
||||||
|
|
||||||
import jinja2
|
|
||||||
from oslo_concurrency import processutils
|
|
||||||
from oslo_log import log as logging
|
|
||||||
from oslo_utils import excutils
|
|
||||||
|
|
||||||
import nova.conf
|
|
||||||
from nova import context
|
|
||||||
from nova.db import api as db
|
|
||||||
from nova.i18n import _
|
|
||||||
|
|
||||||
|
|
||||||
CONF = nova.conf.CONF
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class XVPConsoleProxy(object):
|
|
||||||
"""Sets up XVP config, and manages XVP daemon."""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.xvpconf_template = open(CONF.xvp.console_xvp_conf_template).read()
|
|
||||||
self.host = CONF.host # default, set by manager.
|
|
||||||
super(XVPConsoleProxy, self).__init__()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def console_type(self):
|
|
||||||
return 'vnc+xvp'
|
|
||||||
|
|
||||||
def get_port(self, context):
|
|
||||||
"""Get available port for consoles that need one."""
|
|
||||||
# TODO(mdragon): implement port selection for non multiplex ports,
|
|
||||||
# we are not using that, but someone else may want
|
|
||||||
# it.
|
|
||||||
return CONF.xvp.console_xvp_multiplex_port
|
|
||||||
|
|
||||||
def setup_console(self, context, console):
|
|
||||||
"""Sets up actual proxies."""
|
|
||||||
self._rebuild_xvp_conf(context.elevated())
|
|
||||||
|
|
||||||
def teardown_console(self, context, console):
|
|
||||||
"""Tears down actual proxies."""
|
|
||||||
self._rebuild_xvp_conf(context.elevated())
|
|
||||||
|
|
||||||
def init_host(self):
|
|
||||||
"""Start up any config'ed consoles on start."""
|
|
||||||
ctxt = context.get_admin_context()
|
|
||||||
self._rebuild_xvp_conf(ctxt)
|
|
||||||
|
|
||||||
def fix_pool_password(self, password):
|
|
||||||
"""Trim password to length, and encode."""
|
|
||||||
return self._xvp_encrypt(password, is_pool_password=True)
|
|
||||||
|
|
||||||
def fix_console_password(self, password):
|
|
||||||
"""Trim password to length, and encode."""
|
|
||||||
return self._xvp_encrypt(password)
|
|
||||||
|
|
||||||
def _rebuild_xvp_conf(self, context):
|
|
||||||
LOG.debug('Rebuilding xvp conf')
|
|
||||||
pools = [pool for pool in
|
|
||||||
db.console_pool_get_all_by_host_type(context, self.host,
|
|
||||||
self.console_type)
|
|
||||||
if pool['consoles']]
|
|
||||||
if not pools:
|
|
||||||
LOG.debug('No console pools!')
|
|
||||||
self._xvp_stop()
|
|
||||||
return
|
|
||||||
conf_data = {'multiplex_port': CONF.xvp.console_xvp_multiplex_port,
|
|
||||||
'pools': pools}
|
|
||||||
tmpl_path, tmpl_file = os.path.split(CONF.injected_network_template)
|
|
||||||
env = jinja2.Environment( # nosec
|
|
||||||
loader=jinja2.FileSystemLoader(tmpl_path)) # nosec
|
|
||||||
env.filters['pass_encode'] = self.fix_console_password
|
|
||||||
template = env.get_template(tmpl_file)
|
|
||||||
self._write_conf(template.render(conf_data))
|
|
||||||
self._xvp_restart()
|
|
||||||
|
|
||||||
def _write_conf(self, config):
|
|
||||||
try:
|
|
||||||
LOG.debug('Re-wrote %s', CONF.xvp.console_xvp_conf)
|
|
||||||
with open(CONF.xvp.console_xvp_conf, 'w') as cfile:
|
|
||||||
cfile.write(config)
|
|
||||||
except IOError:
|
|
||||||
with excutils.save_and_reraise_exception():
|
|
||||||
LOG.exception("Failed to write configuration file")
|
|
||||||
|
|
||||||
def _xvp_stop(self):
|
|
||||||
LOG.debug('Stopping xvp')
|
|
||||||
pid = self._xvp_pid()
|
|
||||||
if not pid:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
os.kill(pid, signal.SIGTERM)
|
|
||||||
except OSError:
|
|
||||||
# if it's already not running, no problem.
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _xvp_start(self):
|
|
||||||
if self._xvp_check_running():
|
|
||||||
return
|
|
||||||
LOG.debug('Starting xvp')
|
|
||||||
try:
|
|
||||||
processutils.execute('xvp',
|
|
||||||
'-p', CONF.xvp.console_xvp_pid,
|
|
||||||
'-c', CONF.xvp.console_xvp_conf,
|
|
||||||
'-l', CONF.xvp.console_xvp_log)
|
|
||||||
except processutils.ProcessExecutionError as err:
|
|
||||||
LOG.error('Error starting xvp: %s', err)
|
|
||||||
|
|
||||||
def _xvp_restart(self):
|
|
||||||
LOG.debug('Restarting xvp')
|
|
||||||
if not self._xvp_check_running():
|
|
||||||
LOG.debug('xvp not running...')
|
|
||||||
self._xvp_start()
|
|
||||||
else:
|
|
||||||
pid = self._xvp_pid()
|
|
||||||
os.kill(pid, signal.SIGUSR1)
|
|
||||||
|
|
||||||
def _xvp_pid(self):
|
|
||||||
try:
|
|
||||||
with open(CONF.xvp.console_xvp_pid, 'r') as pidfile:
|
|
||||||
pid = int(pidfile.read())
|
|
||||||
except IOError:
|
|
||||||
return None
|
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
return pid
|
|
||||||
|
|
||||||
def _xvp_check_running(self):
|
|
||||||
pid = self._xvp_pid()
|
|
||||||
if not pid:
|
|
||||||
return False
|
|
||||||
try:
|
|
||||||
os.kill(pid, 0)
|
|
||||||
except OSError:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _xvp_encrypt(self, password, is_pool_password=False):
|
|
||||||
"""Call xvp to obfuscate passwords for config file.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
- password: the password to encode, max 8 char for vm passwords,
|
|
||||||
and 16 chars for pool passwords. passwords will
|
|
||||||
be trimmed to max len before encoding.
|
|
||||||
- is_pool_password: True if this is the XenServer api password
|
|
||||||
False if it's a VM console password
|
|
||||||
(xvp uses different keys and max lengths for pool passwords)
|
|
||||||
|
|
||||||
Note that xvp's obfuscation should not be considered 'real' encryption.
|
|
||||||
It simply DES encrypts the passwords with static keys plainly viewable
|
|
||||||
in the xvp source code.
|
|
||||||
|
|
||||||
"""
|
|
||||||
maxlen = 8
|
|
||||||
flag = '-e'
|
|
||||||
if is_pool_password:
|
|
||||||
maxlen = 16
|
|
||||||
flag = '-x'
|
|
||||||
# xvp will blow up on passwords that are too long (mdragon)
|
|
||||||
password = password[:maxlen]
|
|
||||||
out, err = processutils.execute('xvp', flag, process_input=password)
|
|
||||||
if err:
|
|
||||||
raise processutils.ProcessExecutionError(_("Failed to run xvp."))
|
|
||||||
return out.strip()
|
|
|
@ -1398,16 +1398,6 @@ def project_get_networks(context, project_id, associate=True):
|
||||||
##################
|
##################
|
||||||
|
|
||||||
|
|
||||||
def console_pool_get_all_by_host_type(context, host, console_type):
|
|
||||||
"""Fetch all pools for given proxy host and type."""
|
|
||||||
return IMPL.console_pool_get_all_by_host_type(context,
|
|
||||||
host,
|
|
||||||
console_type)
|
|
||||||
|
|
||||||
|
|
||||||
##################
|
|
||||||
|
|
||||||
|
|
||||||
def pci_device_get_by_addr(context, node_id, dev_addr):
|
def pci_device_get_by_addr(context, node_id, dev_addr):
|
||||||
"""Get PCI device by address."""
|
"""Get PCI device by address."""
|
||||||
return IMPL.pci_device_get_by_addr(context, node_id, dev_addr)
|
return IMPL.pci_device_get_by_addr(context, node_id, dev_addr)
|
||||||
|
|
|
@ -4461,18 +4461,6 @@ def migration_migrate_to_uuid(context, count):
|
||||||
return done, done
|
return done, done
|
||||||
|
|
||||||
|
|
||||||
##################
|
|
||||||
|
|
||||||
|
|
||||||
@pick_context_manager_reader
|
|
||||||
def console_pool_get_all_by_host_type(context, host, console_type):
|
|
||||||
return model_query(context, models.ConsolePool, read_deleted="no").\
|
|
||||||
filter_by(host=host).\
|
|
||||||
filter_by(console_type=console_type).\
|
|
||||||
options(joinedload('consoles')).\
|
|
||||||
all()
|
|
||||||
|
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# User-provided metadata
|
# User-provided metadata
|
||||||
|
|
||||||
|
|
|
@ -985,6 +985,7 @@ class DNSDomain(BASE, NovaBase, models.SoftDeleteMixin):
|
||||||
project_id = Column(String(255))
|
project_id = Column(String(255))
|
||||||
|
|
||||||
|
|
||||||
|
# TODO(stephenfin): Remove in V or later
|
||||||
class ConsolePool(BASE, NovaBase, models.SoftDeleteMixin):
|
class ConsolePool(BASE, NovaBase, models.SoftDeleteMixin):
|
||||||
"""Represents pool of consoles on the same physical node."""
|
"""Represents pool of consoles on the same physical node."""
|
||||||
__tablename__ = 'console_pools'
|
__tablename__ = 'console_pools'
|
||||||
|
|
|
@ -3862,20 +3862,6 @@ class ComputeTestCase(BaseTestCase,
|
||||||
context=self.context, instance=instance, port="wrongport",
|
context=self.context, instance=instance, port="wrongport",
|
||||||
console_type="spice-html5"))
|
console_type="spice-html5"))
|
||||||
|
|
||||||
def test_xvpvnc_vnc_console(self):
|
|
||||||
# Make sure we can a vnc console for an instance.
|
|
||||||
self.flags(enabled=True, group='vnc')
|
|
||||||
self.flags(enabled=False, group='spice')
|
|
||||||
|
|
||||||
instance = self._create_fake_instance_obj()
|
|
||||||
self.compute.build_and_run_instance(self.context,
|
|
||||||
instance, {}, {}, {}, block_device_mapping=[])
|
|
||||||
|
|
||||||
console = self.compute.get_vnc_console(self.context, 'xvpvnc',
|
|
||||||
instance=instance)
|
|
||||||
self.assertTrue(console)
|
|
||||||
self.compute.terminate_instance(self.context, instance, [])
|
|
||||||
|
|
||||||
def test_invalid_vnc_console_type(self):
|
def test_invalid_vnc_console_type(self):
|
||||||
# Raise useful error if console type is an unrecognised string.
|
# Raise useful error if console type is an unrecognised string.
|
||||||
self.flags(enabled=True, group='vnc')
|
self.flags(enabled=True, group='vnc')
|
||||||
|
|
|
@ -8192,9 +8192,6 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
||||||
self.dns_domains = models.DNSDomain.__table__
|
self.dns_domains = models.DNSDomain.__table__
|
||||||
self.shadow_dns_domains = sqlalchemyutils.get_table(
|
self.shadow_dns_domains = sqlalchemyutils.get_table(
|
||||||
self.engine, "shadow_dns_domains")
|
self.engine, "shadow_dns_domains")
|
||||||
self.console_pools = models.ConsolePool.__table__
|
|
||||||
self.shadow_console_pools = sqlalchemyutils.get_table(
|
|
||||||
self.engine, "shadow_console_pools")
|
|
||||||
self.instances = models.Instance.__table__
|
self.instances = models.Instance.__table__
|
||||||
self.shadow_instances = sqlalchemyutils.get_table(
|
self.shadow_instances = sqlalchemyutils.get_table(
|
||||||
self.engine, "shadow_instances")
|
self.engine, "shadow_instances")
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
# Copyright (c) 2010 OpenStack Foundation
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
"""Fake ConsoleProxy driver for tests."""
|
|
||||||
|
|
||||||
|
|
||||||
class FakeConsoleProxy(object):
|
|
||||||
"""Fake ConsoleProxy driver."""
|
|
||||||
|
|
||||||
@property
|
|
||||||
def console_type(self):
|
|
||||||
return 'fake'
|
|
||||||
|
|
||||||
def setup_console(self, context, console):
|
|
||||||
"""Sets up actual proxies."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def teardown_console(self, context, console):
|
|
||||||
"""Tears down actual proxies."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def init_host(self):
|
|
||||||
"""Start up any config'ed consoles on start."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def generate_password(self, length=8):
|
|
||||||
"""Returns random console password."""
|
|
||||||
return 'fakepass'
|
|
||||||
|
|
||||||
def get_port(self, context):
|
|
||||||
"""Get available port for consoles that need one."""
|
|
||||||
return 5999
|
|
||||||
|
|
||||||
def fix_pool_password(self, password):
|
|
||||||
"""Trim password to length, and any other messaging."""
|
|
||||||
return password
|
|
||||||
|
|
||||||
def fix_console_password(self, password):
|
|
||||||
"""Trim password to length, and any other messaging."""
|
|
||||||
return password
|
|
|
@ -1,175 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# Copyright (c) 2012 OpenStack Foundation
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
"""Eventlet WSGI Services to proxy VNC for XCP protocol."""
|
|
||||||
|
|
||||||
import socket
|
|
||||||
|
|
||||||
import eventlet
|
|
||||||
import eventlet.green
|
|
||||||
import eventlet.greenio
|
|
||||||
import eventlet.wsgi
|
|
||||||
from oslo_log import log as logging
|
|
||||||
import webob
|
|
||||||
|
|
||||||
import nova.conf
|
|
||||||
from nova import context
|
|
||||||
from nova import exception
|
|
||||||
from nova import objects
|
|
||||||
from nova import utils
|
|
||||||
from nova import version
|
|
||||||
from nova import wsgi
|
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
|
||||||
CONF = nova.conf.CONF
|
|
||||||
|
|
||||||
|
|
||||||
class XCPVNCProxy(object):
|
|
||||||
"""Class to use the xvp auth protocol to proxy instance vnc consoles."""
|
|
||||||
|
|
||||||
def one_way_proxy(self, source, dest):
|
|
||||||
"""Proxy tcp connection from source to dest."""
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
d = source.recv(32384)
|
|
||||||
except Exception:
|
|
||||||
d = None
|
|
||||||
|
|
||||||
# If recv fails, send a write shutdown the other direction
|
|
||||||
if d is None or len(d) == 0:
|
|
||||||
dest.shutdown(socket.SHUT_WR)
|
|
||||||
break
|
|
||||||
# If send fails, terminate proxy in both directions
|
|
||||||
try:
|
|
||||||
# sendall raises an exception on write error, unlike send
|
|
||||||
dest.sendall(d)
|
|
||||||
except Exception:
|
|
||||||
source.close()
|
|
||||||
dest.close()
|
|
||||||
break
|
|
||||||
|
|
||||||
def handshake(self, req, connect_info, sockets):
|
|
||||||
"""Execute hypervisor-specific vnc auth handshaking (if needed)."""
|
|
||||||
host = connect_info.host
|
|
||||||
port = connect_info.port
|
|
||||||
|
|
||||||
server = eventlet.connect((host, port))
|
|
||||||
|
|
||||||
# Handshake as necessary
|
|
||||||
if 'internal_access_path' in connect_info:
|
|
||||||
path = connect_info.internal_access_path
|
|
||||||
server.sendall('CONNECT %s HTTP/1.1\r\n\r\n' % path)
|
|
||||||
|
|
||||||
data = ""
|
|
||||||
while True:
|
|
||||||
b = server.recv(1)
|
|
||||||
if b:
|
|
||||||
data += b
|
|
||||||
if data.find("\r\n\r\n") != -1:
|
|
||||||
if not data.split("\r\n")[0].find("200"):
|
|
||||||
LOG.info("Error in handshake format: %s", data)
|
|
||||||
return
|
|
||||||
break
|
|
||||||
|
|
||||||
if not b or len(data) > 4096:
|
|
||||||
LOG.info("Error in handshake: %s", data)
|
|
||||||
return
|
|
||||||
|
|
||||||
client = req.environ['eventlet.input'].get_socket()
|
|
||||||
client.sendall("HTTP/1.1 200 OK\r\n\r\n")
|
|
||||||
sockets['client'] = client
|
|
||||||
sockets['server'] = server
|
|
||||||
|
|
||||||
def proxy_connection(self, req, connect_info, start_response):
|
|
||||||
"""Spawn bi-directional vnc proxy."""
|
|
||||||
sockets = {}
|
|
||||||
t0 = utils.spawn(self.handshake, req, connect_info, sockets)
|
|
||||||
t0.wait()
|
|
||||||
|
|
||||||
if not sockets.get('client') or not sockets.get('server'):
|
|
||||||
LOG.info("Invalid request: %s", req)
|
|
||||||
start_response('400 Invalid Request',
|
|
||||||
[('content-type', 'text/html')])
|
|
||||||
return "Invalid Request"
|
|
||||||
|
|
||||||
client = sockets['client']
|
|
||||||
server = sockets['server']
|
|
||||||
|
|
||||||
t1 = utils.spawn(self.one_way_proxy, client, server)
|
|
||||||
t2 = utils.spawn(self.one_way_proxy, server, client)
|
|
||||||
t1.wait()
|
|
||||||
t2.wait()
|
|
||||||
|
|
||||||
# Make sure our sockets are closed
|
|
||||||
server.close()
|
|
||||||
client.close()
|
|
||||||
|
|
||||||
def __call__(self, environ, start_response):
|
|
||||||
try:
|
|
||||||
req = webob.Request(environ)
|
|
||||||
LOG.info("Request: %s", req)
|
|
||||||
token = req.params.get('token')
|
|
||||||
if not token:
|
|
||||||
LOG.info("Request made with missing token: %s", req)
|
|
||||||
start_response('400 Invalid Request',
|
|
||||||
[('content-type', 'text/html')])
|
|
||||||
return "Invalid Request"
|
|
||||||
|
|
||||||
ctxt = context.get_admin_context()
|
|
||||||
|
|
||||||
try:
|
|
||||||
connect_info = objects.ConsoleAuthToken.validate(ctxt, token)
|
|
||||||
except exception.InvalidToken:
|
|
||||||
LOG.info("Request made with invalid token: %s", req)
|
|
||||||
start_response('401 Not Authorized',
|
|
||||||
[('content-type', 'text/html')])
|
|
||||||
return "Not Authorized"
|
|
||||||
|
|
||||||
return self.proxy_connection(req, connect_info, start_response)
|
|
||||||
except Exception as e:
|
|
||||||
LOG.info("Unexpected error: %s", e)
|
|
||||||
|
|
||||||
|
|
||||||
class SafeHttpProtocol(eventlet.wsgi.HttpProtocol):
|
|
||||||
"""HttpProtocol wrapper to suppress IOErrors.
|
|
||||||
|
|
||||||
The proxy code above always shuts down client connections, so we catch
|
|
||||||
the IOError that raises when the SocketServer tries to flush the
|
|
||||||
connection.
|
|
||||||
"""
|
|
||||||
def finish(self):
|
|
||||||
try:
|
|
||||||
eventlet.green.BaseHTTPServer.BaseHTTPRequestHandler.finish(self)
|
|
||||||
except IOError:
|
|
||||||
pass
|
|
||||||
eventlet.greenio.shutdown_safe(self.connection)
|
|
||||||
self.connection.close()
|
|
||||||
|
|
||||||
|
|
||||||
def get_wsgi_server():
|
|
||||||
LOG.info("Starting nova-xvpvncproxy node (version %s)",
|
|
||||||
version.version_string_with_package())
|
|
||||||
|
|
||||||
LOG.warning('The nova-xvpvncproxy service is deprecated as it is Xen '
|
|
||||||
'specific and has effectively been replaced by noVNC '
|
|
||||||
'and the nova-novncproxy service.')
|
|
||||||
|
|
||||||
return wsgi.Server("XCP VNC Proxy",
|
|
||||||
XCPVNCProxy(),
|
|
||||||
protocol=SafeHttpProtocol,
|
|
||||||
host=CONF.vnc.xvpvncproxy_host,
|
|
||||||
port=CONF.vnc.xvpvncproxy_port)
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
The ``nova-xvpvncproxy`` service has been deprecated since the 19.0.0 Stein
|
||||||
|
release and has now been removed. The following configuration options have
|
||||||
|
also been removed:
|
||||||
|
|
||||||
|
* ``[vnc] xvpvncproxy_base_url``
|
||||||
|
* ``[vnc] xvpvncproxy_host``
|
||||||
|
* ``[vnc] xvpvncproxy_port``
|
||||||
|
* ``[xvp] console_xvp_conf_template``
|
||||||
|
* ``[xvp] console_xvp_conf``
|
||||||
|
* ``[xvp] console_xvp_log``
|
||||||
|
* ``[xvp] console_xvp_multiplex_port``
|
||||||
|
* ``[xvp] console_xvp_pid``
|
|
@ -76,7 +76,6 @@ console_scripts =
|
||||||
nova-serialproxy = nova.cmd.serialproxy:main
|
nova-serialproxy = nova.cmd.serialproxy:main
|
||||||
nova-spicehtml5proxy = nova.cmd.spicehtml5proxy:main
|
nova-spicehtml5proxy = nova.cmd.spicehtml5proxy:main
|
||||||
nova-status = nova.cmd.status:main
|
nova-status = nova.cmd.status:main
|
||||||
nova-xvpvncproxy = nova.cmd.xvpvncproxy:main
|
|
||||||
|
|
||||||
wsgi_scripts =
|
wsgi_scripts =
|
||||||
nova-api-wsgi = nova.api.openstack.compute.wsgi:init_application
|
nova-api-wsgi = nova.api.openstack.compute.wsgi:init_application
|
||||||
|
|
Loading…
Reference in New Issue