Merge with trunk

This commit is contained in:
Johannes Erdfelt 2011-05-16 18:14:03 +00:00
commit 674acd025b
12 changed files with 179 additions and 135 deletions

View File

@ -29,6 +29,7 @@
<matt.dietz@rackspace.com> <matthewdietz@Matthew-Dietzs-MacBook-Pro.local>
<matt.dietz@rackspace.com> <mdietz@openstack>
<mordred@inaugust.com> <mordred@hudson>
<naveedm9@gmail.com> <naveed.massjouni@rackspace.com>
<nirmal.ranganathan@rackspace.com> <nirmal.ranganathan@rackspace.coom>
<paul@openstack.org> <paul.voccio@rackspace.com>
<paul@openstack.org> <pvoccio@castor.local>
@ -36,6 +37,7 @@
<rlane@wikimedia.org> <laner@controller>
<sleepsonthefloor@gmail.com> <root@tonbuntu>
<soren.hansen@rackspace.com> <soren@linux2go.dk>
<throughnothing@gmail.com> <will.wolf@rackspace.com>
<todd@ansolabs.com> <todd@lapex>
<todd@ansolabs.com> <todd@rubidine.com>
<tushar.vitthal.patil@gmail.com> <tpatil@vertex.co.in>
@ -44,5 +46,4 @@
<ueno.nachi@lab.ntt.co.jp> <openstack@lab.ntt.co.jp>
<vishvananda@gmail.com> <root@mirror.nasanebula.net>
<vishvananda@gmail.com> <root@ubuntu>
<naveedm9@gmail.com> <naveed.massjouni@rackspace.com>
<vishvananda@gmail.com> <vishvananda@yahoo.com>

View File

@ -80,7 +80,7 @@ Trey Morris <trey.morris@rackspace.com>
Tushar Patil <tushar.vitthal.patil@gmail.com>
Vasiliy Shlykov <vash@vasiliyshlykov.org>
Vishvananda Ishaya <vishvananda@gmail.com>
William Wolf <will.wolf@rackspace.com>
William Wolf <throughnothing@gmail.com>
Yoshiaki Tamura <yoshi@midokura.jp>
Youcef Laribi <Youcef.Laribi@eu.citrix.com>
Yuriy Taraday <yorik.sar@gmail.com>

View File

