Merge lp:~ewanmellor/nova/xenapi into lp:~hudson-openstack/nova/trunk

Proposed by Ewan Mellor
Status: Merged
Approved by: Jay Pipes
Approved revision: 176
Merged at revision: 240
Proposed branch: lp:~ewanmellor/nova/xenapi
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 274 lines (+142/-21)
5 files modified
doc/source/getting.started.rst (+1/-0)
nova/virt/connection.py (+9/-0)
nova/virt/fake.py (+128/-1)
nova/virt/libvirt_conn.py (+0/-20)
plugins/xenapi/README (+4/-0)
To merge this branch: bzr merge lp:~ewanmellor/nova/xenapi
Reviewer Review Type Date Requested Status
Soren Hansen (community) Approve
Jay Pipes (community) Approve
Review via email: mp+32582@code.launchpad.net

Commit message

Added documentation for the nova.virt connection interface, a note about the need to chmod the objectstore script, and a reference for the XenAPI module.

Description of the change

Added documentation for the nova.virt connection interface, a note about the need to chmod the objectstore script, and a reference for the XenAPI module.

To post a comment you must log in.
Revision history for this message
Jay Pipes (jaypipes) wrote :

Documentation++

review: Approve
Revision history for this message
Soren Hansen (soren) wrote :

Yay for more documentation.

Revision history for this message
Soren Hansen (soren) :
review: Approve
Revision history for this message
OpenStack Infra (hudson-openstack) wrote :
Download full text (10.6 KiB)

The attempt to merge lp:~ewanmellor/nova/xenapi into lp:nova failed.Below is the output from the failed tests.

nova.tests.access_unittest
  AccessTestCase
    test_001_allow_all ... [OK]
    test_002_allow_none ... [OK]
    test_003_allow_project_manager ... [OK]
    test_004_allow_sys_and_net ... [OK]
    test_005_allow_sys_no_pm ... [OK]
nova.tests.api_unittest
  ApiEc2TestCase
    test_describe_instances ... [OK]
    test_get_all_key_pairs ... [OK]
nova.tests.auth_unittest
  AuthTestCase
    test_001_can_create_users ... [OK]
    test_002_can_get_user ... [OK]
    test_003_can_retreive_properties ... [OK]
    test_004_signature_is_valid ... [OK]
    test_005_can_get_credentials ... [OK]
    test_006_test_key_storage ... [OK]
    test_007_test_key_generation ... [OK]
    test_008_can_list_key_pairs ... [OK]
    test_009_can_delete_key_pair ... [OK]
    test_010_can_list_users ... [OK]
    test_101_can_add_user_role ... [OK]
    test_199_can_remove_user_role ... [OK]
    test_201_can_create_project ... [OK]
    test_202_user1_is_project_member ... [OK]
    test_203_user2_is_not_project_member ... [OK]
    test_204_user1_is_project_manager ... [OK]
    test_205_user2_is_not_project_manager ... [OK]
    test_206_can_add_user_to_project ... [OK]
    test_207_can_remove_user_from_project ... [OK]
    test_208_can_remove_add_user_with_role ... [OK]
    test_209_can_generate_x509 ... [OK]
    test_210_can_add_project_role ... [OK]
    test_211_can_list_project_roles ... [OK]
    test_212_can_remove_project_role ... [OK]
    test_214_can_retrieve_project_by_user ... [OK]
    test_299_can_delete_project ... [OK]
    test_999_can_delete_users ... [OK]
nova.tests.cloud_unittest
  CloudTestCase
    test_console_output ... [OK]
    test_instance_update_state ... [OK]
    test_run_instances ... ...

Revision history for this message
Jay Pipes (jaypipes) wrote :

grr...

non-deterministic testing--

