changed from 003-004 migration
This commit is contained in:
49
.mailmap
49
.mailmap
@@ -1,36 +1,43 @@
|
|||||||
# Format is:
|
# Format is:
|
||||||
# <preferred e-mail> <other e-mail>
|
# <preferred e-mail> <other e-mail 1>
|
||||||
<code@term.ie> <github@anarkystic.com>
|
# <preferred e-mail> <other e-mail 2>
|
||||||
<code@term.ie> <termie@preciousroy.local>
|
|
||||||
<Armando.Migliaccio@eu.citrix.com> <armando.migliaccio@citrix.com>
|
|
||||||
<matt.dietz@rackspace.com> <matthewdietz@Matthew-Dietzs-MacBook-Pro.local>
|
|
||||||
<matt.dietz@rackspace.com> <mdietz@openstack>
|
|
||||||
<cbehrens@codestud.com> <chris.behrens@rackspace.com>
|
|
||||||
<devin.carlen@gmail.com> <devcamcar@illian.local>
|
|
||||||
<ewan.mellor@citrix.com> <emellor@silver>
|
|
||||||
<jaypipes@gmail.com> <jpipes@serialcoder>
|
|
||||||
<anotherjesse@gmail.com> <jesse@dancelamb>
|
<anotherjesse@gmail.com> <jesse@dancelamb>
|
||||||
<anotherjesse@gmail.com> <jesse@gigantor.local>
|
<anotherjesse@gmail.com> <jesse@gigantor.local>
|
||||||
<anotherjesse@gmail.com> <jesse@ubuntu>
|
<anotherjesse@gmail.com> <jesse@ubuntu>
|
||||||
<jmckenty@gmail.com> <jmckenty@yyj-dhcp171.corp.flock.com>
|
<ant@openstack.org> <amesserl@rackspace.com>
|
||||||
|
<Armando.Migliaccio@eu.citrix.com> <armando.migliaccio@citrix.com>
|
||||||
|
<brian.lamar@rackspace.com> <brian.lamar@gmail.com>
|
||||||
|
<bschott@isi.edu> <bfschott@gmail.com>
|
||||||
|
<cbehrens@codestud.com> <chris.behrens@rackspace.com>
|
||||||
|
<chiradeep@cloud.com> <chiradeep@chiradeep-lt2>
|
||||||
|
<code@term.ie> <github@anarkystic.com>
|
||||||
|
<code@term.ie> <termie@preciousroy.local>
|
||||||
|
<corywright@gmail.com> <cory.wright@rackspace.com>
|
||||||
|
<devin.carlen@gmail.com> <devcamcar@illian.local>
|
||||||
|
<ewan.mellor@citrix.com> <emellor@silver>
|
||||||
|
<jaypipes@gmail.com> <jpipes@serialcoder>
|
||||||
<jmckenty@gmail.com> <jmckenty@joshua-mckentys-macbook-pro.local>
|
<jmckenty@gmail.com> <jmckenty@joshua-mckentys-macbook-pro.local>
|
||||||
|
<jmckenty@gmail.com> <jmckenty@yyj-dhcp171.corp.flock.com>
|
||||||
<jmckenty@gmail.com> <joshua.mckenty@nasa.gov>
|
<jmckenty@gmail.com> <joshua.mckenty@nasa.gov>
|
||||||
<justin@fathomdb.com> <justinsb@justinsb-desktop>
|
<justin@fathomdb.com> <justinsb@justinsb-desktop>
|
||||||
<masumotok@nttdata.co.jp> <root@openstack2-api>
|
<justin@fathomdb.com> <superstack@superstack.org>
|
||||||
<masumotok@nttdata.co.jp> Masumoto<masumotok@nttdata.co.jp>
|
<masumotok@nttdata.co.jp> Masumoto<masumotok@nttdata.co.jp>
|
||||||
|
<masumotok@nttdata.co.jp> <root@openstack2-api>
|
||||||
|
<matt.dietz@rackspace.com> <matthewdietz@Matthew-Dietzs-MacBook-Pro.local>
|
||||||
|
<matt.dietz@rackspace.com> <mdietz@openstack>
|
||||||
<mordred@inaugust.com> <mordred@hudson>
|
<mordred@inaugust.com> <mordred@hudson>
|
||||||
<paul@openstack.org> <pvoccio@castor.local>
|
|
||||||
<paul@openstack.org> <paul.voccio@rackspace.com>
|
<paul@openstack.org> <paul.voccio@rackspace.com>
|
||||||
|
<paul@openstack.org> <pvoccio@castor.local>
|
||||||
|
<rconradharris@gmail.com> <rick.harris@rackspace.com>
|
||||||
|
<rlane@wikimedia.org> <laner@controller>
|
||||||
|
<sleepsonthefloor@gmail.com> <root@tonbuntu>
|
||||||
<soren.hansen@rackspace.com> <soren@linux2go.dk>
|
<soren.hansen@rackspace.com> <soren@linux2go.dk>
|
||||||
<todd@ansolabs.com> <todd@lapex>
|
<todd@ansolabs.com> <todd@lapex>
|
||||||
<todd@ansolabs.com> <todd@rubidine.com>
|
<todd@ansolabs.com> <todd@rubidine.com>
|
||||||
<vishvananda@gmail.com> <vishvananda@yahoo.com>
|
<tushar.vitthal.patil@gmail.com> <tpatil@vertex.co.in>
|
||||||
|
<ueno.nachi@lab.ntt.co.jp> <nati.ueno@gmail.com>
|
||||||
|
<ueno.nachi@lab.ntt.co.jp> <nova@u4>
|
||||||
|
<ueno.nachi@lab.ntt.co.jp> <openstack@lab.ntt.co.jp>
|
||||||
<vishvananda@gmail.com> <root@mirror.nasanebula.net>
|
<vishvananda@gmail.com> <root@mirror.nasanebula.net>
|
||||||
<vishvananda@gmail.com> <root@ubuntu>
|
<vishvananda@gmail.com> <root@ubuntu>
|
||||||
<sleepsonthefloor@gmail.com> <root@tonbuntu>
|
<vishvananda@gmail.com> <vishvananda@yahoo.com>
|
||||||
<rlane@wikimedia.org> <laner@controller>
|
|
||||||
<rconradharris@gmail.com> <rick.harris@rackspace.com>
|
|
||||||
<corywright@gmail.com> <cory.wright@rackspace.com>
|
|
||||||
<ant@openstack.org> <amesserl@rackspace.com>
|
|
||||||
<chiradeep@cloud.com> <chiradeep@chiradeep-lt2>
|
|
||||||
<justin@fathomdb.com> <superstack@superstack.org>
|
|
||||||
|
11
Authors
11
Authors
@@ -4,13 +4,16 @@ Anthony Young <sleepsonthefloor@gmail.com>
|
|||||||
Antony Messerli <ant@openstack.org>
|
Antony Messerli <ant@openstack.org>
|
||||||
Armando Migliaccio <Armando.Migliaccio@eu.citrix.com>
|
Armando Migliaccio <Armando.Migliaccio@eu.citrix.com>
|
||||||
Bilal Akhtar <bilalakhtar@ubuntu.com>
|
Bilal Akhtar <bilalakhtar@ubuntu.com>
|
||||||
|
Brian Lamar <brian.lamar@rackspace.com>
|
||||||
|
Brian Schott <bschott@isi.edu>
|
||||||
|
Brian Waldon <brian.waldon@rackspace.com>
|
||||||
Chiradeep Vittal <chiradeep@cloud.com>
|
Chiradeep Vittal <chiradeep@cloud.com>
|
||||||
Chmouel Boudjnah <chmouel@chmouel.com>
|
Chmouel Boudjnah <chmouel@chmouel.com>
|
||||||
Chris Behrens <cbehrens@codestud.com>
|
Chris Behrens <cbehrens@codestud.com>
|
||||||
Christian Berendt <berendt@b1-systems.de>
|
Christian Berendt <berendt@b1-systems.de>
|
||||||
Cory Wright <corywright@gmail.com>
|
Cory Wright <corywright@gmail.com>
|
||||||
David Pravec <David.Pravec@danix.org>
|
|
||||||
Dan Prince <dan.prince@rackspace.com>
|
Dan Prince <dan.prince@rackspace.com>
|
||||||
|
David Pravec <David.Pravec@danix.org>
|
||||||
Dean Troyer <dtroyer@gmail.com>
|
Dean Troyer <dtroyer@gmail.com>
|
||||||
Devin Carlen <devin.carlen@gmail.com>
|
Devin Carlen <devin.carlen@gmail.com>
|
||||||
Ed Leafe <ed@leafe.com>
|
Ed Leafe <ed@leafe.com>
|
||||||
@@ -41,7 +44,8 @@ Monsyne Dragon <mdragon@rackspace.com>
|
|||||||
Monty Taylor <mordred@inaugust.com>
|
Monty Taylor <mordred@inaugust.com>
|
||||||
MORITA Kazutaka <morita.kazutaka@gmail.com>
|
MORITA Kazutaka <morita.kazutaka@gmail.com>
|
||||||
Muneyuki Noguchi <noguchimn@nttdata.co.jp>
|
Muneyuki Noguchi <noguchimn@nttdata.co.jp>
|
||||||
Nachi Ueno <ueno.nachi@lab.ntt.co.jp> <openstack@lab.ntt.co.jp> <nati.ueno@gmail.com> <nova@u4>
|
Nachi Ueno <ueno.nachi@lab.ntt.co.jp>
|
||||||
|
Naveed Massjouni <naveed.massjouni@rackspace.com>
|
||||||
Paul Voccio <paul@openstack.org>
|
Paul Voccio <paul@openstack.org>
|
||||||
Ricardo Carrillo Cruz <emaildericky@gmail.com>
|
Ricardo Carrillo Cruz <emaildericky@gmail.com>
|
||||||
Rick Clark <rick@openstack.org>
|
Rick Clark <rick@openstack.org>
|
||||||
@@ -55,7 +59,8 @@ Soren Hansen <soren.hansen@rackspace.com>
|
|||||||
Thierry Carrez <thierry@openstack.org>
|
Thierry Carrez <thierry@openstack.org>
|
||||||
Todd Willey <todd@ansolabs.com>
|
Todd Willey <todd@ansolabs.com>
|
||||||
Trey Morris <trey.morris@rackspace.com>
|
Trey Morris <trey.morris@rackspace.com>
|
||||||
Tushar Patil <tushar.vitthal.patil@gmail.com> <tpatil@vertex.co.in>
|
Tushar Patil <tushar.vitthal.patil@gmail.com>
|
||||||
|
Vasiliy Shlykov <vash@vasiliyshlykov.org>
|
||||||
Vishvananda Ishaya <vishvananda@gmail.com>
|
Vishvananda Ishaya <vishvananda@gmail.com>
|
||||||
Youcef Laribi <Youcef.Laribi@eu.citrix.com>
|
Youcef Laribi <Youcef.Laribi@eu.citrix.com>
|
||||||
Zhixue Wu <Zhixue.Wu@citrix.com>
|
Zhixue Wu <Zhixue.Wu@citrix.com>
|
||||||
|
19
HACKING
19
HACKING
@@ -47,3 +47,22 @@ Human Alphabetical Order Examples
|
|||||||
from nova.auth import users
|
from nova.auth import users
|
||||||
from nova.endpoint import api
|
from nova.endpoint import api
|
||||||
from nova.endpoint import cloud
|
from nova.endpoint import cloud
|
||||||
|
|
||||||
|
Docstrings
|
||||||
|
----------
|
||||||
|
"""Summary of the function, class or method, less than 80 characters.
|
||||||
|
|
||||||
|
New paragraph after newline that explains in more detail any general
|
||||||
|
information about the function, class or method. After this, if defining
|
||||||
|
parameters and return types use the Sphinx format. After that an extra
|
||||||
|
newline then close the quotations.
|
||||||
|
|
||||||
|
When writing the docstring for a class, an extra line should be placed
|
||||||
|
after the closing quotations. For more in-depth explanations for these
|
||||||
|
decisions see http://www.python.org/dev/peps/pep-0257/
|
||||||
|
|
||||||
|
:param foo: the foo parameter
|
||||||
|
:param bar: the bar parameter
|
||||||
|
:returns: description of the return value
|
||||||
|
|
||||||
|
"""
|
||||||
|
10
MANIFEST.in
10
MANIFEST.in
@@ -6,14 +6,23 @@ graft doc
|
|||||||
graft smoketests
|
graft smoketests
|
||||||
graft tools
|
graft tools
|
||||||
graft etc
|
graft etc
|
||||||
|
graft bzrplugins
|
||||||
|
graft contrib
|
||||||
|
graft po
|
||||||
|
graft plugins
|
||||||
include nova/api/openstack/notes.txt
|
include nova/api/openstack/notes.txt
|
||||||
|
include nova/auth/*.schema
|
||||||
include nova/auth/novarc.template
|
include nova/auth/novarc.template
|
||||||
|
include nova/auth/opendj.sh
|
||||||
include nova/auth/slap.sh
|
include nova/auth/slap.sh
|
||||||
include nova/cloudpipe/bootscript.sh
|
include nova/cloudpipe/bootscript.sh
|
||||||
include nova/cloudpipe/client.ovpn.template
|
include nova/cloudpipe/client.ovpn.template
|
||||||
|
include nova/cloudpipe/bootscript.template
|
||||||
include nova/compute/fakevirtinstance.xml
|
include nova/compute/fakevirtinstance.xml
|
||||||
include nova/compute/interfaces.template
|
include nova/compute/interfaces.template
|
||||||
|
include nova/console/xvp.conf.template
|
||||||
include nova/db/sqlalchemy/migrate_repo/migrate.cfg
|
include nova/db/sqlalchemy/migrate_repo/migrate.cfg
|
||||||
|
include nova/db/sqlalchemy/migrate_repo/README
|
||||||
include nova/virt/interfaces.template
|
include nova/virt/interfaces.template
|
||||||
include nova/virt/libvirt*.xml.template
|
include nova/virt/libvirt*.xml.template
|
||||||
include nova/tests/CA/
|
include nova/tests/CA/
|
||||||
@@ -25,6 +34,7 @@ include nova/tests/bundle/1mb.manifest.xml
|
|||||||
include nova/tests/bundle/1mb.no_kernel_or_ramdisk.manifest.xml
|
include nova/tests/bundle/1mb.no_kernel_or_ramdisk.manifest.xml
|
||||||
include nova/tests/bundle/1mb.part.0
|
include nova/tests/bundle/1mb.part.0
|
||||||
include nova/tests/bundle/1mb.part.1
|
include nova/tests/bundle/1mb.part.1
|
||||||
|
include nova/tests/db/nova.austin.sqlite
|
||||||
include plugins/xenapi/README
|
include plugins/xenapi/README
|
||||||
include plugins/xenapi/etc/xapi.d/plugins/objectstore
|
include plugins/xenapi/etc/xapi.d/plugins/objectstore
|
||||||
include plugins/xenapi/etc/xapi.d/plugins/pluginlib_nova.py
|
include plugins/xenapi/etc/xapi.d/plugins/pluginlib_nova.py
|
||||||
|
@@ -433,6 +433,37 @@ class ProjectCommands(object):
|
|||||||
"nova-api server on this host.")
|
"nova-api server on this host.")
|
||||||
|
|
||||||
|
|
||||||
|
class FixedIpCommands(object):
|
||||||
|
"""Class for managing fixed ip."""
|
||||||
|
|
||||||
|
def list(self, host=None):
|
||||||
|
"""Lists all fixed ips (optionally by host) arguments: [host]"""
|
||||||
|
ctxt = context.get_admin_context()
|
||||||
|
if host == None:
|
||||||
|
fixed_ips = db.fixed_ip_get_all(ctxt)
|
||||||
|
else:
|
||||||
|
fixed_ips = db.fixed_ip_get_all_by_host(ctxt, host)
|
||||||
|
|
||||||
|
print "%-18s\t%-15s\t%-17s\t%-15s\t%s" % (_('network'),
|
||||||
|
_('IP address'),
|
||||||
|
_('MAC address'),
|
||||||
|
_('hostname'),
|
||||||
|
_('host'))
|
||||||
|
for fixed_ip in fixed_ips:
|
||||||
|
hostname = None
|
||||||
|
host = None
|
||||||
|
mac_address = None
|
||||||
|
if fixed_ip['instance']:
|
||||||
|
instance = fixed_ip['instance']
|
||||||
|
hostname = instance['hostname']
|
||||||
|
host = instance['host']
|
||||||
|
mac_address = instance['mac_address']
|
||||||
|
print "%-18s\t%-15s\t%-17s\t%-15s\t%s" % (
|
||||||
|
fixed_ip['network']['cidr'],
|
||||||
|
fixed_ip['address'],
|
||||||
|
mac_address, hostname, host)
|
||||||
|
|
||||||
|
|
||||||
class FloatingIpCommands(object):
|
class FloatingIpCommands(object):
|
||||||
"""Class for managing floating ip."""
|
"""Class for managing floating ip."""
|
||||||
|
|
||||||
@@ -472,8 +503,8 @@ class NetworkCommands(object):
|
|||||||
"""Class for managing networks."""
|
"""Class for managing networks."""
|
||||||
|
|
||||||
def create(self, fixed_range=None, num_networks=None,
|
def create(self, fixed_range=None, num_networks=None,
|
||||||
network_size=None, vlan_start=None, vpn_start=None,
|
network_size=None, vlan_start=None,
|
||||||
fixed_range_v6=None):
|
vpn_start=None, fixed_range_v6=None, label='public'):
|
||||||
"""Creates fixed ips for host by range
|
"""Creates fixed ips for host by range
|
||||||
arguments: [fixed_range=FLAG], [num_networks=FLAG],
|
arguments: [fixed_range=FLAG], [num_networks=FLAG],
|
||||||
[network_size=FLAG], [vlan_start=FLAG],
|
[network_size=FLAG], [vlan_start=FLAG],
|
||||||
@@ -495,9 +526,22 @@ class NetworkCommands(object):
|
|||||||
cidr=fixed_range,
|
cidr=fixed_range,
|
||||||
num_networks=int(num_networks),
|
num_networks=int(num_networks),
|
||||||
network_size=int(network_size),
|
network_size=int(network_size),
|
||||||
cidr_v6=fixed_range_v6,
|
|
||||||
vlan_start=int(vlan_start),
|
vlan_start=int(vlan_start),
|
||||||
vpn_start=int(vpn_start))
|
vpn_start=int(vpn_start),
|
||||||
|
cidr_v6=fixed_range_v6,
|
||||||
|
label=label)
|
||||||
|
|
||||||
|
def list(self):
|
||||||
|
"""List all created networks"""
|
||||||
|
print "%-18s\t%-15s\t%-15s\t%-15s" % (_('network'),
|
||||||
|
_('netmask'),
|
||||||
|
_('start address'),
|
||||||
|
'DNS')
|
||||||
|
for network in db.network_get_all(context.get_admin_context()):
|
||||||
|
print "%-18s\t%-15s\t%-15s\t%-15s" % (network.cidr,
|
||||||
|
network.netmask,
|
||||||
|
network.dhcp_start,
|
||||||
|
network.dns)
|
||||||
|
|
||||||
|
|
||||||
class ServiceCommands(object):
|
class ServiceCommands(object):
|
||||||
@@ -579,6 +623,13 @@ class VolumeCommands(object):
|
|||||||
ctxt = context.get_admin_context()
|
ctxt = context.get_admin_context()
|
||||||
volume = db.volume_get(ctxt, param2id(volume_id))
|
volume = db.volume_get(ctxt, param2id(volume_id))
|
||||||
host = volume['host']
|
host = volume['host']
|
||||||
|
|
||||||
|
if not host:
|
||||||
|
print "Volume not yet assigned to host."
|
||||||
|
print "Deleting volume from database and skipping rpc."
|
||||||
|
db.volume_destroy(ctxt, param2id(volume_id))
|
||||||
|
return
|
||||||
|
|
||||||
if volume['status'] == 'in-use':
|
if volume['status'] == 'in-use':
|
||||||
print "Volume is in-use."
|
print "Volume is in-use."
|
||||||
print "Detach volume from instance and then try again."
|
print "Detach volume from instance and then try again."
|
||||||
@@ -615,6 +666,7 @@ CATEGORIES = [
|
|||||||
('role', RoleCommands),
|
('role', RoleCommands),
|
||||||
('shell', ShellCommands),
|
('shell', ShellCommands),
|
||||||
('vpn', VpnCommands),
|
('vpn', VpnCommands),
|
||||||
|
('fixed', FixedIpCommands),
|
||||||
('floating', FloatingIpCommands),
|
('floating', FloatingIpCommands),
|
||||||
('network', NetworkCommands),
|
('network', NetworkCommands),
|
||||||
('service', ServiceCommands),
|
('service', ServiceCommands),
|
||||||
|
@@ -1826,7 +1826,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: nova/virt/xenapi/vm_utils.py:290
|
#: nova/virt/xenapi/vm_utils.py:290
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "PV Kernel in VDI:%d"
|
msgid "PV Kernel in VDI:%s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: nova/virt/xenapi/vm_utils.py:318
|
#: nova/virt/xenapi/vm_utils.py:318
|
||||||
|
@@ -74,6 +74,25 @@ LOG = logging.getLogger("nova.ldapdriver")
|
|||||||
# in which we may want to change the interface a bit more.
|
# in which we may want to change the interface a bit more.
|
||||||
|
|
||||||
|
|
||||||
|
def _clean(attr):
|
||||||
|
"""Clean attr for insertion into ldap"""
|
||||||
|
if attr is None:
|
||||||
|
return None
|
||||||
|
if type(attr) is unicode:
|
||||||
|
return str(attr)
|
||||||
|
return attr
|
||||||
|
|
||||||
|
|
||||||
|
def sanitize(fn):
|
||||||
|
"""Decorator to sanitize all args"""
|
||||||
|
def _wrapped(self, *args, **kwargs):
|
||||||
|
args = [_clean(x) for x in args]
|
||||||
|
kwargs = dict((k, _clean(v)) for (k, v) in kwargs)
|
||||||
|
return fn(self, *args, **kwargs)
|
||||||
|
_wrapped.func_name = fn.func_name
|
||||||
|
return _wrapped
|
||||||
|
|
||||||
|
|
||||||
class LdapDriver(object):
|
class LdapDriver(object):
|
||||||
"""Ldap Auth driver
|
"""Ldap Auth driver
|
||||||
|
|
||||||
@@ -106,23 +125,27 @@ class LdapDriver(object):
|
|||||||
self.conn.unbind_s()
|
self.conn.unbind_s()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def get_user(self, uid):
|
def get_user(self, uid):
|
||||||
"""Retrieve user by id"""
|
"""Retrieve user by id"""
|
||||||
attr = self.__get_ldap_user(uid)
|
attr = self.__get_ldap_user(uid)
|
||||||
return self.__to_user(attr)
|
return self.__to_user(attr)
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def get_user_from_access_key(self, access):
|
def get_user_from_access_key(self, access):
|
||||||
"""Retrieve user by access key"""
|
"""Retrieve user by access key"""
|
||||||
query = '(accessKey=%s)' % access
|
query = '(accessKey=%s)' % access
|
||||||
dn = FLAGS.ldap_user_subtree
|
dn = FLAGS.ldap_user_subtree
|
||||||
return self.__to_user(self.__find_object(dn, query))
|
return self.__to_user(self.__find_object(dn, query))
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def get_project(self, pid):
|
def get_project(self, pid):
|
||||||
"""Retrieve project by id"""
|
"""Retrieve project by id"""
|
||||||
dn = self.__project_to_dn(pid)
|
dn = self.__project_to_dn(pid)
|
||||||
attr = self.__find_object(dn, LdapDriver.project_pattern)
|
attr = self.__find_object(dn, LdapDriver.project_pattern)
|
||||||
return self.__to_project(attr)
|
return self.__to_project(attr)
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def get_users(self):
|
def get_users(self):
|
||||||
"""Retrieve list of users"""
|
"""Retrieve list of users"""
|
||||||
attrs = self.__find_objects(FLAGS.ldap_user_subtree,
|
attrs = self.__find_objects(FLAGS.ldap_user_subtree,
|
||||||
@@ -134,6 +157,7 @@ class LdapDriver(object):
|
|||||||
users.append(user)
|
users.append(user)
|
||||||
return users
|
return users
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def get_projects(self, uid=None):
|
def get_projects(self, uid=None):
|
||||||
"""Retrieve list of projects"""
|
"""Retrieve list of projects"""
|
||||||
pattern = LdapDriver.project_pattern
|
pattern = LdapDriver.project_pattern
|
||||||
@@ -143,6 +167,7 @@ class LdapDriver(object):
|
|||||||
pattern)
|
pattern)
|
||||||
return [self.__to_project(attr) for attr in attrs]
|
return [self.__to_project(attr) for attr in attrs]
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def create_user(self, name, access_key, secret_key, is_admin):
|
def create_user(self, name, access_key, secret_key, is_admin):
|
||||||
"""Create a user"""
|
"""Create a user"""
|
||||||
if self.__user_exists(name):
|
if self.__user_exists(name):
|
||||||
@@ -196,6 +221,7 @@ class LdapDriver(object):
|
|||||||
self.conn.add_s(self.__uid_to_dn(name), attr)
|
self.conn.add_s(self.__uid_to_dn(name), attr)
|
||||||
return self.__to_user(dict(attr))
|
return self.__to_user(dict(attr))
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def create_project(self, name, manager_uid,
|
def create_project(self, name, manager_uid,
|
||||||
description=None, member_uids=None):
|
description=None, member_uids=None):
|
||||||
"""Create a project"""
|
"""Create a project"""
|
||||||
@@ -231,6 +257,7 @@ class LdapDriver(object):
|
|||||||
self.conn.add_s(dn, attr)
|
self.conn.add_s(dn, attr)
|
||||||
return self.__to_project(dict(attr))
|
return self.__to_project(dict(attr))
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def modify_project(self, project_id, manager_uid=None, description=None):
|
def modify_project(self, project_id, manager_uid=None, description=None):
|
||||||
"""Modify an existing project"""
|
"""Modify an existing project"""
|
||||||
if not manager_uid and not description:
|
if not manager_uid and not description:
|
||||||
@@ -249,21 +276,25 @@ class LdapDriver(object):
|
|||||||
dn = self.__project_to_dn(project_id)
|
dn = self.__project_to_dn(project_id)
|
||||||
self.conn.modify_s(dn, attr)
|
self.conn.modify_s(dn, attr)
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def add_to_project(self, uid, project_id):
|
def add_to_project(self, uid, project_id):
|
||||||
"""Add user to project"""
|
"""Add user to project"""
|
||||||
dn = self.__project_to_dn(project_id)
|
dn = self.__project_to_dn(project_id)
|
||||||
return self.__add_to_group(uid, dn)
|
return self.__add_to_group(uid, dn)
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def remove_from_project(self, uid, project_id):
|
def remove_from_project(self, uid, project_id):
|
||||||
"""Remove user from project"""
|
"""Remove user from project"""
|
||||||
dn = self.__project_to_dn(project_id)
|
dn = self.__project_to_dn(project_id)
|
||||||
return self.__remove_from_group(uid, dn)
|
return self.__remove_from_group(uid, dn)
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def is_in_project(self, uid, project_id):
|
def is_in_project(self, uid, project_id):
|
||||||
"""Check if user is in project"""
|
"""Check if user is in project"""
|
||||||
dn = self.__project_to_dn(project_id)
|
dn = self.__project_to_dn(project_id)
|
||||||
return self.__is_in_group(uid, dn)
|
return self.__is_in_group(uid, dn)
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def has_role(self, uid, role, project_id=None):
|
def has_role(self, uid, role, project_id=None):
|
||||||
"""Check if user has role
|
"""Check if user has role
|
||||||
|
|
||||||
@@ -273,6 +304,7 @@ class LdapDriver(object):
|
|||||||
role_dn = self.__role_to_dn(role, project_id)
|
role_dn = self.__role_to_dn(role, project_id)
|
||||||
return self.__is_in_group(uid, role_dn)
|
return self.__is_in_group(uid, role_dn)
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def add_role(self, uid, role, project_id=None):
|
def add_role(self, uid, role, project_id=None):
|
||||||
"""Add role for user (or user and project)"""
|
"""Add role for user (or user and project)"""
|
||||||
role_dn = self.__role_to_dn(role, project_id)
|
role_dn = self.__role_to_dn(role, project_id)
|
||||||
@@ -283,11 +315,13 @@ class LdapDriver(object):
|
|||||||
else:
|
else:
|
||||||
return self.__add_to_group(uid, role_dn)
|
return self.__add_to_group(uid, role_dn)
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def remove_role(self, uid, role, project_id=None):
|
def remove_role(self, uid, role, project_id=None):
|
||||||
"""Remove role for user (or user and project)"""
|
"""Remove role for user (or user and project)"""
|
||||||
role_dn = self.__role_to_dn(role, project_id)
|
role_dn = self.__role_to_dn(role, project_id)
|
||||||
return self.__remove_from_group(uid, role_dn)
|
return self.__remove_from_group(uid, role_dn)
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def get_user_roles(self, uid, project_id=None):
|
def get_user_roles(self, uid, project_id=None):
|
||||||
"""Retrieve list of roles for user (or user and project)"""
|
"""Retrieve list of roles for user (or user and project)"""
|
||||||
if project_id is None:
|
if project_id is None:
|
||||||
@@ -307,6 +341,7 @@ class LdapDriver(object):
|
|||||||
roles = self.__find_objects(project_dn, query)
|
roles = self.__find_objects(project_dn, query)
|
||||||
return [role['cn'][0] for role in roles]
|
return [role['cn'][0] for role in roles]
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def delete_user(self, uid):
|
def delete_user(self, uid):
|
||||||
"""Delete a user"""
|
"""Delete a user"""
|
||||||
if not self.__user_exists(uid):
|
if not self.__user_exists(uid):
|
||||||
@@ -332,12 +367,14 @@ class LdapDriver(object):
|
|||||||
# Delete entry
|
# Delete entry
|
||||||
self.conn.delete_s(self.__uid_to_dn(uid))
|
self.conn.delete_s(self.__uid_to_dn(uid))
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def delete_project(self, project_id):
|
def delete_project(self, project_id):
|
||||||
"""Delete a project"""
|
"""Delete a project"""
|
||||||
project_dn = self.__project_to_dn(project_id)
|
project_dn = self.__project_to_dn(project_id)
|
||||||
self.__delete_roles(project_dn)
|
self.__delete_roles(project_dn)
|
||||||
self.__delete_group(project_dn)
|
self.__delete_group(project_dn)
|
||||||
|
|
||||||
|
@sanitize
|
||||||
def modify_user(self, uid, access_key=None, secret_key=None, admin=None):
|
def modify_user(self, uid, access_key=None, secret_key=None, admin=None):
|
||||||
"""Modify an existing user"""
|
"""Modify an existing user"""
|
||||||
if not access_key and not secret_key and admin is None:
|
if not access_key and not secret_key and admin is None:
|
||||||
|
@@ -282,6 +282,8 @@ DEFINE_integer('auth_token_ttl', 3600, 'Seconds for auth tokens to linger')
|
|||||||
|
|
||||||
DEFINE_string('state_path', os.path.join(os.path.dirname(__file__), '../'),
|
DEFINE_string('state_path', os.path.join(os.path.dirname(__file__), '../'),
|
||||||
"Top-level directory for maintaining nova's state")
|
"Top-level directory for maintaining nova's state")
|
||||||
|
DEFINE_string('logdir', None, 'output to a per-service log file in named '
|
||||||
|
'directory')
|
||||||
|
|
||||||
DEFINE_string('sql_connection',
|
DEFINE_string('sql_connection',
|
||||||
'sqlite:///$state_path/nova.sqlite',
|
'sqlite:///$state_path/nova.sqlite',
|
||||||
|
21
nova/log.py
21
nova/log.py
@@ -28,9 +28,11 @@ It also allows setting of formatting information through flags.
|
|||||||
|
|
||||||
|
|
||||||
import cStringIO
|
import cStringIO
|
||||||
|
import inspect
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
@@ -92,7 +94,7 @@ critical = logging.critical
|
|||||||
log = logging.log
|
log = logging.log
|
||||||
# handlers
|
# handlers
|
||||||
StreamHandler = logging.StreamHandler
|
StreamHandler = logging.StreamHandler
|
||||||
FileHandler = logging.FileHandler
|
RotatingFileHandler = logging.handlers.RotatingFileHandler
|
||||||
# logging.SysLogHandler is nicer than logging.logging.handler.SysLogHandler.
|
# logging.SysLogHandler is nicer than logging.logging.handler.SysLogHandler.
|
||||||
SysLogHandler = logging.handlers.SysLogHandler
|
SysLogHandler = logging.handlers.SysLogHandler
|
||||||
|
|
||||||
@@ -111,6 +113,18 @@ def _dictify_context(context):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
def _get_binary_name():
|
||||||
|
return os.path.basename(inspect.stack()[-1][1])
|
||||||
|
|
||||||
|
|
||||||
|
def get_log_file_path(binary=None):
|
||||||
|
if FLAGS.logfile:
|
||||||
|
return FLAGS.logfile
|
||||||
|
if FLAGS.logdir:
|
||||||
|
binary = binary or _get_binary_name()
|
||||||
|
return '%s.log' % (os.path.join(FLAGS.logdir, binary),)
|
||||||
|
|
||||||
|
|
||||||
def basicConfig():
|
def basicConfig():
|
||||||
logging.basicConfig()
|
logging.basicConfig()
|
||||||
for handler in logging.root.handlers:
|
for handler in logging.root.handlers:
|
||||||
@@ -123,8 +137,9 @@ def basicConfig():
|
|||||||
syslog = SysLogHandler(address='/dev/log')
|
syslog = SysLogHandler(address='/dev/log')
|
||||||
syslog.setFormatter(_formatter)
|
syslog.setFormatter(_formatter)
|
||||||
logging.root.addHandler(syslog)
|
logging.root.addHandler(syslog)
|
||||||
if FLAGS.logfile:
|
logpath = get_log_file_path()
|
||||||
logfile = FileHandler(FLAGS.logfile)
|
if logpath:
|
||||||
|
logfile = RotatingFileHandler(logpath)
|
||||||
logfile.setFormatter(_formatter)
|
logfile.setFormatter(_formatter)
|
||||||
logging.root.addHandler(logfile)
|
logging.root.addHandler(logfile)
|
||||||
|
|
||||||
|
@@ -29,6 +29,7 @@ import uuid
|
|||||||
|
|
||||||
from carrot import connection as carrot_connection
|
from carrot import connection as carrot_connection
|
||||||
from carrot import messaging
|
from carrot import messaging
|
||||||
|
from eventlet import greenpool
|
||||||
from eventlet import greenthread
|
from eventlet import greenthread
|
||||||
|
|
||||||
from nova import context
|
from nova import context
|
||||||
@@ -42,6 +43,8 @@ from nova import utils
|
|||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
LOG = logging.getLogger('nova.rpc')
|
LOG = logging.getLogger('nova.rpc')
|
||||||
|
|
||||||
|
flags.DEFINE_integer('rpc_thread_pool_size', 1024, 'Size of RPC thread pool')
|
||||||
|
|
||||||
|
|
||||||
class Connection(carrot_connection.BrokerConnection):
|
class Connection(carrot_connection.BrokerConnection):
|
||||||
"""Connection instance object"""
|
"""Connection instance object"""
|
||||||
@@ -155,11 +158,15 @@ class AdapterConsumer(TopicConsumer):
|
|||||||
def __init__(self, connection=None, topic="broadcast", proxy=None):
|
def __init__(self, connection=None, topic="broadcast", proxy=None):
|
||||||
LOG.debug(_('Initing the Adapter Consumer for %s') % topic)
|
LOG.debug(_('Initing the Adapter Consumer for %s') % topic)
|
||||||
self.proxy = proxy
|
self.proxy = proxy
|
||||||
|
self.pool = greenpool.GreenPool(FLAGS.rpc_thread_pool_size)
|
||||||
super(AdapterConsumer, self).__init__(connection=connection,
|
super(AdapterConsumer, self).__init__(connection=connection,
|
||||||
topic=topic)
|
topic=topic)
|
||||||
|
|
||||||
|
def receive(self, *args, **kwargs):
|
||||||
|
self.pool.spawn_n(self._receive, *args, **kwargs)
|
||||||
|
|
||||||
@exception.wrap_exception
|
@exception.wrap_exception
|
||||||
def receive(self, message_data, message):
|
def _receive(self, message_data, message):
|
||||||
"""Magically looks for a method on the proxy object and calls it
|
"""Magically looks for a method on the proxy object and calls it
|
||||||
|
|
||||||
Message data should be a dictionary with two keys:
|
Message data should be a dictionary with two keys:
|
||||||
|
@@ -248,16 +248,14 @@ class ApiEc2TestCase(test.TestCase):
|
|||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
rv = self.ec2.get_all_security_groups()
|
rv = self.ec2.get_all_security_groups()
|
||||||
# I don't bother checkng that we actually find it here,
|
|
||||||
# because the create/delete unit test further up should
|
group = [grp for grp in rv if grp.name == security_group_name][0]
|
||||||
# be good enough for that.
|
|
||||||
for group in rv:
|
self.assertEquals(len(group.rules), 1)
|
||||||
if group.name == security_group_name:
|
self.assertEquals(int(group.rules[0].from_port), 80)
|
||||||
self.assertEquals(len(group.rules), 1)
|
self.assertEquals(int(group.rules[0].to_port), 81)
|
||||||
self.assertEquals(int(group.rules[0].from_port), 80)
|
self.assertEquals(len(group.rules[0].grants), 1)
|
||||||
self.assertEquals(int(group.rules[0].to_port), 81)
|
self.assertEquals(str(group.rules[0].grants[0]), '0.0.0.0/0')
|
||||||
self.assertEquals(len(group.rules[0].grants), 1)
|
|
||||||
self.assertEquals(str(group.rules[0].grants[0]), '0.0.0.0/0')
|
|
||||||
|
|
||||||
self.expect_http()
|
self.expect_http()
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
@@ -314,16 +312,13 @@ class ApiEc2TestCase(test.TestCase):
|
|||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
rv = self.ec2.get_all_security_groups()
|
rv = self.ec2.get_all_security_groups()
|
||||||
# I don't bother checkng that we actually find it here,
|
|
||||||
# because the create/delete unit test further up should
|
group = [grp for grp in rv if grp.name == security_group_name][0]
|
||||||
# be good enough for that.
|
self.assertEquals(len(group.rules), 1)
|
||||||
for group in rv:
|
self.assertEquals(int(group.rules[0].from_port), 80)
|
||||||
if group.name == security_group_name:
|
self.assertEquals(int(group.rules[0].to_port), 81)
|
||||||
self.assertEquals(len(group.rules), 1)
|
self.assertEquals(len(group.rules[0].grants), 1)
|
||||||
self.assertEquals(int(group.rules[0].from_port), 80)
|
self.assertEquals(str(group.rules[0].grants[0]), '::/0')
|
||||||
self.assertEquals(int(group.rules[0].to_port), 81)
|
|
||||||
self.assertEquals(len(group.rules[0].grants), 1)
|
|
||||||
self.assertEquals(str(group.rules[0].grants[0]), '::/0')
|
|
||||||
|
|
||||||
self.expect_http()
|
self.expect_http()
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
@@ -46,6 +46,27 @@ class RootLoggerTestCase(test.TestCase):
|
|||||||
self.assert_(True) # didn't raise exception
|
self.assert_(True) # didn't raise exception
|
||||||
|
|
||||||
|
|
||||||
|
class LogHandlerTestCase(test.TestCase):
|
||||||
|
def test_log_path_logdir(self):
|
||||||
|
self.flags(logdir='/some/path')
|
||||||
|
self.assertEquals(log.get_log_file_path(binary='foo-bar'),
|
||||||
|
'/some/path/foo-bar.log')
|
||||||
|
|
||||||
|
def test_log_path_logfile(self):
|
||||||
|
self.flags(logfile='/some/path/foo-bar.log')
|
||||||
|
self.assertEquals(log.get_log_file_path(binary='foo-bar'),
|
||||||
|
'/some/path/foo-bar.log')
|
||||||
|
|
||||||
|
def test_log_path_none(self):
|
||||||
|
self.assertTrue(log.get_log_file_path(binary='foo-bar') is None)
|
||||||
|
|
||||||
|
def test_log_path_logfile_overrides_logdir(self):
|
||||||
|
self.flags(logdir='/some/other/path',
|
||||||
|
logfile='/some/path/foo-bar.log')
|
||||||
|
self.assertEquals(log.get_log_file_path(binary='foo-bar'),
|
||||||
|
'/some/path/foo-bar.log')
|
||||||
|
|
||||||
|
|
||||||
class NovaFormatterTestCase(test.TestCase):
|
class NovaFormatterTestCase(test.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(NovaFormatterTestCase, self).setUp()
|
super(NovaFormatterTestCase, self).setUp()
|
||||||
|
@@ -32,6 +32,7 @@ from nova.virt import xenapi_conn
|
|||||||
from nova.virt.xenapi import fake as xenapi_fake
|
from nova.virt.xenapi import fake as xenapi_fake
|
||||||
from nova.virt.xenapi import volume_utils
|
from nova.virt.xenapi import volume_utils
|
||||||
from nova.virt.xenapi.vmops import SimpleDH
|
from nova.virt.xenapi.vmops import SimpleDH
|
||||||
|
from nova.virt.xenapi.vmops import VMOps
|
||||||
from nova.tests.db import fakes as db_fakes
|
from nova.tests.db import fakes as db_fakes
|
||||||
from nova.tests.xenapi import stubs
|
from nova.tests.xenapi import stubs
|
||||||
from nova.tests.glance import stubs as glance_stubs
|
from nova.tests.glance import stubs as glance_stubs
|
||||||
@@ -141,6 +142,10 @@ class XenAPIVolumeTestCase(test.TestCase):
|
|||||||
self.stubs.UnsetAll()
|
self.stubs.UnsetAll()
|
||||||
|
|
||||||
|
|
||||||
|
def reset_network(*args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class XenAPIVMTestCase(test.TestCase):
|
class XenAPIVMTestCase(test.TestCase):
|
||||||
"""
|
"""
|
||||||
Unit tests for VM operations
|
Unit tests for VM operations
|
||||||
@@ -162,6 +167,7 @@ class XenAPIVMTestCase(test.TestCase):
|
|||||||
stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
|
stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
|
||||||
stubs.stubout_get_this_vm_uuid(self.stubs)
|
stubs.stubout_get_this_vm_uuid(self.stubs)
|
||||||
stubs.stubout_stream_disk(self.stubs)
|
stubs.stubout_stream_disk(self.stubs)
|
||||||
|
self.stubs.Set(VMOps, 'reset_network', reset_network)
|
||||||
glance_stubs.stubout_glance_client(self.stubs,
|
glance_stubs.stubout_glance_client(self.stubs,
|
||||||
glance_stubs.FakeGlance)
|
glance_stubs.FakeGlance)
|
||||||
self.conn = xenapi_conn.get_connection(False)
|
self.conn = xenapi_conn.get_connection(False)
|
||||||
@@ -243,7 +249,8 @@ class XenAPIVMTestCase(test.TestCase):
|
|||||||
# Check that the VM is running according to XenAPI.
|
# Check that the VM is running according to XenAPI.
|
||||||
self.assertEquals(vm['power_state'], 'Running')
|
self.assertEquals(vm['power_state'], 'Running')
|
||||||
|
|
||||||
def _test_spawn(self, image_id, kernel_id, ramdisk_id):
|
def _test_spawn(self, image_id, kernel_id, ramdisk_id,
|
||||||
|
instance_type="m1.large"):
|
||||||
stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
|
stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
|
||||||
values = {'name': 1,
|
values = {'name': 1,
|
||||||
'id': 1,
|
'id': 1,
|
||||||
@@ -252,7 +259,7 @@ class XenAPIVMTestCase(test.TestCase):
|
|||||||
'image_id': image_id,
|
'image_id': image_id,
|
||||||
'kernel_id': kernel_id,
|
'kernel_id': kernel_id,
|
||||||
'ramdisk_id': ramdisk_id,
|
'ramdisk_id': ramdisk_id,
|
||||||
'instance_type': 'm1.large',
|
'instance_type': instance_type,
|
||||||
'mac_address': 'aa:bb:cc:dd:ee:ff',
|
'mac_address': 'aa:bb:cc:dd:ee:ff',
|
||||||
}
|
}
|
||||||
conn = xenapi_conn.get_connection(False)
|
conn = xenapi_conn.get_connection(False)
|
||||||
@@ -260,6 +267,12 @@ class XenAPIVMTestCase(test.TestCase):
|
|||||||
conn.spawn(instance)
|
conn.spawn(instance)
|
||||||
self.check_vm_record(conn)
|
self.check_vm_record(conn)
|
||||||
|
|
||||||
|
def test_spawn_not_enough_memory(self):
|
||||||
|
FLAGS.xenapi_image_service = 'glance'
|
||||||
|
self.assertRaises(Exception,
|
||||||
|
self._test_spawn,
|
||||||
|
1, 2, 3, "m1.xlarge")
|
||||||
|
|
||||||
def test_spawn_raw_objectstore(self):
|
def test_spawn_raw_objectstore(self):
|
||||||
FLAGS.xenapi_image_service = 'objectstore'
|
FLAGS.xenapi_image_service = 'objectstore'
|
||||||
self._test_spawn(1, None, None)
|
self._test_spawn(1, None, None)
|
||||||
|
@@ -43,8 +43,6 @@ else:
|
|||||||
|
|
||||||
|
|
||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
flags.DEFINE_string('logdir', None, 'directory to keep log files in '
|
|
||||||
'(will be prepended to $logfile)')
|
|
||||||
|
|
||||||
|
|
||||||
class TwistdServerOptions(ServerOptions):
|
class TwistdServerOptions(ServerOptions):
|
||||||
|
Reference in New Issue
Block a user