Merge lp:~soren/nova/uml into lp:~hudson-openstack/nova/trunk

Proposed by Soren Hansen
Status: Merged
Approved by: Soren Hansen
Approved revision: no longer in the revision history of the source branch.
Merged at revision: 238
Proposed branch: lp:~soren/nova/uml
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 197 lines (+134/-10)
3 files modified
nova/tests/virt_unittest.py (+69/-0)
nova/virt/libvirt.uml.xml.template (+25/-0)
nova/virt/libvirt_conn.py (+40/-10)
To merge this branch: bzr merge lp:~soren/nova/uml
Reviewer Review Type Date Requested Status
Eric Day (community) Approve
Vish Ishaya (community) Approve
Review via email: mp+32676@code.launchpad.net

Commit message

Add new libvirt_type option "uml" for user-mode-linux.. This switches the libvirt URI to uml:///system and uses a different template for the libvirt xml.

Description of the change

Yo dawg, I heard you like clouds, so I put a cloud in your cloud...

This patchset let us use UML guests. This makes it possible to run Nova on e.g. Rackspace Cloud Servers.

Mind you, you will need a user-mode-linux package other than the one from Lucid to make this work, since that one is broken. You can find a working version in the nova-core ppa (or in probably a week's time in Lucid-updates).

To post a comment you must log in.
lp:~soren/nova/uml updated
229. By Ewan Mellor

Bug #617776: DescribeImagesResponse contains type element, when it should be called imageType

Make the objectstore respond with the field 'imageType' as well as 'type'.
The former is the correct one, according to the EC2 API specification for
the DescribeImages response. The latter is for compatibility with euca2ools
and other clients.

230. By Vish Ishaya

Improves pep8 compliance and pylint score in network code.

231. By Devin Carlen

Implemented admin client / admin api for fetching user roles.

232. By Vish Ishaya

Sets a hostname for instances that properly resolves and cleans up network classes

233. By Vish Ishaya

Fixes bug lp:616312 by reversing the order of args in nova-manage when it calls AuthManager.get_credentials.

234. By Vish Ishaya

Removes the workaround for syslog-ng of removing newlines.

235. By Joel Moore <email address hidden>

Fixed path to keys directory.

236. By Joel Moore <email address hidden>

Removes requirement of internet connectivity to run api server.

Revision history for this message
Vish Ishaya (vishvananda) wrote :

coolness. lgtm. I suppose the debian packaging will need to be updated to copy the xml files from the new location.

review: Approve
lp:~soren/nova/uml updated
237. By Vish Ishaya

Catches and logs exceptions for rpc calls and raises a RemoteError exception on the caller side.

Revision history for this message
Eric Day (eday) wrote :

lgtm

review: Approve
lp:~soren/nova/uml updated
238. By Soren Hansen

Add new libvirt_type option "uml" for user-mode-linux.. This switches the libvirt URI to uml:///system and uses a different template for the libvirt xml.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'nova/tests/virt_unittest.py'
2--- nova/tests/virt_unittest.py 1970-01-01 00:00:00 +0000
3+++ nova/tests/virt_unittest.py 2010-08-14 20:03:43 +0000
4@@ -0,0 +1,69 @@
5+# vim: tabstop=4 shiftwidth=4 softtabstop=4
6+#
7+# Copyright 2010 OpenStack LLC
8+#
9+# Licensed under the Apache License, Version 2.0 (the "License"); you may
10+# not use this file except in compliance with the License. You may obtain
11+# a copy of the License at
12+#
13+# http://www.apache.org/licenses/LICENSE-2.0
14+#
15+# Unless required by applicable law or agreed to in writing, software
16+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18+# License for the specific language governing permissions and limitations
19+# under the License.
20+
21+from nova import flags
22+from nova import test
23+from nova.virt import libvirt_conn
24+
25+FLAGS = flags.FLAGS
26+
27+
28+class LibvirtConnTestCase(test.TrialTestCase):
29+ def test_get_uri_and_template(self):
30+ class MockDataModel(object):
31+ def __init__(self):
32+ self.datamodel = { 'name' : 'i-cafebabe',
33+ 'memory_kb' : '1024000',
34+ 'basepath' : '/some/path',
35+ 'bridge_name' : 'br100',
36+ 'mac_address' : '02:12:34:46:56:67',
37+ 'vcpus' : 2 }
38+
39+ type_uri_map = { 'qemu' : ('qemu:///system',
40+ [lambda s: '<domain type=\'qemu\'>' in s,
41+ lambda s: 'type>hvm</type' in s,
42+ lambda s: 'emulator>/usr/bin/kvm' not in s]),
43+ 'kvm' : ('qemu:///system',
44+ [lambda s: '<domain type=\'kvm\'>' in s,
45+ lambda s: 'type>hvm</type' in s,
46+ lambda s: 'emulator>/usr/bin/qemu<' not in s]),
47+ 'uml' : ('uml:///system',
48+ [lambda s: '<domain type=\'uml\'>' in s,
49+ lambda s: 'type>uml</type' in s]),
50+ }
51+
52+ for (libvirt_type,(expected_uri, checks)) in type_uri_map.iteritems():
53+ FLAGS.libvirt_type = libvirt_type
54+ conn = libvirt_conn.LibvirtConnection(True)
55+
56+ uri, template = conn.get_uri_and_template()
57+ self.assertEquals(uri, expected_uri)
58+
59+ for i, check in enumerate(checks):
60+ xml = conn.toXml(MockDataModel())
61+ self.assertTrue(check(xml), '%s failed check %d' % (xml, i))
62+
63+ # Deliberately not just assigning this string to FLAGS.libvirt_uri and
64+ # checking against that later on. This way we make sure the
65+ # implementation doesn't fiddle around with the FLAGS.
66+ testuri = 'something completely different'
67+ FLAGS.libvirt_uri = testuri
68+ for (libvirt_type,(expected_uri, checks)) in type_uri_map.iteritems():
69+ FLAGS.libvirt_type = libvirt_type
70+ conn = libvirt_conn.LibvirtConnection(True)
71+ uri, template = conn.get_uri_and_template()
72+ self.assertEquals(uri, testuri)
73+
74
75=== renamed file 'nova/compute/interfaces.template' => 'nova/virt/interfaces.template'
76=== renamed file 'nova/compute/libvirt.xml.template' => 'nova/virt/libvirt.qemu.xml.template'
77=== added file 'nova/virt/libvirt.uml.xml.template'
78--- nova/virt/libvirt.uml.xml.template 1970-01-01 00:00:00 +0000
79+++ nova/virt/libvirt.uml.xml.template 2010-08-14 20:03:43 +0000
80@@ -0,0 +1,25 @@
81+<domain type='%(type)s'>
82+ <name>%(name)s</name>
83+ <memory>%(memory_kb)s</memory>
84+ <os>
85+ <type>%(type)s</type>
86+ <kernel>/usr/bin/linux</kernel>
87+ <root>/dev/ubda1</root>
88+ </os>
89+ <devices>
90+ <disk type='file'>
91+ <source file='%(basepath)s/disk'/>
92+ <target dev='ubd0' bus='uml'/>
93+ </disk>
94+ <interface type='bridge'>
95+ <source bridge='%(bridge_name)s'/>
96+ <mac address='%(mac_address)s'/>
97+ </interface>
98+ <console type="pty" />
99+ <serial type="file">
100+ <source path='%(basepath)s/console.log'/>
101+ <target port='1'/>
102+ </serial>
103+ </devices>
104+ <nova>%(nova)s</nova>
105+</domain>
106
107=== modified file 'nova/virt/libvirt_conn.py'
108--- nova/virt/libvirt_conn.py 2010-08-10 15:37:07 +0000
109+++ nova/virt/libvirt_conn.py 2010-08-14 20:03:43 +0000
110@@ -44,15 +44,20 @@
111
112 FLAGS = flags.FLAGS
113 flags.DEFINE_string('libvirt_xml_template',
114- utils.abspath('compute/libvirt.xml.template'),
115- 'Libvirt XML Template')
116+ utils.abspath('virt/libvirt.qemu.xml.template'),
117+ 'Libvirt XML Template for QEmu/KVM')
118+flags.DEFINE_string('libvirt_uml_xml_template',
119+ utils.abspath('virt/libvirt.uml.xml.template'),
120+ 'Libvirt XML Template for user-mode-linux')
121 flags.DEFINE_string('injected_network_template',
122- utils.abspath('compute/interfaces.template'),
123+ utils.abspath('virt/interfaces.template'),
124 'Template file for injected network')
125-
126 flags.DEFINE_string('libvirt_type',
127 'kvm',
128- 'Libvirt domain type (kvm, qemu, etc)')
129+ 'Libvirt domain type (valid options are: kvm, qemu, uml)')
130+flags.DEFINE_string('libvirt_uri',
131+ '',
132+ 'Override the default libvirt URI (which is dependent on libvirt_type)')
133
134 def get_connection(read_only):
135 # These are loaded late so that there's no need to install these
136@@ -65,16 +70,42 @@
137 libxml2 = __import__('libxml2')
138 return LibvirtConnection(read_only)
139
140-
141 class LibvirtConnection(object):
142 def __init__(self, read_only):
143+ self.libvirt_uri, template_file = self.get_uri_and_template()
144+
145+ self.libvirt_xml = open(template_file).read()
146+ self._wrapped_conn = None
147+ self.read_only = read_only
148+
149+
150+ @property
151+ def _conn(self):
152+ if not self._wrapped_conn:
153+ self._wrapped_conn = self._connect(self.libvirt_uri, self.read_only)
154+ return self._wrapped_conn
155+
156+
157+ def get_uri_and_template(self):
158+ if FLAGS.libvirt_type == 'uml':
159+ uri = FLAGS.libvirt_uri or 'uml:///system'
160+ template_file = FLAGS.libvirt_uml_xml_template
161+ else:
162+ uri = FLAGS.libvirt_uri or 'qemu:///system'
163+ template_file = FLAGS.libvirt_xml_template
164+ return uri, template_file
165+
166+
167+ def _connect(self, uri, read_only):
168 auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_NOECHOPROMPT],
169 'root',
170 None]
171+
172 if read_only:
173- self._conn = libvirt.openReadOnly('qemu:///system')
174+ return libvirt.openReadOnly(uri)
175 else:
176- self._conn = libvirt.openAuth('qemu:///system', auth, 0)
177+ return libvirt.openAuth(uri, auth, 0)
178+
179
180
181 def list_instances(self):
182@@ -237,14 +268,13 @@
183 def toXml(self, instance):
184 # TODO(termie): cache?
185 logging.debug("Starting the toXML method")
186- libvirt_xml = open(FLAGS.libvirt_xml_template).read()
187 xml_info = instance.datamodel.copy()
188 # TODO(joshua): Make this xml express the attached disks as well
189
190 # TODO(termie): lazy lazy hack because xml is annoying
191 xml_info['nova'] = json.dumps(instance.datamodel.copy())
192 xml_info['type'] = FLAGS.libvirt_type
193- libvirt_xml = libvirt_xml % xml_info
194+ libvirt_xml = self.libvirt_xml % xml_info
195 logging.debug("Finished the toXML method")
196
197 return libvirt_xml