setting to approve again...this is just docs, shouldn't be any test failures. :(

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/source/getting.started.rst'
2--- doc/source/getting.started.rst 2010-07-25 01:06:22 +0000
3+++ doc/source/getting.started.rst 2010-08-13 13:39:41 +0000
4@@ -40,6 +40,7 @@
5
6 * M2Crypto: python library interface for openssl
7 * curl
8+* XenAPI: Needed only for Xen Cloud Platform or XenServer support. Available from http://wiki.xensource.com/xenwiki/XCP_SDK or http://community.citrix.com/cdn/xs/sdks.
9
10 Vendored python libaries (don't require any installation)
11
12
13=== modified file 'nova/virt/connection.py'
14--- nova/virt/connection.py 2010-07-18 17:28:21 +0000
15+++ nova/virt/connection.py 2010-08-13 13:39:41 +0000
16@@ -27,6 +27,15 @@
17
18
19 def get_connection(read_only=False):
20+ """Returns an object representing the connection to a virtualization
21+ platform. This could be nova.virt.fake.FakeConnection in test mode,
22+ a connection to KVM or QEMU via libvirt, or a connection to XenServer
23+ or Xen Cloud Platform via XenAPI.
24+
25+ Any object returned here must conform to the interface documented by
26+ FakeConnection.
27+ """
28+
29 # TODO(termie): maybe lazy load after initial check for permissions
30 # TODO(termie): check whether we can be disconnected
31 t = FLAGS.connection_type
32
33=== modified file 'nova/virt/fake.py'
34--- nova/virt/fake.py 2010-07-18 17:15:12 +0000
35+++ nova/virt/fake.py 2010-08-13 13:39:41 +0000
36@@ -19,6 +19,7 @@
37
38 """
39 A fake (in-memory) hypervisor+api. Allows nova testing w/o a hypervisor.
40+This module also documents the semantics of real hypervisor connections.
41 """
42
43 import logging
44@@ -32,6 +33,38 @@
45
46
47 class FakeConnection(object):
48+ """
49+ The interface to this class talks in terms of 'instances' (Amazon EC2 and
50+ internal Nova terminology), by which we mean 'running virtual machine'
51+ (XenAPI terminology) or domain (Xen or libvirt terminology).
52+
53+ An instance has an ID, which is the identifier chosen by Nova to represent
54+ the instance further up the stack. This is unfortunately also called a
55+ 'name' elsewhere. As far as this layer is concerned, 'instance ID' and
56+ 'instance name' are synonyms.
57+
58+ Note that the instance ID or name is not human-readable or
59+ customer-controlled -- it's an internal ID chosen by Nova. At the
60+ nova.virt layer, instances do not have human-readable names at all -- such
61+ things are only known higher up the stack.
62+
63+ Most virtualization platforms will also have their own identity schemes,
64+ to uniquely identify a VM or domain. These IDs must stay internal to the
65+ platform-specific layer, and never escape the connection interface. The
66+ platform-specific layer is responsible for keeping track of which instance
67+ ID maps to which platform-specific ID, and vice versa.
68+
69+ In contrast, the list_disks and list_interfaces calls may return
70+ platform-specific IDs. These identify a specific virtual disk or specific
71+ virtual network interface, and these IDs are opaque to the rest of Nova.
72+
73+ Some methods here take an instance of nova.compute.service.Instance. This
74+ is the datastructure used by nova.compute to store details regarding an
75+ instance, and pass them into this layer. This layer is responsible for
76+ translating that generic datastructure into terms that are specific to the
77+ virtualization platform.
78+ """
79+
80 def __init__(self):
81 self.instances = {}
82
83@@ -42,20 +75,59 @@
84 return cls._instance
85
86 def list_instances(self):
87+ """
88+ Return the names of all the instances known to the virtualization
89+ layer, as a list.
90+ """
91 return self.instances.keys()
92
93 def spawn(self, instance):
94+ """
95+ Create a new instance/VM/domain on the virtualization platform.
96+
97+ The given parameter is an instance of nova.compute.service.Instance.
98+ This function should use the data there to guide the creation of
99+ the new instance.
100+
101+ Once this function successfully completes, the instance should be
102+ running (power_state.RUNNING).
103+
104+ If this function fails, any partial instance should be completely
105+ cleaned up, and the virtualization platform should be in the state
106+ that it was before this call began.
107+ """
108+
109 fake_instance = FakeInstance()
110 self.instances[instance.name] = fake_instance
111 fake_instance._state = power_state.RUNNING
112
113 def reboot(self, instance):
114+ """
115+ Reboot the specified instance.
116+
117+ The given parameter is an instance of nova.compute.service.Instance,
118+ and so the instance is being specified as instance.name.
119+ """
120 pass
121-
122+
123 def destroy(self, instance):
124+ """
125+ Destroy (shutdown and delete) the specified instance.
126+
127+ The given parameter is an instance of nova.compute.service.Instance,
128+ and so the instance is being specified as instance.name.
129+ """
130 del self.instances[instance.name]
131
132 def get_info(self, instance_id):
133+ """
134+ Get a block of information about the given instance. This is returned
135+ as a dictionary containing 'state': The power_state of the instance,
136+ 'max_mem': The maximum memory for the instance, in KiB, 'mem': The
137+ current memory the instance has, in KiB, 'num_cpu': The current number
138+ of virtual CPUs the instance has, 'cpu_time': The total CPU time used
139+ by the instance, in nanoseconds.
140+ """
141 i = self.instances[instance_id]
142 return {'state': i._state,
143 'max_mem': 0,
144@@ -64,15 +136,70 @@
145 'cpu_time': 0}
146
147 def list_disks(self, instance_id):
148+ """
149+ Return the IDs of all the virtual disks attached to the specified
150+ instance, as a list. These IDs are opaque to the caller (they are
151+ only useful for giving back to this layer as a parameter to
152+ disk_stats). These IDs only need to be unique for a given instance.
153+
154+ Note that this function takes an instance ID, not a
155+ compute.service.Instance, so that it can be called by compute.monitor.
156+ """
157 return ['A_DISK']
158
159 def list_interfaces(self, instance_id):
160+ """
161+ Return the IDs of all the virtual network interfaces attached to the
162+ specified instance, as a list. These IDs are opaque to the caller
163+ (they are only useful for giving back to this layer as a parameter to
164+ interface_stats). These IDs only need to be unique for a given
165+ instance.
166+
167+ Note that this function takes an instance ID, not a
168+ compute.service.Instance, so that it can be called by compute.monitor.
169+ """
170 return ['A_VIF']
171
172 def block_stats(self, instance_id, disk_id):
173+ """
174+ Return performance counters associated with the given disk_id on the
175+ given instance_id. These are returned as [rd_req, rd_bytes, wr_req,
176+ wr_bytes, errs], where rd indicates read, wr indicates write, req is
177+ the total number of I/O requests made, bytes is the total number of
178+ bytes transferred, and errs is the number of requests held up due to a
179+ full pipeline.
180+
181+ All counters are long integers.
182+
183+ This method is optional. On some platforms (e.g. XenAPI) performance
184+ statistics can be retrieved directly in aggregate form, without Nova
185+ having to do the aggregation. On those platforms, this method is
186+ unused.
187+
188+ Note that this function takes an instance ID, not a
189+ compute.service.Instance, so that it can be called by compute.monitor.
190+ """
191 return [0L, 0L, 0L, 0L, null]
192
193 def interface_stats(self, instance_id, iface_id):
194+ """
195+ Return performance counters associated with the given iface_id on the
196+ given instance_id. These are returned as [rx_bytes, rx_packets,
197+ rx_errs, rx_drop, tx_bytes, tx_packets, tx_errs, tx_drop], where rx
198+ indicates receive, tx indicates transmit, bytes and packets indicate
199+ the total number of bytes or packets transferred, and errs and dropped
200+ is the total number of packets failed / dropped.
201+
202+ All counters are long integers.
203+
204+ This method is optional. On some platforms (e.g. XenAPI) performance
205+ statistics can be retrieved directly in aggregate form, without Nova
206+ having to do the aggregation. On those platforms, this method is
207+ unused.
208+
209+ Note that this function takes an instance ID, not a
210+ compute.service.Instance, so that it can be called by compute.monitor.
211+ """
212 return [0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L]
213
214
215
216=== modified file 'nova/virt/libvirt_conn.py'
217--- nova/virt/libvirt_conn.py 2010-08-10 15:37:07 +0000
218+++ nova/virt/libvirt_conn.py 2010-08-13 13:39:41 +0000
219@@ -261,12 +261,6 @@
220
221
222 def get_disks(self, instance_id):
223- """
224- Note that this function takes an instance ID, not an Instance, so
225- that it can be called by monitor.
226-
227- Returns a list of all block devices for this domain.
228- """
229 domain = self._conn.lookupByName(instance_id)
230 # TODO(devcamcar): Replace libxml2 with etree.
231 xml = domain.XMLDesc(0)
232@@ -304,12 +298,6 @@
233
234
235 def get_interfaces(self, instance_id):
236- """
237- Note that this function takes an instance ID, not an Instance, so
238- that it can be called by monitor.
239-
240- Returns a list of all network interfaces for this instance.
241- """
242 domain = self._conn.lookupByName(instance_id)
243 # TODO(devcamcar): Replace libxml2 with etree.
244 xml = domain.XMLDesc(0)
245@@ -347,18 +335,10 @@
246
247
248 def block_stats(self, instance_id, disk):
249- """
250- Note that this function takes an instance ID, not an Instance, so
251- that it can be called by monitor.
252- """
253 domain = self._conn.lookupByName(instance_id)
254 return domain.blockStats(disk)
255
256
257 def interface_stats(self, instance_id, interface):
258- """
259- Note that this function takes an instance ID, not an Instance, so
260- that it can be called by monitor.
261- """
262 domain = self._conn.lookupByName(instance_id)
263 return domain.interfaceStats(interface)
264
265=== modified file 'plugins/xenapi/README'
266--- plugins/xenapi/README 2010-08-02 23:52:06 +0000
267+++ plugins/xenapi/README 2010-08-13 13:39:41 +0000
268@@ -1,2 +1,6 @@
269 This directory contains files that are required for the XenAPI support. They
270 should be installed in the XenServer / Xen Cloud Platform domain 0.
271+
272+Also, you need to
273+
274+chmod u+x /etc/xapi.d/plugins/objectstore