From a3077cbb859a9237f9516ed0f073fe00839277c4 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 1 Nov 2010 16:25:56 -0700 Subject: basics to get proxied ajaxterm working with virsh --- nova/virt/libvirt.qemu.xml.template | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'nova/virt') diff --git a/nova/virt/libvirt.qemu.xml.template b/nova/virt/libvirt.qemu.xml.template index 2538b1ade..d5a249665 100644 --- a/nova/virt/libvirt.qemu.xml.template +++ b/nova/virt/libvirt.qemu.xml.template @@ -4,6 +4,9 @@ hvm %(basepath)s/kernel %(basepath)s/ramdisk + root=/dev/vda1 console=ttyS0 @@ -25,9 +28,15 @@ + + + + + -- cgit From 08963a0df7a6d1c90ba12ce60cbf15c93b0b70e6 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 21 Dec 2010 14:44:53 -0800 Subject: prototype works with kvm. now moving call from api to compute --- nova/virt/libvirt.qemu.xml.template | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/libvirt.qemu.xml.template b/nova/virt/libvirt.qemu.xml.template index d5a249665..1f0c8a3ff 100644 --- a/nova/virt/libvirt.qemu.xml.template +++ b/nova/virt/libvirt.qemu.xml.template @@ -4,9 +4,6 @@ hvm %(basepath)s/kernel %(basepath)s/ramdisk - root=/dev/vda1 console=ttyS0 @@ -28,15 +25,22 @@ - - - - - ---> + + + + + + + + + + + -- cgit From a84e2b9131e4c8b212c9de0b9ad4931f7743ff75 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 21 Dec 2010 18:20:55 -0800 Subject: move prototype code from api into compute worker --- nova/virt/libvirt_conn.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'nova/virt') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 509ed97a0..f2110e4e8 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -42,6 +42,10 @@ from nova.compute import disk from nova.compute import instance_types from nova.compute import power_state from nova.virt import images +import subprocess +import random +import uuid +from xml.dom import minidom libvirt = None libxml2 = None @@ -71,7 +75,9 @@ flags.DEFINE_string('libvirt_uri', flags.DEFINE_bool('allow_project_net_traffic', True, 'Whether to allow in project network traffic') - +flags.DEFINE_string('console_dmz', + 'tonbuntu:8000', + 'location of console proxy') def get_connection(read_only): # These are loaded late so that there's no need to install these @@ -310,6 +316,47 @@ class LibvirtConnection(object): d.addCallback(self._dump_file) return d + @exception.wrap_exception + def get_ajax_console(self, instance): + def get_open_port(): + for i in xrange(0,100): # don't loop forever + port = random.randint(10000, 12000) + cmd = 'netcat 0.0.0.0 %s -w 2 < /dev/null' % (port,) + # this Popen will exit with 0 only if the port is in use, + # so a nonzero return value implies it is unused + port_is_unused = (subprocess.Popen(cmd, shell=True).wait() != 0) + if port_is_unused: + return port + raise 'Unable to find an open port' + + def get_pty_for_instance(instance_name): + stdout, stderr = utils.execute('virsh dumpxml %s' % instance_name) + dom = minidom.parseString(stdout) + serials = dom.getElementsByTagName('serial') + for serial in serials: + if serial.getAttribute('type') == 'pty': + source = serial.getElementsByTagName('source')[0] + return source.getAttribute('path') + + port = get_open_port() + token = str(uuid.uuid4()) + + host = instance['host'] + + if FLAGS.libvirt_type == 'uml': + pass #FIXME + elif FLAGS.libvirt_type == 'xen': + pass #FIXME + else: + ajaxterm_cmd = 'socat - %s' % get_pty_for_instance(instance['name']) + + cmd = '%s/tools/ajaxterm/ajaxterm.py --command "%s" -t %s -p %s' \ + % (utils.novadir(), ajaxterm_cmd, token, port) + + subprocess.Popen(cmd, shell=True) + return 'http://%s/?token=%s&host=%s&port=%s' \ + % (FLAGS.console_dmz, token, host, port) + @defer.inlineCallbacks def _create_image(self, inst, libvirt_xml): # syntactic nicety -- cgit From 28645bec4a6d084f6dc6fa51184061844826cb12 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 21 Dec 2010 23:15:00 -0800 Subject: a few more fixes after merge with trunk --- nova/virt/libvirt_conn.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index d39e3cc5b..b186a7c45 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -42,6 +42,7 @@ import shutil import random import subprocess import uuid +from xml.dom import minidom from eventlet import event @@ -86,6 +87,9 @@ flags.DEFINE_string('libvirt_uri', flags.DEFINE_bool('allow_project_net_traffic', True, 'Whether to allow in project network traffic') +flags.DEFINE_string('console_dmz', + 'tonbuntu:8000', + 'location of console proxy') def get_connection(read_only): @@ -389,13 +393,13 @@ class LibvirtConnection(object): def get_open_port(): for i in xrange(0,100): # don't loop forever port = random.randint(10000, 12000) - cmd = 'netcat 0.0.0.0 %s -w 2 < /dev/null' % (port,) - # this Popen will exit with 0 only if the port is in use, + # netcat will exit with 0 only if the port is in use, # so a nonzero return value implies it is unused - port_is_unused = (subprocess.Popen(cmd, shell=True).wait() != 0) - if port_is_unused: + cmd = 'netcat 0.0.0.0 %s -w 1 < /dev/null || echo free' % (port) + stdout, stderr = utils.execute(cmd) + if stdout.strip() == 'free': return port - raise 'Unable to find an open port' + raise Exception('Unable to find an open port') def get_pty_for_instance(instance_name): stdout, stderr = utils.execute('virsh dumpxml %s' % instance_name) -- cgit From 19f389b3dcc89f0115dc6fc1a6ca606338ad866a Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 22 Dec 2010 12:36:37 -0800 Subject: working connection security --- nova/virt/libvirt_conn.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index b186a7c45..800312c98 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -87,9 +87,6 @@ flags.DEFINE_string('libvirt_uri', flags.DEFINE_bool('allow_project_net_traffic', True, 'Whether to allow in project network traffic') -flags.DEFINE_string('console_dmz', - 'tonbuntu:8000', - 'location of console proxy') def get_connection(read_only): @@ -426,8 +423,9 @@ class LibvirtConnection(object): % (utils.novadir(), ajaxterm_cmd, token, port) subprocess.Popen(cmd, shell=True) - return 'http://%s/?token=%s&host=%s&port=%s' \ - % (FLAGS.console_dmz, token, host, port) + return {'token': token, 'host': host, 'port': port} + #return 'http://%s/?token=%s&host=%s&port=%s' \ + # % (FLAGS.console_dmz, token, host, port) def _create_image(self, inst, libvirt_xml, prefix='', disk_images=None): # syntactic nicety -- cgit From 0093342106cc270859df0511dbefad8ec8fc2320 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 22 Dec 2010 13:31:33 -0800 Subject: use libvirt python bindings instead of system call --- nova/virt/libvirt_conn.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 800312c98..658efa8d1 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -392,17 +392,18 @@ class LibvirtConnection(object): port = random.randint(10000, 12000) # netcat will exit with 0 only if the port is in use, # so a nonzero return value implies it is unused - cmd = 'netcat 0.0.0.0 %s -w 1 < /dev/null || echo free' % (port) + cmd = 'netcat 0.0.0.0 %s -w 1 Date: Wed, 22 Dec 2010 18:52:43 -0800 Subject: minor notes, commit before rewriting proxy with eventlet --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/virt') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 658efa8d1..55754ea48 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -389,7 +389,7 @@ class LibvirtConnection(object): def get_ajax_console(self, instance): def get_open_port(): for i in xrange(0,100): # don't loop forever - port = random.randint(10000, 12000) + port = random.randint(10000, 12000) #TODO - make flag # netcat will exit with 0 only if the port is in use, # so a nonzero return value implies it is unused cmd = 'netcat 0.0.0.0 %s -w 1 Date: Thu, 23 Dec 2010 00:23:08 -0800 Subject: move port range for ajaxterm to flag --- nova/virt/libvirt_conn.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'nova/virt') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 55754ea48..1049eaefa 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -87,6 +87,9 @@ flags.DEFINE_string('libvirt_uri', flags.DEFINE_bool('allow_project_net_traffic', True, 'Whether to allow in project network traffic') +flags.DEFINE_string('ajaxterm_portrange', + '10000-12000', + 'Range of ports that ajaxterm should randomly try to bind') def get_connection(read_only): @@ -388,8 +391,9 @@ class LibvirtConnection(object): @exception.wrap_exception def get_ajax_console(self, instance): def get_open_port(): + start_port, end_port = FLAGS.ajaxterm_portrange.split("-") for i in xrange(0,100): # don't loop forever - port = random.randint(10000, 12000) #TODO - make flag + port = random.randint(int(start_port), int(end_port)) # netcat will exit with 0 only if the port is in use, # so a nonzero return value implies it is unused cmd = 'netcat 0.0.0.0 %s -w 1 Date: Thu, 23 Dec 2010 00:58:15 -0800 Subject: removing xen/uml specific switches. If they need special treatment, we can add it --- nova/virt/libvirt_conn.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index d855770b7..3c0efd18f 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -427,12 +427,7 @@ class LibvirtConnection(object): host = instance['host'] - if FLAGS.libvirt_type == 'uml': - pass #FIXME - elif FLAGS.libvirt_type == 'xen': - pass #FIXME - else: - ajaxterm_cmd = 'socat - %s' % get_pty_for_instance(instance['name']) + ajaxterm_cmd = 'socat - %s' % get_pty_for_instance(instance['name']) cmd = '%s/tools/ajaxterm/ajaxterm.py --command "%s" -t %s -p %s' \ % (utils.novadir(), ajaxterm_cmd, token, port) -- cgit From 43dfae5926bafa1575aee9624651cfcb8f170bb3 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Thu, 23 Dec 2010 01:22:54 -0800 Subject: some pep8 fixes --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/virt') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 3c0efd18f..40a430d86 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -402,7 +402,7 @@ class LibvirtConnection(object): def get_ajax_console(self, instance): def get_open_port(): start_port, end_port = FLAGS.ajaxterm_portrange.split("-") - for i in xrange(0,100): # don't loop forever + for i in xrange(0,100): # don't loop forever port = random.randint(int(start_port), int(end_port)) # netcat will exit with 0 only if the port is in use, # so a nonzero return value implies it is unused -- cgit From 35638077a186f9315ac6e30cdbe096730a540ed8 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 28 Dec 2010 17:42:33 -0800 Subject: add in unit tests --- nova/virt/fake.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'nova/virt') diff --git a/nova/virt/fake.py b/nova/virt/fake.py index 238acf798..b97dbd511 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -260,6 +260,8 @@ class FakeConnection(object): def get_console_output(self, instance): return 'FAKE CONSOLE OUTPUT' + def get_ajax_console(self, instance): + return 'http://fakeajaxconsole.com/?token=FAKETOKEN' class FakeInstance(object): -- cgit From 8df8dd5cedb8bd84053fa489df8b9cf34ee68895 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Mon, 3 Jan 2011 08:56:36 -0800 Subject: add stubs for xen driver --- nova/virt/xenapi/vmops.py | 5 +++++ nova/virt/xenapi_conn.py | 4 ++++ 2 files changed, 9 insertions(+) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 76f31635a..146b9e6df 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -281,3 +281,8 @@ class VMOps(object): """Return snapshot of console""" # TODO: implement this to fix pylint! return 'FAKE CONSOLE OUTPUT of instance' + + def get_ajax_console(self, instance): + """Return link to instance's ajax console""" + # TODO: implement this! + return 'http://fakeajaxconsole/fake_url' diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index f17c8f39d..e1ad04b15 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -175,6 +175,10 @@ class XenAPIConnection(object): """Return snapshot of console""" return self._vmops.get_console_output(instance) + def get_ajax_console(self, instance): + """Return link to instance's ajax console""" + return self._vmops.get_ajax_console(instance) + def attach_volume(self, instance_name, device_path, mountpoint): """Attach volume storage to VM instance""" return self._volumeops.attach_volume(instance_name, -- cgit From ee2d8a5bcdaf938b7047131d7809d1b6b3120b59 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Mon, 3 Jan 2011 22:51:19 -0800 Subject: some fixes per vish's feedback --- nova/virt/libvirt_conn.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 6471e8c0c..a36af16e2 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -438,7 +438,7 @@ class LibvirtConnection(object): stdout, stderr = utils.execute(cmd) if stdout.strip() == 'free': return port - raise Exception('Unable to find an open port') + raise Exception(_('Unable to find an open port')) def get_pty_for_instance(instance_name): virt_dom = self._conn.lookupByName(instance_name) @@ -452,7 +452,6 @@ class LibvirtConnection(object): port = get_open_port() token = str(uuid.uuid4()) - host = instance['host'] ajaxterm_cmd = 'socat - %s' % get_pty_for_instance(instance['name']) @@ -462,8 +461,6 @@ class LibvirtConnection(object): subprocess.Popen(cmd, shell=True) return {'token': token, 'host': host, 'port': port} - #return 'http://%s/?token=%s&host=%s&port=%s' \ - # % (FLAGS.console_dmz, token, host, port) def _create_image(self, inst, libvirt_xml, prefix='', disk_images=None): # syntactic nicety -- cgit From 7c01430020ceabec765f388b70685808064cda3f Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 4 Jan 2011 16:22:47 -0800 Subject: some more cleanup --- nova/virt/libvirt.xml.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/virt') diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index 3317c9eca..2eb7d9488 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -72,7 +72,7 @@ - + -- cgit From 9b99e385967c4ba21d94d82aa62115fc11634118 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Wed, 5 Jan 2011 14:57:31 -0800 Subject: socat will need to be added to our nova sudoers --- nova/virt/libvirt_conn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/virt') diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index a36af16e2..d83c57741 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -454,7 +454,7 @@ class LibvirtConnection(object): token = str(uuid.uuid4()) host = instance['host'] - ajaxterm_cmd = 'socat - %s' % get_pty_for_instance(instance['name']) + ajaxterm_cmd = 'sudo socat - %s' % get_pty_for_instance(instance['name']) cmd = '%s/tools/ajaxterm/ajaxterm.py --command "%s" -t %s -p %s' \ % (utils.novadir(), ajaxterm_cmd, token, port) -- cgit From eb48bdce5ad131245977dff50030f5561b8809c1 Mon Sep 17 00:00:00 2001 From: Anthony Young Date: Tue, 11 Jan 2011 14:33:20 -0800 Subject: bah - pep8 errors --- nova/virt/fake.py | 1 + nova/virt/libvirt_conn.py | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/fake.py b/nova/virt/fake.py index 925c32e4d..8abe08e41 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -292,6 +292,7 @@ class FakeConnection(object): def get_ajax_console(self, instance): return 'http://fakeajaxconsole.com/?token=FAKETOKEN' + class FakeInstance(object): def __init__(self): diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index dc31d8357..4a907c88f 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -445,7 +445,7 @@ class LibvirtConnection(object): def get_ajax_console(self, instance): def get_open_port(): start_port, end_port = FLAGS.ajaxterm_portrange.split("-") - for i in xrange(0,100): # don't loop forever + for i in xrange(0, 100): # don't loop forever port = random.randint(int(start_port), int(end_port)) # netcat will exit with 0 only if the port is in use, # so a nonzero return value implies it is unused @@ -469,10 +469,11 @@ class LibvirtConnection(object): token = str(uuid.uuid4()) host = instance['host'] - ajaxterm_cmd = 'sudo socat - %s' % get_pty_for_instance(instance['name']) + ajaxterm_cmd = 'sudo socat - %s' \ + % get_pty_for_instance(instance['name']) cmd = '%s/tools/ajaxterm/ajaxterm.py --command "%s" -t %s -p %s' \ - % (utils.novadir(), ajaxterm_cmd, token, port) + % (utils.novadir(), ajaxterm_cmd, token, port) subprocess.Popen(cmd, shell=True) return {'token': token, 'host': host, 'port': port} -- cgit