@ -19,6 +19,7 @@
"""Handles all requests relating to instances (guest vms)."""
import datetime
import eventlet
import re
import time
@ -42,6 +43,8 @@ LOG = logging.getLogger('nova.compute.api')
FLAGS = flags.FLAGS
flags.DECLARE('vncproxy_topic', 'nova.vnc')
flags.DEFINE_integer('find_host_timeout', 30,
'Timeout after NN seconds when looking for a host.')
def generate_default_hostname(instance_id):
@ -484,7 +487,7 @@ class API(base.Base):
def _find_host(self, context, instance_id):
"""Find the host associated with an instance."""
for attempts in xrange(10):
for attempts in xrange(FLAGS.find_host_timeout):
instance = self.get(context, instance_id)
host = instance["host"]
if host:
@ -493,6 +496,15 @@ class API(base.Base):
raise exception.Error(_("Unable to find host for Instance %s")
% instance_id)
def _set_admin_password(self, context, instance_id, password):
"""Set the root/admin password for the given instance."""
host = self._find_host(context, instance_id)
rpc.cast(context,
self.db.queue_get_for(context, FLAGS.compute_topic, host),
{"method": "set_admin_password",
"args": {"instance_id": instance_id, "new_pass": password}})
def snapshot(self, context, instance_id, name):
"""Snapshot the given instance.
@ -646,12 +658,8 @@ class API(base.Base):
def set_admin_password(self, context, instance_id, password=None):
"""Set the root/admin password for the given instance."""
host = self._find_host(context, instance_id)
rpc.cast(context,
self.db.queue_get_for(context, FLAGS.compute_topic, host),
{"method": "set_admin_password",
"args": {"instance_id": instance_id, "new_pass": password}})
eventlet.spawn_n(self._set_admin_password(context, instance_id,
password))
def inject_file(self, context, instance_id):
"""Write a file to the given instance."""

View File

@ -77,7 +77,8 @@ flags.DEFINE_integer("rescue_timeout", 0,
" Set to 0 to disable.")
flags.DEFINE_bool('auto_assign_floating_ip', False,
'Autoassigning floating ip to VM')
flags.DEFINE_integer('host_state_interval', 120,
'Interval in seconds for querying the host status')
LOG = logging.getLogger('nova.compute.manager')
@ -426,6 +427,12 @@ class ComputeManager(manager.SchedulerDependentManager):
LOG.audit(_("Instance %s: Root password set"),
instance_ref["name"])
break
except NotImplementedError:
# NOTE(dprince): if the driver doesn't implement
# set_admin_password we break to avoid a loop
LOG.warn(_('set_admin_password is not implemented '
'by this driver.'))
break
except Exception, e:
# Catch all here because this could be anything.
LOG.exception(e)

View File

@ -183,7 +183,7 @@ class ServersTest(test.TestCase):
self.assertEqual(res_dict['server']['id'], 1)
self.assertEqual(res_dict['server']['name'], 'server1')
def test_get_server_by_id_v11(self):
def test_get_server_by_id_v1_1(self):
req = webob.Request.blank('/v1.1/servers/1')
res = req.get_response(fakes.wsgi_app())
res_dict = json.loads(res.body)
@ -246,7 +246,7 @@ class ServersTest(test.TestCase):
self.assertEqual(len(addresses["private"]), 1)
self.assertEqual(addresses["private"][0], private)
def test_get_server_addresses_V10(self):
def test_get_server_addresses_v1_0(self):
private = '192.168.0.3'
public = ['1.2.3.4']
new_return_server = return_server_with_addresses(private, public)
@ -257,7 +257,7 @@ class ServersTest(test.TestCase):
self.assertEqual(res_dict, {
'addresses': {'public': public, 'private': [private]}})
def test_get_server_addresses_xml_V10(self):
def test_get_server_addresses_xml_v1_0(self):
private_expected = "192.168.0.3"
public_expected = ["1.2.3.4"]
new_return_server = return_server_with_addresses(private_expected,
@ -276,7 +276,7 @@ class ServersTest(test.TestCase):
(ip,) = private.getElementsByTagName('ip')
self.assertEquals(ip.getAttribute('addr'), private_expected)
def test_get_server_addresses_public_V10(self):
def test_get_server_addresses_public_v1_0(self):
private = "192.168.0.3"
public = ["1.2.3.4"]
new_return_server = return_server_with_addresses(private, public)
@ -286,7 +286,7 @@ class ServersTest(test.TestCase):
res_dict = json.loads(res.body)
self.assertEqual(res_dict, {'public': public})
def test_get_server_addresses_private_V10(self):
def test_get_server_addresses_private_v1_0(self):
private = "192.168.0.3"
public = ["1.2.3.4"]
new_return_server = return_server_with_addresses(private, public)
@ -296,7 +296,7 @@ class ServersTest(test.TestCase):
res_dict = json.loads(res.body)
self.assertEqual(res_dict, {'private': [private]})
def test_get_server_addresses_public_xml_V10(self):
def test_get_server_addresses_public_xml_v1_0(self):
private = "192.168.0.3"
public = ["1.2.3.4"]
new_return_server = return_server_with_addresses(private, public)
@ -310,7 +310,7 @@ class ServersTest(test.TestCase):
(ip,) = public_node.getElementsByTagName('ip')
self.assertEquals(ip.getAttribute('addr'), public[0])
def test_get_server_addresses_private_xml_V10(self):
def test_get_server_addresses_private_xml_v1_0(self):
private = "192.168.0.3"
public = ["1.2.3.4"]
new_return_server = return_server_with_addresses(private, public)
@ -324,7 +324,7 @@ class ServersTest(test.TestCase):
(ip,) = private_node.getElementsByTagName('ip')
self.assertEquals(ip.getAttribute('addr'), private)
def test_get_server_by_id_with_addresses_v11(self):
def test_get_server_by_id_with_addresses_v1_1(self):
private = "192.168.0.3"
public = ["1.2.3.4"]
new_return_server = return_server_with_addresses(private, public)
@ -354,7 +354,7 @@ class ServersTest(test.TestCase):
self.assertEqual(s.get('imageId', None), None)
i += 1
def test_get_server_list_v11(self):
def test_get_server_list_v1_1(self):
req = webob.Request.blank('/v1.1/servers')
res = req.get_response(fakes.wsgi_app())
res_dict = json.loads(res.body)
@ -576,16 +576,16 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 400)
def test_create_instance_v11(self):
def test_create_instance_v1_1(self):
self._setup_for_create_instance()
imageRef = 'http://localhost/v1.1/images/2'
flavorRef = 'http://localhost/v1.1/flavors/3'
image_ref = 'http://localhost/v1.1/images/2'
flavor_ref = 'http://localhost/v1.1/flavors/3'
body = {
'server': {
'name': 'server_test',
'imageRef': imageRef,
'flavorRef': flavorRef,
'imageRef': image_ref,
'flavorRef': flavor_ref,
'metadata': {
'hello': 'world',
'open': 'stack',
@ -605,17 +605,17 @@ class ServersTest(test.TestCase):
self.assertEqual(16, len(server['adminPass']))
self.assertEqual('server_test', server['name'])
self.assertEqual(1, server['id'])
self.assertEqual(flavorRef, server['flavorRef'])
self.assertEqual(imageRef, server['imageRef'])
self.assertEqual(flavor_ref, server['flavorRef'])
self.assertEqual(image_ref, server['imageRef'])
self.assertEqual(res.status_int, 200)
def test_create_instance_v11_bad_href(self):
def test_create_instance_v1_1_bad_href(self):
self._setup_for_create_instance()
imageRef = 'http://localhost/v1.1/images/asdf'
flavorRef = 'http://localhost/v1.1/flavors/3'
image_ref = 'http://localhost/v1.1/images/asdf'
flavor_ref = 'http://localhost/v1.1/flavors/3'
body = dict(server=dict(
name='server_test', imageRef=imageRef, flavorRef=flavorRef,
name='server_test', imageRef=image_ref, flavorRef=flavor_ref,
metadata={'hello': 'world', 'open': 'stack'},
personality={}))
req = webob.Request.blank('/v1.1/servers')
@ -625,17 +625,17 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 400)
def test_create_instance_v11_local_href(self):
def test_create_instance_v1_1_local_href(self):
self._setup_for_create_instance()
imageRef = 'http://localhost/v1.1/images/2'
imageRefLocal = '2'
flavorRef = 'http://localhost/v1.1/flavors/3'
image_ref = 'http://localhost/v1.1/images/2'
image_ref_local = '2'
flavor_ref = 'http://localhost/v1.1/flavors/3'
body = {
'server': {
'name': 'server_test',
'imageRef': imageRefLocal,
'flavorRef': flavorRef,
'imageRef': image_ref_local,
'flavorRef': flavor_ref,
},
}
@ -648,11 +648,11 @@ class ServersTest(test.TestCase):
server = json.loads(res.body)['server']
self.assertEqual(1, server['id'])
self.assertEqual(flavorRef, server['flavorRef'])
self.assertEqual(imageRef, server['imageRef'])
self.assertEqual(flavor_ref, server['flavorRef'])
self.assertEqual(image_ref, server['imageRef'])
self.assertEqual(res.status_int, 200)
def test_create_instance_with_admin_pass_v10(self):
def test_create_instance_with_admin_pass_v1_0(self):
self._setup_for_create_instance()
body = {
@ -673,16 +673,16 @@ class ServersTest(test.TestCase):
self.assertNotEqual(res['server']['adminPass'],
body['server']['adminPass'])
def test_create_instance_with_admin_pass_v11(self):
def test_create_instance_with_admin_pass_v1_1(self):
self._setup_for_create_instance()
imageRef = 'http://localhost/v1.1/images/2'
flavorRef = 'http://localhost/v1.1/flavors/3'
image_ref = 'http://localhost/v1.1/images/2'
flavor_ref = 'http://localhost/v1.1/flavors/3'
body = {
'server': {
'name': 'server_test',
'imageRef': imageRef,
'flavorRef': flavorRef,
'imageRef': image_ref,
'flavorRef': flavor_ref,
'adminPass': 'testpass',
},
}
@ -695,16 +695,16 @@ class ServersTest(test.TestCase):
server = json.loads(res.body)['server']
self.assertEqual(server['adminPass'], body['server']['adminPass'])
def test_create_instance_with_empty_admin_pass_v11(self):
def test_create_instance_with_empty_admin_pass_v1_1(self):
self._setup_for_create_instance()
imageRef = 'http://localhost/v1.1/images/2'
flavorRef = 'http://localhost/v1.1/flavors/3'
image_ref = 'http://localhost/v1.1/images/2'
flavor_ref = 'http://localhost/v1.1/flavors/3'
body = {
'server': {
'name': 'server_test',
'imageRef': imageRef,
'flavorRef': flavorRef,
'imageRef': image_ref,
'flavorRef': flavor_ref,
'adminPass': '',
},
}
@ -758,7 +758,7 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 400)
def test_update_server_v10(self):
def test_update_server_v1_0(self):
inst_dict = dict(name='server_test', adminPass='bacon')
self.body = json.dumps(dict(server=inst_dict))
@ -781,7 +781,7 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 204)
def test_update_server_adminPass_ignored_v11(self):
def test_update_server_adminPass_ignored_v1_1(self):
inst_dict = dict(name='server_test', adminPass='bacon')
self.body = json.dumps(dict(server=inst_dict))
@ -822,7 +822,7 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 501)
def test_server_backup_schedule_deprecated_v11(self):
def test_server_backup_schedule_deprecated_v1_1(self):
req = webob.Request.blank('/v1.1/servers/1/backup_schedule')
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 404)
@ -1113,7 +1113,7 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 400)
def test_server_rebuild_accepted_minimum_v11(self):
def test_server_rebuild_accepted_minimum_v1_1(self):
body = {
"rebuild": {
"imageRef": "http://localhost/images/2",
@ -1128,7 +1128,7 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 202)
def test_server_rebuild_rejected_when_building_v11(self):
def test_server_rebuild_rejected_when_building_v1_1(self):
body = {
"rebuild": {
"imageRef": "http://localhost/images/2",
@ -1147,7 +1147,7 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 409)
def test_server_rebuild_accepted_with_metadata_v11(self):
def test_server_rebuild_accepted_with_metadata_v1_1(self):
body = {
"rebuild": {
"imageRef": "http://localhost/images/2",
@ -1165,7 +1165,7 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 202)
def test_server_rebuild_accepted_with_bad_metadata_v11(self):
def test_server_rebuild_accepted_with_bad_metadata_v1_1(self):
body = {
"rebuild": {
"imageRef": "http://localhost/images/2",
@ -1181,7 +1181,7 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 400)
def test_server_rebuild_bad_entity_v11(self):
def test_server_rebuild_bad_entity_v1_1(self):
body = {
"rebuild": {
"imageId": 2,
@ -1196,7 +1196,7 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 400)
def test_server_rebuild_bad_personality_v11(self):
def test_server_rebuild_bad_personality_v1_1(self):
body = {
"rebuild": {
"imageRef": "http://localhost/images/2",
@ -1215,7 +1215,7 @@ class ServersTest(test.TestCase):
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 400)
def test_server_rebuild_personality_v11(self):
def test_server_rebuild_personality_v1_1(self):
body = {
"rebuild": {
"imageRef": "http://localhost/images/2",

View File

@ -279,6 +279,26 @@ class CloudTestCase(test.TestCase):
user_group=['all'])
self.assertEqual(True, result['is_public'])
def test_deregister_image(self):
deregister_image = self.cloud.deregister_image
def fake_delete(self, context, id):
return None
self.stubs.Set(local.LocalImageService, 'delete', fake_delete)
# valid image
result = deregister_image(self.context, 'ami-00000001')
self.assertEqual(result['imageId'], 'ami-00000001')
# invalid image
self.stubs.UnsetAll()
def fake_detail_empty(self, context):
return []
self.stubs.Set(local.LocalImageService, 'detail', fake_detail_empty)
self.assertRaises(exception.ImageNotFound, deregister_image,
self.context, 'ami-bad001')
def test_console_output(self):
instance_type = FLAGS.default_instance_type
max_count = 1

View File

@ -16,6 +16,7 @@
"""Test suite for XenAPI."""
import eventlet
import functools
import json
import os
@ -198,6 +199,28 @@ class XenAPIVMTestCase(test.TestCase):
self.context = context.RequestContext('fake', 'fake', False)
self.conn = xenapi_conn.get_connection(False)
def test_parallel_builds(self):
stubs.stubout_loopingcall_delay(self.stubs)
def _do_build(id, proj, user, *args):
values = {
'id': id,
'project_id': proj,
'user_id': user,
'image_id': 1,
'kernel_id': 2,
'ramdisk_id': 3,
'instance_type_id': '3', # m1.large
'mac_address': 'aa:bb:cc:dd:ee:ff',
'os_type': 'linux'}
instance = db.instance_create(self.context, values)
self.conn.spawn(instance)
gt1 = eventlet.spawn(_do_build, 1, self.project.id, self.user.id)
gt2 = eventlet.spawn(_do_build, 2, self.project.id, self.user.id)
gt1.wait()
gt2.wait()
def test_list_instances_0(self):
instances = self.conn.list_instances()
self.assertEquals(instances, [])

View File

@ -16,6 +16,7 @@
"""Stubouts, mocks and fixtures for the test suite"""
import eventlet
from nova.virt import xenapi_conn
from nova.virt.xenapi import fake
from nova.virt.xenapi import volume_utils
@ -28,29 +29,6 @@ def stubout_instance_snapshot(stubs):
@classmethod
def fake_fetch_image(cls, session, instance_id, image, user, project,
type):
# Stubout wait_for_task
def fake_wait_for_task(self, task, id):
class FakeEvent:
def send(self, value):
self.rv = value
def wait(self):
return self.rv
done = FakeEvent()
self._poll_task(id, task, done)
rv = done.wait()
return rv
def fake_loop(self):
pass
stubs.Set(xenapi_conn.XenAPISession, 'wait_for_task',
fake_wait_for_task)
stubs.Set(xenapi_conn.XenAPISession, '_stop_loop', fake_loop)
from nova.virt.xenapi.fake import create_vdi
name_label = "instance-%s" % instance_id
#TODO: create fake SR record
@ -63,11 +41,6 @@ def stubout_instance_snapshot(stubs):
stubs.Set(vm_utils.VMHelper, 'fetch_image', fake_fetch_image)
def fake_parse_xmlrpc_value(val):
return val
stubs.Set(xenapi_conn, '_parse_xmlrpc_value', fake_parse_xmlrpc_value)
def fake_wait_for_vhd_coalesce(session, instance_id, sr_ref, vdi_ref,
original_parent_uuid):
from nova.virt.xenapi.fake import create_vdi
@ -144,6 +117,16 @@ def stubout_loopingcall_start(stubs):
stubs.Set(utils.LoopingCall, 'start', fake_start)
def stubout_loopingcall_delay(stubs):
def fake_start(self, interval, now=True):
self._running = True
eventlet.sleep(1)
self.f(*self.args, **self.kw)
# This would fail before parallel xenapi calls were fixed
assert self._running == False
stubs.Set(utils.LoopingCall, 'start', fake_start)
class FakeSessionForVMTests(fake.SessionBase):
""" Stubs out a XenAPISession for VM tests """
def __init__(self, uri):

View File

@ -442,6 +442,8 @@ class LoopingCall(object):
try:
while self._running:
self.f(*self.args, **self.kw)
if not self._running:
break
greenthread.sleep(interval)
except LoopingCallDone, e:
self.stop()

View File

@ -347,7 +347,6 @@ class XenAPISession(object):
"(is the Dom0 disk full?)"))
with timeout.Timeout(FLAGS.xenapi_login_timeout, exception):
self._session.login_with_password(user, pw)
self.loop = None
def get_imported_xenapi(self):
"""Stubout point. This can be replaced with a mock xenapi module."""
@ -384,57 +383,52 @@ class XenAPISession(object):
def wait_for_task(self, task, id=None):
"""Return the result of the given task. The task is polled
until it completes. Not re-entrant."""
until it completes."""
done = event.Event()
self.loop = utils.LoopingCall(self._poll_task, id, task, done)
self.loop.start(FLAGS.xenapi_task_poll_interval, now=True)
rv = done.wait()
self.loop.stop()
return rv
loop = utils.LoopingCall(f=None)
def _stop_loop(self):
"""Stop polling for task to finish."""
#NOTE(sandy-walsh) Had to break this call out to support unit tests.
if self.loop:
self.loop.stop()
def _poll_task():
"""Poll the given XenAPI task, and return the result if the
action was completed successfully or not.
"""
try:
name = self._session.xenapi.task.get_name_label(task)
status = self._session.xenapi.task.get_status(task)
if id:
action = dict(
instance_id=int(id),
action=name[0:255], # Ensure action is never > 255
error=None)
if status == "pending":
return
elif status == "success":
result = self._session.xenapi.task.get_result(task)
LOG.info(_("Task [%(name)s] %(task)s status:"
" success %(result)s") % locals())
done.send(_parse_xmlrpc_value(result))
else:
error_info = self._session.xenapi.task.get_error_info(task)
action["error"] = str(error_info)
LOG.warn(_("Task [%(name)s] %(task)s status:"
" %(status)s %(error_info)s") % locals())
done.send_exception(self.XenAPI.Failure(error_info))
if id:
db.instance_action_create(context.get_admin_context(),
action)
except self.XenAPI.Failure, exc:
LOG.warn(exc)
done.send_exception(*sys.exc_info())
loop.stop()
loop.f = _poll_task
loop.start(FLAGS.xenapi_task_poll_interval, now=True)
return done.wait()
def _create_session(self, url):
"""Stubout point. This can be replaced with a mock session."""
return self.XenAPI.Session(url)
def _poll_task(self, id, task, done):
"""Poll the given XenAPI task, and fire the given action if we
get a result.
"""
try:
name = self._session.xenapi.task.get_name_label(task)
status = self._session.xenapi.task.get_status(task)
if id:
action = dict(
instance_id=int(id),
action=name[0:255], # Ensure action is never > 255
error=None)
if status == "pending":
return
elif status == "success":
result = self._session.xenapi.task.get_result(task)
LOG.info(_("Task [%(name)s] %(task)s status:"
" success %(result)s") % locals())
done.send(_parse_xmlrpc_value(result))
else:
error_info = self._session.xenapi.task.get_error_info(task)
action["error"] = str(error_info)
LOG.warn(_("Task [%(name)s] %(task)s status:"
" %(status)s %(error_info)s") % locals())
done.send_exception(self.XenAPI.Failure(error_info))
if id:
db.instance_action_create(context.get_admin_context(), action)
except self.XenAPI.Failure, exc:
LOG.warn(exc)
done.send_exception(*sys.exc_info())
self._stop_loop()
def _unwrap_plugin_exceptions(self, func, *args, **kwargs):
"""Parse exception details"""
try:

View File

@ -1,3 +1,4 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
@ -31,11 +32,15 @@ ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
VENV = os.path.join(ROOT, '.nova-venv')
PIP_REQUIRES = os.path.join(ROOT, 'tools', 'pip-requires')
TWISTED_NOVA='http://nova.openstack.org/Twisted-10.0.0Nova.tar.gz'
PY_VERSION = "python" + str(sys.version_info[0]) + '.' + str(sys.version_info[1])
def die(message, *args):
print >>sys.stderr, message % args
sys.exit(1)
def check_python_version():
if sys.version_info < (2, 6):
die("Need Python Version >= 2.6")
def run_command(cmd, redirect_output=True, check_exit_code=True):
"""
@ -100,12 +105,12 @@ def install_dependencies(venv=VENV):
# Tell the virtual env how to "import nova"
pthfile = os.path.join(venv, "lib", "python2.6", "site-packages", "nova.pth")
pthfile = os.path.join(venv, "lib", PY_VERSION, "site-packages", "nova.pth")
f = open(pthfile, 'w')
f.write("%s\n" % ROOT)
# Patch eventlet (see FAQ # 1485)
patchsrc = os.path.join(ROOT, 'tools', 'eventlet-patch')
patchfile = os.path.join(venv, "lib", "python2.6", "site-packages", "eventlet",
patchfile = os.path.join(venv, "lib", PY_VERSION, "site-packages", "eventlet",
"green", "subprocess.py")
patch_cmd = "patch %s %s" % (patchfile, patchsrc)
os.system(patch_cmd)
@ -134,6 +139,7 @@ def print_help():
def main(argv):
check_python_version()
check_dependencies()
create_virtualenv()
install_dependencies()

View File

@ -2,7 +2,7 @@ SQLAlchemy==0.6.3
pep8==0.5.0
pylint==0.19
IPy==0.70
Cheetah==2.4.2.1
Cheetah==2.4.4
M2Crypto==0.20.2
amqplib==0.6.1
anyjson==0.2.4