incorporate feedback from termie
This commit is contained in:
parent
71bd388a6c
commit
b01742ddb5
@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable-msg=C0103
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
@ -50,7 +49,7 @@ flags.DEFINE_boolean('vnc_debug', False,
|
||||
'Enable debugging features, like token bypassing')
|
||||
flags.DEFINE_integer('vnc_proxy_port', 6080,
|
||||
'Port that the VNC proxy should bind to')
|
||||
flags.DEFINE_string('vnc_proxy_iface', '0.0.0.0',
|
||||
flags.DEFINE_string('vnc_proxy_host', '0.0.0.0',
|
||||
'Address that the VNC proxy should bind to')
|
||||
flags.DEFINE_integer('vnc_token_ttl', 300,
|
||||
'How many seconds before deleting tokens')
|
||||
@ -90,5 +89,5 @@ if __name__ == "__main__":
|
||||
with_auth = auth.NovaAuthMiddleware(with_logging)
|
||||
|
||||
server = wsgi.Server()
|
||||
server.start(with_auth, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_iface)
|
||||
server.start(with_auth, FLAGS.vnc_proxy_port, host=FLAGS.vnc_proxy_host)
|
||||
server.wait()
|
||||
|
@ -477,21 +477,22 @@ class API(base.Base):
|
||||
output['token'])}
|
||||
|
||||
def get_vnc_console(self, context, instance_id):
|
||||
"""Get a url to an AJAX Console"""
|
||||
"""Get a url to a VNC Console."""
|
||||
instance = self.get(context, instance_id)
|
||||
output = self._call_compute_message('get_vnc_console',
|
||||
context,
|
||||
instance_id)
|
||||
rpc.cast(context, '%s' % FLAGS.vnc_console_proxy_topic,
|
||||
{'method': 'authorize_vnc_console',
|
||||
'args': {'token': output['token'], 'host': output['host'],
|
||||
'args': {'token': output['token'],
|
||||
'host': output['host'],
|
||||
'port': output['port']}})
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
return {'url': '%s/vnc_auto.html?token=%s&host=%s&port=%s' %
|
||||
(FLAGS.vnc_console_proxy_url,
|
||||
output['token'], 'hostignore', 'portignore')}
|
||||
return {'url': '%s/vnc_auto.html?token=%s&host=%s&port=%s' % (
|
||||
FLAGS.vnc_console_proxy_url,
|
||||
output['token'],
|
||||
'hostignore',
|
||||
'portignore')}
|
||||
|
||||
def get_console_output(self, context, instance_id):
|
||||
"""Get console output for an an instance"""
|
||||
|
@ -559,7 +559,7 @@ class ComputeManager(manager.Manager):
|
||||
|
||||
@exception.wrap_exception
|
||||
def get_vnc_console(self, context, instance_id):
|
||||
"""Return connection information for an vnc console"""
|
||||
"""Return connection information for an vnc console."""
|
||||
context = context.elevated()
|
||||
LOG.debug(_("instance %s: getting vnc console"), instance_id)
|
||||
instance_ref = self.db.instance_get(context, instance_id)
|
||||
|
@ -287,8 +287,8 @@ DEFINE_string('vnc_console_proxy_url',
|
||||
'http://127.0.0.1:6080',
|
||||
'location of vnc console proxy, \
|
||||
in the form "http://127.0.0.1:6080"')
|
||||
DEFINE_string('vnc_compute_host_iface', '0.0.0.0',
|
||||
'the compute host interface on which vnc server should listen')
|
||||
DEFINE_string('vnc_server_host', '0.0.0.0',
|
||||
'the host interface on which vnc server should listen')
|
||||
DEFINE_bool('vnc_enabled', True,
|
||||
'enable vnc related features')
|
||||
DEFINE_bool('verbose', False, 'show debug output')
|
||||
|
@ -101,8 +101,8 @@
|
||||
<target port='0'/>
|
||||
</serial>
|
||||
|
||||
#if $getVar('vnc_compute_host_iface', False)
|
||||
<graphics type='vnc' port='-1' autoport='yes' keymap='en-us' listen='${vnc_compute_host_iface}'/>
|
||||
#if $getVar('vnc_server_host', False)
|
||||
<graphics type='vnc' port='-1' autoport='yes' keymap='en-us' listen='${vnc_server_host}'/>
|
||||
#end if
|
||||
</devices>
|
||||
</domain>
|
||||
|
@ -516,6 +516,7 @@ class LibvirtConnection(object):
|
||||
def get_vnc_port_for_instance(instance_name):
|
||||
virt_dom = self._conn.lookupByName(instance_name)
|
||||
xml = virt_dom.XMLDesc(0)
|
||||
# TODO: use etree instead of minidom
|
||||
dom = minidom.parseString(xml)
|
||||
|
||||
for graphic in dom.getElementsByTagName('graphics'):
|
||||
@ -735,7 +736,7 @@ class LibvirtConnection(object):
|
||||
'driver_type': driver_type}
|
||||
|
||||
if FLAGS.vnc_enabled:
|
||||
xml_info['vnc_compute_host_iface'] = FLAGS.vnc_compute_host_iface
|
||||
xml_info['vnc_server_host'] = FLAGS.vnc_server_host
|
||||
if ra_server:
|
||||
xml_info['ra_server'] = ra_server + "/128"
|
||||
if not rescue:
|
||||
|
@ -18,11 +18,12 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Auth Components for VNC Console"""
|
||||
"""Auth Components for VNC Console."""
|
||||
|
||||
import time
|
||||
import urlparse
|
||||
import webob
|
||||
|
||||
from webob import Request
|
||||
|
||||
from nova import flags
|
||||
@ -32,12 +33,13 @@ from nova import utils
|
||||
from nova import wsgi
|
||||
from nova import vnc
|
||||
|
||||
|
||||
LOG = logging.getLogger('nova.vnc-proxy')
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
|
||||
class NovaAuthMiddleware(object):
|
||||
"""Implementation of Middleware to Handle Nova Auth"""
|
||||
"""Implementation of Middleware to Handle Nova Auth."""
|
||||
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
@ -67,13 +69,12 @@ class NovaAuthMiddleware(object):
|
||||
middleware = self
|
||||
middleware.tokens = {}
|
||||
|
||||
class Callback:
|
||||
def __call__(self, data, message):
|
||||
if data['method'] == 'authorize_vnc_console':
|
||||
token = data['args']['token']
|
||||
LOG.audit(_("Received Token: %s)"), token)
|
||||
middleware.tokens[token] = \
|
||||
{'args': data['args'], 'last_activity_at': time.time()}
|
||||
def callback(self, data, message):
|
||||
if data['method'] == 'authorize_vnc_console':
|
||||
token = data['args']['token']
|
||||
LOG.audit(_("Received Token: %s)"), token)
|
||||
middleware.tokens[token] = \
|
||||
{'args': data['args'], 'last_activity_at': time.time()}
|
||||
|
||||
def delete_expired_tokens():
|
||||
now = time.time()
|
||||
@ -90,7 +91,7 @@ class NovaAuthMiddleware(object):
|
||||
consumer = rpc.TopicConsumer(
|
||||
connection=conn,
|
||||
topic=FLAGS.vnc_console_proxy_topic)
|
||||
consumer.register_callback(Callback())
|
||||
consumer.register_callback(callback)
|
||||
|
||||
utils.LoopingCall(consumer.fetch, auto_ack=True,
|
||||
enable_callbacks=True).start(0.1)
|
||||
@ -103,7 +104,6 @@ class LoggingMiddleware(object):
|
||||
|
||||
@webob.dec.wsgify
|
||||
def __call__(self, req):
|
||||
|
||||
if req.path == vnc.proxy.WS_ENDPOINT:
|
||||
LOG.info(_("Received Websocket Request: %s"), req.url)
|
||||
else:
|
||||
|
@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable-msg=C0103
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
@ -20,11 +19,13 @@
|
||||
|
||||
"""Eventlet WSGI Services to proxy VNC. No nova deps."""
|
||||
|
||||
from base64 import b64encode, b64decode
|
||||
import base64
|
||||
import os
|
||||
|
||||
import eventlet
|
||||
from eventlet import wsgi
|
||||
from eventlet import websocket
|
||||
import os
|
||||
|
||||
from webob import Request
|
||||
import webob
|
||||
|
||||
@ -32,7 +33,7 @@ WS_ENDPOINT = '/data'
|
||||
|
||||
|
||||
class WebsocketVNCProxy(object):
|
||||
"""Class to proxy from websocket to vnc server"""
|
||||
"""Class to proxy from websocket to vnc server."""
|
||||
|
||||
def __init__(self, wwwroot):
|
||||
self.wwwroot = wwwroot
|
||||
@ -58,7 +59,7 @@ class WebsocketVNCProxy(object):
|
||||
d = source.recv(32384)
|
||||
if d == '':
|
||||
break
|
||||
d = b64encode(d)
|
||||
d = base64.b64encode(d)
|
||||
dest.send(d)
|
||||
except:
|
||||
source.close()
|
||||
@ -70,7 +71,7 @@ class WebsocketVNCProxy(object):
|
||||
d = source.wait()
|
||||
if d is None:
|
||||
break
|
||||
d = b64decode(d)
|
||||
d = base64.b64decode(d)
|
||||
dest.sendall(d)
|
||||
except:
|
||||
source.close()
|
||||
@ -118,7 +119,7 @@ class WebsocketVNCProxy(object):
|
||||
|
||||
|
||||
class DebugMiddleware(object):
|
||||
"""Debug middleware. Skip auth, get vnc port and host from query string"""
|
||||
"""Debug middleware. Skip auth, get vnc connect info from query string."""
|
||||
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
|
@ -1,163 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# pylint: disable-msg=C0103
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# 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.
|
||||
|
||||
"""Euca add-on to use vnc console"""
|
||||
|
||||
import getopt
|
||||
import os
|
||||
import sys
|
||||
|
||||
# If ../nova/__init__.py exists, add ../ to Python search path, so that
|
||||
# it will override what happens to be installed in /usr/(local/)lib/python...
|
||||
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
||||
os.pardir,
|
||||
os.pardir))
|
||||
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
|
||||
sys.path.insert(0, possible_topdir)
|
||||
|
||||
import boto
|
||||
import nova
|
||||
from boto.ec2.connection import EC2Connection
|
||||
from euca2ools import Euca2ool, InstanceValidationError, Util, ConnectionFailed
|
||||
|
||||
usage_string = """
|
||||
Retrieves a url to an vnc console terminal
|
||||
|
||||
euca-get-vnc-console [-h, --help] [--version] [--debug] instance_id
|
||||
|
||||
REQUIRED PARAMETERS
|
||||
|
||||
instance_id: unique identifier for the instance show the console output for.
|
||||
|
||||
OPTIONAL PARAMETERS
|
||||
|
||||
"""
|
||||
|
||||
|
||||
# This class extends boto to add VNCConsole functionality
|
||||
class NovaEC2Connection(EC2Connection):
|
||||
|
||||
def get_vnc_console(self, instance_id):
|
||||
"""
|
||||
Retrieves a console connection for the specified instance.
|
||||
|
||||
:type instance_id: string
|
||||
:param instance_id: The instance ID of a running instance on the cloud.
|
||||
|
||||
:rtype: :class:`VNCConsole`
|
||||
"""
|
||||
|
||||
class VNCConsole:
|
||||
def __init__(self, parent=None):
|
||||
self.parent = parent
|
||||
self.instance_id = None
|
||||
self.url = None
|
||||
|
||||
def startElement(self, name, attrs, connection):
|
||||
return None
|
||||
|
||||
def endElement(self, name, value, connection):
|
||||
if name == 'instanceId':
|
||||
self.instance_id = value
|
||||
elif name == 'url':
|
||||
self.url = value
|
||||
else:
|
||||
setattr(self, name, value)
|
||||
|
||||
params = {}
|
||||
return self.get_object('GetVNCConsole',
|
||||
{'InstanceId': instance_id}, VNCConsole)
|
||||
|
||||
|
||||
def override_connect_ec2(aws_access_key_id=None,
|
||||
aws_secret_access_key=None, **kwargs):
|
||||
return NovaEC2Connection(aws_access_key_id,
|
||||
aws_secret_access_key, **kwargs)
|
||||
|
||||
# override boto's connect_ec2 method, so that we can use NovaEC2Connection
|
||||
boto.connect_ec2 = override_connect_ec2
|
||||
|
||||
|
||||
def usage(status=1):
|
||||
print usage_string
|
||||
Util().usage()
|
||||
sys.exit(status)
|
||||
|
||||
|
||||
def version():
|
||||
print Util().version()
|
||||
sys.exit()
|
||||
|
||||
|
||||
def display_console_output(console_output):
|
||||
print console_output.instance_id
|
||||
print console_output.timestamp
|
||||
print console_output.output
|
||||
|
||||
|
||||
def display_vnc_console_output(console_output):
|
||||
print console_output.url
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
euca = Euca2ool()
|
||||
except Exception, e:
|
||||
print e
|
||||
usage()
|
||||
|
||||
instance_id = None
|
||||
|
||||
for name, value in euca.opts:
|
||||
if name in ('-h', '--help'):
|
||||
usage(0)
|
||||
elif name == '--version':
|
||||
version()
|
||||
elif name == '--debug':
|
||||
debug = True
|
||||
|
||||
for arg in euca.args:
|
||||
instance_id = arg
|
||||
break
|
||||
|
||||
if instance_id:
|
||||
try:
|
||||
euca.validate_instance_id(instance_id)
|
||||
except InstanceValidationError:
|
||||
print 'Invalid instance id'
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
euca_conn = euca.make_connection()
|
||||
except ConnectionFailed, e:
|
||||
print e.message
|
||||
sys.exit(1)
|
||||
try:
|
||||
console_output = euca_conn.get_vnc_console(instance_id)
|
||||
except Exception, ex:
|
||||
euca.display_error_and_exit('%s' % ex)
|
||||
|
||||
display_vnc_console_output(console_output)
|
||||
else:
|
||||
print 'instance_id must be specified'
|
||||
usage()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue
Block a user