PEP8 and pylint cleanup. There should be no functional changes here, just style changes to get violations down.
This commit is contained in:
parent
3e3407f2e4
commit
e012a2b737
@ -39,6 +39,7 @@ from nova import server
|
|||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
flags.DEFINE_integer('api_port', 8773, 'API port')
|
flags.DEFINE_integer('api_port', 8773, 'API port')
|
||||||
|
|
||||||
|
|
||||||
def main(_args):
|
def main(_args):
|
||||||
from nova import api
|
from nova import api
|
||||||
from nova import wsgi
|
from nova import wsgi
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
# Copyright (c) 2005, the Lawrence Journal-World
|
# Copyright (c) 2005, the Lawrence Journal-World
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# are permitted provided that the following conditions are met:
|
# modification, are permitted provided that the following conditions are met:
|
||||||
#
|
#
|
||||||
# 1. Redistributions of source code must retain the above copyright notice,
|
# 1. Redistributions of source code must retain the above copyright notice,
|
||||||
# this list of conditions and the following disclaimer.
|
# this list of conditions and the following disclaimer.
|
||||||
@ -32,20 +32,21 @@
|
|||||||
# notice, this list of conditions and the following disclaimer in the
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
# documentation and/or other materials provided with the distribution.
|
# documentation and/or other materials provided with the distribution.
|
||||||
#
|
#
|
||||||
# 3. Neither the name of Django nor the names of its contributors may be used
|
# 3. Neither the name of Django nor the names of its contributors may be
|
||||||
# to endorse or promote products derived from this software without
|
# used to endorse or promote products derived from this software without
|
||||||
# specific prior written permission.
|
# specific prior written permission.
|
||||||
#
|
#
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -181,8 +182,8 @@ class ShellCommands(object):
|
|||||||
if shell == 'ipython':
|
if shell == 'ipython':
|
||||||
try:
|
try:
|
||||||
import IPython
|
import IPython
|
||||||
# Explicitly pass an empty list as arguments, because otherwise IPython
|
# Explicitly pass an empty list as arguments, because
|
||||||
# would use sys.argv from this script.
|
# otherwise IPython would use sys.argv from this script.
|
||||||
shell = IPython.Shell.IPShell(argv=[])
|
shell = IPython.Shell.IPShell(argv=[])
|
||||||
shell.mainloop()
|
shell.mainloop()
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@ -190,13 +191,14 @@ class ShellCommands(object):
|
|||||||
|
|
||||||
if shell == 'python':
|
if shell == 'python':
|
||||||
import code
|
import code
|
||||||
try: # Try activating rlcompleter, because it's handy.
|
try:
|
||||||
|
# Try activating rlcompleter, because it's handy.
|
||||||
import readline
|
import readline
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
# We don't have to wrap the following import in a 'try', because
|
# We don't have to wrap the following import in a 'try',
|
||||||
# we already know 'readline' was imported successfully.
|
# because we already know 'readline' was imported successfully.
|
||||||
import rlcompleter
|
import rlcompleter
|
||||||
readline.parse_and_bind("tab:complete")
|
readline.parse_and_bind("tab:complete")
|
||||||
code.interact()
|
code.interact()
|
||||||
@ -242,7 +244,6 @@ class UserCommands(object):
|
|||||||
print 'export EC2_ACCESS_KEY=%s' % user.access
|
print 'export EC2_ACCESS_KEY=%s' % user.access
|
||||||
print 'export EC2_SECRET_KEY=%s' % user.secret
|
print 'export EC2_SECRET_KEY=%s' % user.secret
|
||||||
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.manager = manager.AuthManager()
|
self.manager = manager.AuthManager()
|
||||||
|
|
||||||
@ -291,6 +292,7 @@ class UserCommands(object):
|
|||||||
is_admin = False
|
is_admin = False
|
||||||
self.manager.modify_user(name, access_key, secret_key, is_admin)
|
self.manager.modify_user(name, access_key, secret_key, is_admin)
|
||||||
|
|
||||||
|
|
||||||
class ProjectCommands(object):
|
class ProjectCommands(object):
|
||||||
"""Class for managing projects."""
|
"""Class for managing projects."""
|
||||||
|
|
||||||
@ -380,7 +382,6 @@ class FloatingIpCommands(object):
|
|||||||
db.floating_ip_destroy(context.get_admin_context(),
|
db.floating_ip_destroy(context.get_admin_context(),
|
||||||
str(address))
|
str(address))
|
||||||
|
|
||||||
|
|
||||||
def list(self, host=None):
|
def list(self, host=None):
|
||||||
"""Lists all floating ips (optionally by host)
|
"""Lists all floating ips (optionally by host)
|
||||||
arguments: [host]"""
|
arguments: [host]"""
|
||||||
@ -397,6 +398,7 @@ class FloatingIpCommands(object):
|
|||||||
floating_ip['address'],
|
floating_ip['address'],
|
||||||
instance)
|
instance)
|
||||||
|
|
||||||
|
|
||||||
class NetworkCommands(object):
|
class NetworkCommands(object):
|
||||||
"""Class for managing networks."""
|
"""Class for managing networks."""
|
||||||
|
|
||||||
@ -429,8 +431,7 @@ CATEGORIES = [
|
|||||||
('shell', ShellCommands),
|
('shell', ShellCommands),
|
||||||
('vpn', VpnCommands),
|
('vpn', VpnCommands),
|
||||||
('floating', FloatingIpCommands),
|
('floating', FloatingIpCommands),
|
||||||
('network', NetworkCommands)
|
('network', NetworkCommands)]
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def lazy_match(name, key_value_tuples):
|
def lazy_match(name, key_value_tuples):
|
||||||
|
@ -17,13 +17,14 @@
|
|||||||
import bzrlib.log
|
import bzrlib.log
|
||||||
from bzrlib.osutils import format_date
|
from bzrlib.osutils import format_date
|
||||||
|
|
||||||
#
|
|
||||||
# This is mostly stolen from bzrlib.log.GnuChangelogLogFormatter
|
|
||||||
# The difference is that it logs the author rather than the committer
|
|
||||||
# which for Nova always is Tarmac.
|
|
||||||
#
|
|
||||||
class NovaLogFormat(bzrlib.log.GnuChangelogLogFormatter):
|
class NovaLogFormat(bzrlib.log.GnuChangelogLogFormatter):
|
||||||
|
"""This is mostly stolen from bzrlib.log.GnuChangelogLogFormatter
|
||||||
|
The difference is that it logs the author rather than the committer
|
||||||
|
which for Nova always is Tarmac."""
|
||||||
|
|
||||||
preferred_levels = 1
|
preferred_levels = 1
|
||||||
|
|
||||||
def log_revision(self, revision):
|
def log_revision(self, revision):
|
||||||
"""Log a revision, either merged or not."""
|
"""Log a revision, either merged or not."""
|
||||||
to_file = self.to_file
|
to_file = self.to_file
|
||||||
@ -38,13 +39,14 @@ class NovaLogFormat(bzrlib.log.GnuChangelogLogFormatter):
|
|||||||
to_file.write('%s %s\n\n' % (date_str, ", ".join(authors)))
|
to_file.write('%s %s\n\n' % (date_str, ", ".join(authors)))
|
||||||
|
|
||||||
if revision.delta is not None and revision.delta.has_changed():
|
if revision.delta is not None and revision.delta.has_changed():
|
||||||
for c in revision.delta.added + revision.delta.removed + revision.delta.modified:
|
for c in revision.delta.added + revision.delta.removed + \
|
||||||
|
revision.delta.modified:
|
||||||
path, = c[:1]
|
path, = c[:1]
|
||||||
to_file.write('\t* %s:\n' % (path,))
|
to_file.write('\t* %s:\n' % (path,))
|
||||||
for c in revision.delta.renamed:
|
for c in revision.delta.renamed:
|
||||||
oldpath,newpath = c[:2]
|
oldpath, newpath = c[:2]
|
||||||
# For renamed files, show both the old and the new path
|
# For renamed files, show both the old and the new path
|
||||||
to_file.write('\t* %s:\n\t* %s:\n' % (oldpath,newpath))
|
to_file.write('\t* %s:\n\t* %s:\n' % (oldpath, newpath))
|
||||||
to_file.write('\n')
|
to_file.write('\n')
|
||||||
|
|
||||||
if not revision.rev.message:
|
if not revision.rev.message:
|
||||||
@ -56,4 +58,3 @@ class NovaLogFormat(bzrlib.log.GnuChangelogLogFormatter):
|
|||||||
to_file.write('\n')
|
to_file.write('\n')
|
||||||
|
|
||||||
bzrlib.log.register_formatter('novalog', NovaLogFormat)
|
bzrlib.log.register_formatter('novalog', NovaLogFormat)
|
||||||
|
|
||||||
|
@ -25,10 +25,10 @@ import httplib
|
|||||||
from boto.ec2.regioninfo import RegionInfo
|
from boto.ec2.regioninfo import RegionInfo
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_CLC_URL='http://127.0.0.1:8773'
|
DEFAULT_CLC_URL = 'http://127.0.0.1:8773'
|
||||||
DEFAULT_REGION='nova'
|
DEFAULT_REGION = 'nova'
|
||||||
DEFAULT_ACCESS_KEY='admin'
|
DEFAULT_ACCESS_KEY = 'admin'
|
||||||
DEFAULT_SECRET_KEY='admin'
|
DEFAULT_SECRET_KEY = 'admin'
|
||||||
|
|
||||||
|
|
||||||
class UserInfo(object):
|
class UserInfo(object):
|
||||||
@ -199,9 +199,7 @@ class NovaAdminClient(object):
|
|||||||
|
|
||||||
def connection_for(self, username, project, clc_url=None, region=None,
|
def connection_for(self, username, project, clc_url=None, region=None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
"""
|
"""Returns a boto ec2 connection for the given username."""
|
||||||
Returns a boto ec2 connection for the given username.
|
|
||||||
"""
|
|
||||||
if not clc_url:
|
if not clc_url:
|
||||||
clc_url = self.clc_url
|
clc_url = self.clc_url
|
||||||
if not region:
|
if not region:
|
||||||
@ -220,36 +218,37 @@ class NovaAdminClient(object):
|
|||||||
**kwargs)
|
**kwargs)
|
||||||
|
|
||||||
def split_clc_url(self, clc_url):
|
def split_clc_url(self, clc_url):
|
||||||
"""
|
"""Splits a cloud controller endpoint url."""
|
||||||
Splits a cloud controller endpoint url.
|
|
||||||
"""
|
|
||||||
parts = httplib.urlsplit(clc_url)
|
parts = httplib.urlsplit(clc_url)
|
||||||
is_secure = parts.scheme == 'https'
|
is_secure = parts.scheme == 'https'
|
||||||
ip, port = parts.netloc.split(':')
|
ip, port = parts.netloc.split(':')
|
||||||
return {'ip': ip, 'port': int(port), 'is_secure': is_secure}
|
return {'ip': ip, 'port': int(port), 'is_secure': is_secure}
|
||||||
|
|
||||||
def get_users(self):
|
def get_users(self):
|
||||||
""" grabs the list of all users """
|
"""Grabs the list of all users."""
|
||||||
return self.apiconn.get_list('DescribeUsers', {}, [('item', UserInfo)])
|
return self.apiconn.get_list('DescribeUsers', {}, [('item', UserInfo)])
|
||||||
|
|
||||||
def get_user(self, name):
|
def get_user(self, name):
|
||||||
""" grab a single user by name """
|
"""Grab a single user by name."""
|
||||||
user = self.apiconn.get_object('DescribeUser', {'Name': name}, UserInfo)
|
user = self.apiconn.get_object('DescribeUser', {'Name': name},
|
||||||
|
UserInfo)
|
||||||
if user.username != None:
|
if user.username != None:
|
||||||
return user
|
return user
|
||||||
|
|
||||||
def has_user(self, username):
|
def has_user(self, username):
|
||||||
""" determine if user exists """
|
"""Determine if user exists."""
|
||||||
return self.get_user(username) != None
|
return self.get_user(username) != None
|
||||||
|
|
||||||
def create_user(self, username):
|
def create_user(self, username):
|
||||||
""" creates a new user, returning the userinfo object with access/secret """
|
"""Creates a new user, returning the userinfo object with
|
||||||
return self.apiconn.get_object('RegisterUser', {'Name': username}, UserInfo)
|
access/secret."""
|
||||||
|
return self.apiconn.get_object('RegisterUser', {'Name': username},
|
||||||
|
UserInfo)
|
||||||
|
|
||||||
def delete_user(self, username):
|
def delete_user(self, username):
|
||||||
""" deletes a user """
|
"""Deletes a user."""
|
||||||
return self.apiconn.get_object('DeregisterUser', {'Name': username}, UserInfo)
|
return self.apiconn.get_object('DeregisterUser', {'Name': username},
|
||||||
|
UserInfo)
|
||||||
|
|
||||||
def get_roles(self, project_roles=True):
|
def get_roles(self, project_roles=True):
|
||||||
"""Returns a list of available roles."""
|
"""Returns a list of available roles."""
|
||||||
@ -258,11 +257,10 @@ class NovaAdminClient(object):
|
|||||||
[('item', UserRole)])
|
[('item', UserRole)])
|
||||||
|
|
||||||
def get_user_roles(self, user, project=None):
|
def get_user_roles(self, user, project=None):
|
||||||
"""Returns a list of roles for the given user.
|
"""Returns a list of roles for the given user. Omitting project will
|
||||||
Omitting project will return any global roles that the user has.
|
return any global roles that the user has. Specifying project will
|
||||||
Specifying project will return only project specific roles.
|
return only project specific roles."""
|
||||||
"""
|
params = {'User': user}
|
||||||
params = {'User':user}
|
|
||||||
if project:
|
if project:
|
||||||
params['Project'] = project
|
params['Project'] = project
|
||||||
return self.apiconn.get_list('DescribeUserRoles',
|
return self.apiconn.get_list('DescribeUserRoles',
|
||||||
@ -270,24 +268,19 @@ class NovaAdminClient(object):
|
|||||||
[('item', UserRole)])
|
[('item', UserRole)])
|
||||||
|
|
||||||
def add_user_role(self, user, role, project=None):
|
def add_user_role(self, user, role, project=None):
|
||||||
"""
|
"""Add a role to a user either globally or for a specific project."""
|
||||||
Add a role to a user either globally or for a specific project.
|
|
||||||
"""
|
|
||||||
return self.modify_user_role(user, role, project=project,
|
return self.modify_user_role(user, role, project=project,
|
||||||
operation='add')
|
operation='add')
|
||||||
|
|
||||||
def remove_user_role(self, user, role, project=None):
|
def remove_user_role(self, user, role, project=None):
|
||||||
"""
|
"""Remove a role from a user either globally or for a specific
|
||||||
Remove a role from a user either globally or for a specific project.
|
project."""
|
||||||
"""
|
|
||||||
return self.modify_user_role(user, role, project=project,
|
return self.modify_user_role(user, role, project=project,
|
||||||
operation='remove')
|
operation='remove')
|
||||||
|
|
||||||
def modify_user_role(self, user, role, project=None, operation='add',
|
def modify_user_role(self, user, role, project=None, operation='add',
|
||||||
**kwargs):
|
**kwargs):
|
||||||
"""
|
"""Add or remove a role for a user and project."""
|
||||||
Add or remove a role for a user and project.
|
|
||||||
"""
|
|
||||||
params = {'User': user,
|
params = {'User': user,
|
||||||
'Role': role,
|
'Role': role,
|
||||||
'Project': project,
|
'Project': project,
|
||||||
@ -295,9 +288,7 @@ class NovaAdminClient(object):
|
|||||||
return self.apiconn.get_status('ModifyUserRole', params)
|
return self.apiconn.get_status('ModifyUserRole', params)
|
||||||
|
|
||||||
def get_projects(self, user=None):
|
def get_projects(self, user=None):
|
||||||
"""
|
"""Returns a list of all projects."""
|
||||||
Returns a list of all projects.
|
|
||||||
"""
|
|
||||||
if user:
|
if user:
|
||||||
params = {'User': user}
|
params = {'User': user}
|
||||||
else:
|
else:
|
||||||
@ -307,9 +298,7 @@ class NovaAdminClient(object):
|
|||||||
[('item', ProjectInfo)])
|
[('item', ProjectInfo)])
|
||||||
|
|
||||||
def get_project(self, name):
|
def get_project(self, name):
|
||||||
"""
|
"""Returns a single project with the specified name."""
|
||||||
Returns a single project with the specified name.
|
|
||||||
"""
|
|
||||||
project = self.apiconn.get_object('DescribeProject',
|
project = self.apiconn.get_object('DescribeProject',
|
||||||
{'Name': name},
|
{'Name': name},
|
||||||
ProjectInfo)
|
ProjectInfo)
|
||||||
@ -319,9 +308,7 @@ class NovaAdminClient(object):
|
|||||||
|
|
||||||
def create_project(self, projectname, manager_user, description=None,
|
def create_project(self, projectname, manager_user, description=None,
|
||||||
member_users=None):
|
member_users=None):
|
||||||
"""
|
"""Creates a new project."""
|
||||||
Creates a new project.
|
|
||||||
"""
|
|
||||||
params = {'Name': projectname,
|
params = {'Name': projectname,
|
||||||
'ManagerUser': manager_user,
|
'ManagerUser': manager_user,
|
||||||
'Description': description,
|
'Description': description,
|
||||||
@ -329,50 +316,38 @@ class NovaAdminClient(object):
|
|||||||
return self.apiconn.get_object('RegisterProject', params, ProjectInfo)
|
return self.apiconn.get_object('RegisterProject', params, ProjectInfo)
|
||||||
|
|
||||||
def delete_project(self, projectname):
|
def delete_project(self, projectname):
|
||||||
"""
|
"""Permanently deletes the specified project."""
|
||||||
Permanently deletes the specified project.
|
|
||||||
"""
|
|
||||||
return self.apiconn.get_object('DeregisterProject',
|
return self.apiconn.get_object('DeregisterProject',
|
||||||
{'Name': projectname},
|
{'Name': projectname},
|
||||||
ProjectInfo)
|
ProjectInfo)
|
||||||
|
|
||||||
def get_project_members(self, name):
|
def get_project_members(self, name):
|
||||||
"""
|
"""Returns a list of members of a project."""
|
||||||
Returns a list of members of a project.
|
|
||||||
"""
|
|
||||||
return self.apiconn.get_list('DescribeProjectMembers',
|
return self.apiconn.get_list('DescribeProjectMembers',
|
||||||
{'Name': name},
|
{'Name': name},
|
||||||
[('item', ProjectMember)])
|
[('item', ProjectMember)])
|
||||||
|
|
||||||
def add_project_member(self, user, project):
|
def add_project_member(self, user, project):
|
||||||
"""
|
"""Adds a user to a project."""
|
||||||
Adds a user to a project.
|
|
||||||
"""
|
|
||||||
return self.modify_project_member(user, project, operation='add')
|
return self.modify_project_member(user, project, operation='add')
|
||||||
|
|
||||||
def remove_project_member(self, user, project):
|
def remove_project_member(self, user, project):
|
||||||
"""
|
"""Removes a user from a project."""
|
||||||
Removes a user from a project.
|
|
||||||
"""
|
|
||||||
return self.modify_project_member(user, project, operation='remove')
|
return self.modify_project_member(user, project, operation='remove')
|
||||||
|
|
||||||
def modify_project_member(self, user, project, operation='add'):
|
def modify_project_member(self, user, project, operation='add'):
|
||||||
"""
|
"""Adds or removes a user from a project."""
|
||||||
Adds or removes a user from a project.
|
|
||||||
"""
|
|
||||||
params = {'User': user,
|
params = {'User': user,
|
||||||
'Project': project,
|
'Project': project,
|
||||||
'Operation': operation}
|
'Operation': operation}
|
||||||
return self.apiconn.get_status('ModifyProjectMember', params)
|
return self.apiconn.get_status('ModifyProjectMember', params)
|
||||||
|
|
||||||
def get_zip(self, user, project):
|
def get_zip(self, user, project):
|
||||||
"""
|
"""Returns the content of a zip file containing novarc and access
|
||||||
Returns the content of a zip file containing novarc and access credentials.
|
credentials."""
|
||||||
"""
|
|
||||||
params = {'Name': user, 'Project': project}
|
params = {'Name': user, 'Project': project}
|
||||||
zip = self.apiconn.get_object('GenerateX509ForUser', params, UserInfo)
|
zip = self.apiconn.get_object('GenerateX509ForUser', params, UserInfo)
|
||||||
return zip.file
|
return zip.file
|
||||||
|
|
||||||
def get_hosts(self):
|
def get_hosts(self):
|
||||||
return self.apiconn.get_list('DescribeHosts', {}, [('item', HostInfo)])
|
return self.apiconn.get_list('DescribeHosts', {}, [('item', HostInfo)])
|
||||||
|
|
||||||
|
@ -26,7 +26,9 @@ import random
|
|||||||
from nova import exception
|
from nova import exception
|
||||||
from nova import utils
|
from nova import utils
|
||||||
|
|
||||||
|
|
||||||
class RequestContext(object):
|
class RequestContext(object):
|
||||||
|
|
||||||
def __init__(self, user, project, is_admin=None, read_deleted=False,
|
def __init__(self, user, project, is_admin=None, read_deleted=False,
|
||||||
remote_address=None, timestamp=None, request_id=None):
|
remote_address=None, timestamp=None, request_id=None):
|
||||||
if hasattr(user, 'id'):
|
if hasattr(user, 'id'):
|
||||||
@ -56,10 +58,8 @@ class RequestContext(object):
|
|||||||
timestamp = utils.parse_isotime(timestamp)
|
timestamp = utils.parse_isotime(timestamp)
|
||||||
self.timestamp = timestamp
|
self.timestamp = timestamp
|
||||||
if not request_id:
|
if not request_id:
|
||||||
request_id = ''.join(
|
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-'
|
||||||
[random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-')
|
request_id = ''.join([random.choice(chars) for x in xrange(20)])
|
||||||
for x in xrange(20)]
|
|
||||||
)
|
|
||||||
self.request_id = request_id
|
self.request_id = request_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -81,7 +81,8 @@ class RequestContext(object):
|
|||||||
from nova.auth import manager
|
from nova.auth import manager
|
||||||
if not self._project:
|
if not self._project:
|
||||||
try:
|
try:
|
||||||
self._project = manager.AuthManager().get_project(self.project_id)
|
auth_manager = manager.AuthManager()
|
||||||
|
self._project = auth_manager.get_project(self.project_id)
|
||||||
except exception.NotFound:
|
except exception.NotFound:
|
||||||
pass
|
pass
|
||||||
return self._project
|
return self._project
|
||||||
|
@ -39,9 +39,12 @@ from nova import flags
|
|||||||
|
|
||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
flags.DEFINE_string('ca_file', 'cacert.pem', 'Filename of root CA')
|
flags.DEFINE_string('ca_file', 'cacert.pem', 'Filename of root CA')
|
||||||
flags.DEFINE_string('keys_path', utils.abspath('../keys'), 'Where we keep our keys')
|
flags.DEFINE_string('keys_path', utils.abspath('../keys'),
|
||||||
flags.DEFINE_string('ca_path', utils.abspath('../CA'), 'Where we keep our root CA')
|
'Where we keep our keys')
|
||||||
flags.DEFINE_boolean('use_intermediate_ca', False, 'Should we use intermediate CAs for each project?')
|
flags.DEFINE_string('ca_path', utils.abspath('../CA'),
|
||||||
|
'Where we keep our root CA')
|
||||||
|
flags.DEFINE_boolean('use_intermediate_ca', False,
|
||||||
|
'Should we use intermediate CAs for each project?')
|
||||||
|
|
||||||
|
|
||||||
def ca_path(project_id):
|
def ca_path(project_id):
|
||||||
@ -55,11 +58,11 @@ def fetch_ca(project_id=None, chain=True):
|
|||||||
project_id = None
|
project_id = None
|
||||||
buffer = ""
|
buffer = ""
|
||||||
if project_id:
|
if project_id:
|
||||||
with open(ca_path(project_id),"r") as cafile:
|
with open(ca_path(project_id), "r") as cafile:
|
||||||
buffer += cafile.read()
|
buffer += cafile.read()
|
||||||
if not chain:
|
if not chain:
|
||||||
return buffer
|
return buffer
|
||||||
with open(ca_path(None),"r") as cafile:
|
with open(ca_path(None), "r") as cafile:
|
||||||
buffer += cafile.read()
|
buffer += cafile.read()
|
||||||
return buffer
|
return buffer
|
||||||
|
|
||||||
@ -88,17 +91,18 @@ def generate_key_pair(bits=1024):
|
|||||||
|
|
||||||
|
|
||||||
def ssl_pub_to_ssh_pub(ssl_public_key, name='root', suffix='nova'):
|
def ssl_pub_to_ssh_pub(ssl_public_key, name='root', suffix='nova'):
|
||||||
rsa_key = M2Crypto.RSA.load_pub_key_bio(M2Crypto.BIO.MemoryBuffer(ssl_public_key))
|
pub_key_buffer = M2Crypto.BIO.MemoryBuffer(ssl_public_key)
|
||||||
|
rsa_key = M2Crypto.RSA.load_pub_key_bio(pub_key_buffer)
|
||||||
e, n = rsa_key.pub()
|
e, n = rsa_key.pub()
|
||||||
|
|
||||||
key_type = 'ssh-rsa'
|
key_type = 'ssh-rsa'
|
||||||
|
|
||||||
key_data = struct.pack('>I', len(key_type))
|
key_data = struct.pack('>I', len(key_type))
|
||||||
key_data += key_type
|
key_data += key_type
|
||||||
key_data += '%s%s' % (e,n)
|
key_data += '%s%s' % (e, n)
|
||||||
|
|
||||||
b64_blob = base64.b64encode(key_data)
|
b64_blob = base64.b64encode(key_data)
|
||||||
return '%s %s %s@%s\n' %(key_type, b64_blob, name, suffix)
|
return '%s %s %s@%s\n' % (key_type, b64_blob, name, suffix)
|
||||||
|
|
||||||
|
|
||||||
def generate_x509_cert(subject, bits=1024):
|
def generate_x509_cert(subject, bits=1024):
|
||||||
@ -106,8 +110,11 @@ def generate_x509_cert(subject, bits=1024):
|
|||||||
keyfile = os.path.abspath(os.path.join(tmpdir, 'temp.key'))
|
keyfile = os.path.abspath(os.path.join(tmpdir, 'temp.key'))
|
||||||
csrfile = os.path.join(tmpdir, 'temp.csr')
|
csrfile = os.path.join(tmpdir, 'temp.csr')
|
||||||
logging.debug("openssl genrsa -out %s %s" % (keyfile, bits))
|
logging.debug("openssl genrsa -out %s %s" % (keyfile, bits))
|
||||||
utils.runthis("Generating private key: %s", "openssl genrsa -out %s %s" % (keyfile, bits))
|
utils.runthis("Generating private key: %s",
|
||||||
utils.runthis("Generating CSR: %s", "openssl req -new -key %s -out %s -batch -subj %s" % (keyfile, csrfile, subject))
|
"openssl genrsa -out %s %s" % (keyfile, bits))
|
||||||
|
utils.runthis("Generating CSR: %s",
|
||||||
|
"openssl req -new -key %s -out %s -batch -subj %s" %
|
||||||
|
(keyfile, csrfile, subject))
|
||||||
private_key = open(keyfile).read()
|
private_key = open(keyfile).read()
|
||||||
csr = open(csrfile).read()
|
csr = open(csrfile).read()
|
||||||
shutil.rmtree(tmpdir)
|
shutil.rmtree(tmpdir)
|
||||||
@ -123,7 +130,8 @@ def sign_csr(csr_text, intermediate=None):
|
|||||||
if not os.path.exists(user_ca):
|
if not os.path.exists(user_ca):
|
||||||
start = os.getcwd()
|
start = os.getcwd()
|
||||||
os.chdir(FLAGS.ca_path)
|
os.chdir(FLAGS.ca_path)
|
||||||
utils.runthis("Generating intermediate CA: %s", "sh geninter.sh %s" % (intermediate))
|
utils.runthis("Generating intermediate CA: %s",
|
||||||
|
"sh geninter.sh %s" % (intermediate))
|
||||||
os.chdir(start)
|
os.chdir(start)
|
||||||
return _sign_csr(csr_text, user_ca)
|
return _sign_csr(csr_text, user_ca)
|
||||||
|
|
||||||
@ -137,7 +145,10 @@ def _sign_csr(csr_text, ca_folder):
|
|||||||
start = os.getcwd()
|
start = os.getcwd()
|
||||||
# Change working dir to CA
|
# Change working dir to CA
|
||||||
os.chdir(ca_folder)
|
os.chdir(ca_folder)
|
||||||
utils.runthis("Signing cert: %s", "openssl ca -batch -out %s/outbound.crt -config ./openssl.cnf -infiles %s/inbound.csr" % (tmpfolder, tmpfolder))
|
utils.runthis("Signing cert: %s",
|
||||||
|
"openssl ca -batch -out %s/outbound.crt "
|
||||||
|
"-config ./openssl.cnf -infiles %s/inbound.csr" %
|
||||||
|
(tmpfolder, tmpfolder))
|
||||||
os.chdir(start)
|
os.chdir(start)
|
||||||
with open("%s/outbound.crt" % (tmpfolder), "r") as crtfile:
|
with open("%s/outbound.crt" % (tmpfolder), "r") as crtfile:
|
||||||
return crtfile.read()
|
return crtfile.read()
|
||||||
@ -148,10 +159,11 @@ def mkreq(bits, subject="foo", ca=0):
|
|||||||
req = M2Crypto.X509.Request()
|
req = M2Crypto.X509.Request()
|
||||||
rsa = M2Crypto.RSA.gen_key(bits, 65537, callback=lambda: None)
|
rsa = M2Crypto.RSA.gen_key(bits, 65537, callback=lambda: None)
|
||||||
pk.assign_rsa(rsa)
|
pk.assign_rsa(rsa)
|
||||||
rsa = None # should not be freed here
|
# Should not be freed here
|
||||||
|
rsa = None
|
||||||
req.set_pubkey(pk)
|
req.set_pubkey(pk)
|
||||||
req.set_subject(subject)
|
req.set_subject(subject)
|
||||||
req.sign(pk,'sha512')
|
req.sign(pk, 'sha512')
|
||||||
assert req.verify(pk)
|
assert req.verify(pk)
|
||||||
pk2 = req.get_pubkey()
|
pk2 = req.get_pubkey()
|
||||||
assert req.verify(pk2)
|
assert req.verify(pk2)
|
||||||
@ -165,7 +177,8 @@ def mkcacert(subject='nova', years=1):
|
|||||||
cert = M2Crypto.X509.X509()
|
cert = M2Crypto.X509.X509()
|
||||||
cert.set_serial_number(1)
|
cert.set_serial_number(1)
|
||||||
cert.set_version(2)
|
cert.set_version(2)
|
||||||
cert.set_subject(sub) # FIXME subject is not set in mkreq yet
|
# FIXME subject is not set in mkreq yet
|
||||||
|
cert.set_subject(sub)
|
||||||
t = long(time.time()) + time.timezone
|
t = long(time.time()) + time.timezone
|
||||||
now = M2Crypto.ASN1.ASN1_UTCTIME()
|
now = M2Crypto.ASN1.ASN1_UTCTIME()
|
||||||
now.set_time(t)
|
now.set_time(t)
|
||||||
@ -189,7 +202,6 @@ def mkcacert(subject='nova', years=1):
|
|||||||
return cert, pk, pkey
|
return cert, pk, pkey
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
|
# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
@ -212,6 +224,7 @@ def mkcacert(subject='nova', years=1):
|
|||||||
# IN THE SOFTWARE.
|
# IN THE SOFTWARE.
|
||||||
# http://code.google.com/p/boto
|
# http://code.google.com/p/boto
|
||||||
|
|
||||||
|
|
||||||
def compute_md5(fp):
|
def compute_md5(fp):
|
||||||
"""
|
"""
|
||||||
@type fp: file
|
@type fp: file
|
||||||
|
@ -47,7 +47,7 @@ class ApiError(Error):
|
|||||||
def __init__(self, message='Unknown', code='Unknown'):
|
def __init__(self, message='Unknown', code='Unknown'):
|
||||||
self.message = message
|
self.message = message
|
||||||
self.code = code
|
self.code = code
|
||||||
super(ApiError, self).__init__('%s: %s'% (code, message))
|
super(ApiError, self).__init__('%s: %s' % (code, message))
|
||||||
|
|
||||||
|
|
||||||
class NotFound(Error):
|
class NotFound(Error):
|
||||||
@ -69,6 +69,7 @@ class NotEmpty(Error):
|
|||||||
class Invalid(Error):
|
class Invalid(Error):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InvalidInputException(Error):
|
class InvalidInputException(Error):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -86,5 +87,3 @@ def wrap_exception(f):
|
|||||||
raise
|
raise
|
||||||
_wrap.func_name = f.func_name
|
_wrap.func_name = f.func_name
|
||||||
return _wrap
|
return _wrap
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,7 +130,6 @@ class Backend(object):
|
|||||||
self._exchanges[exchange].publish(
|
self._exchanges[exchange].publish(
|
||||||
message, routing_key=routing_key)
|
message, routing_key=routing_key)
|
||||||
|
|
||||||
|
|
||||||
__instance = None
|
__instance = None
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -180,7 +180,8 @@ DEFINE_string('connection_type', 'libvirt', 'libvirt, xenapi or fake')
|
|||||||
DEFINE_integer('s3_port', 3333, 's3 port')
|
DEFINE_integer('s3_port', 3333, 's3 port')
|
||||||
DEFINE_string('s3_host', '127.0.0.1', 's3 host')
|
DEFINE_string('s3_host', '127.0.0.1', 's3 host')
|
||||||
DEFINE_string('compute_topic', 'compute', 'the topic compute nodes listen on')
|
DEFINE_string('compute_topic', 'compute', 'the topic compute nodes listen on')
|
||||||
DEFINE_string('scheduler_topic', 'scheduler', 'the topic scheduler nodes listen on')
|
DEFINE_string('scheduler_topic', 'scheduler',
|
||||||
|
'the topic scheduler nodes listen on')
|
||||||
DEFINE_string('volume_topic', 'volume', 'the topic volume nodes listen on')
|
DEFINE_string('volume_topic', 'volume', 'the topic volume nodes listen on')
|
||||||
DEFINE_string('network_topic', 'network', 'the topic network nodes listen on')
|
DEFINE_string('network_topic', 'network', 'the topic network nodes listen on')
|
||||||
|
|
||||||
|
@ -45,8 +45,6 @@ class Manager(object):
|
|||||||
yield
|
yield
|
||||||
|
|
||||||
def init_host(self):
|
def init_host(self):
|
||||||
"""Do any initialization that needs to be run if this is a standalone service.
|
"""Do any initialization that needs to be run if this is a standalone
|
||||||
|
service. Child classes should override this method."""
|
||||||
Child classes should override this method.
|
|
||||||
"""
|
|
||||||
pass
|
pass
|
||||||
|
@ -36,6 +36,7 @@ FLAGS = flags.FLAGS
|
|||||||
flags.DEFINE_integer('process_pool_size', 4,
|
flags.DEFINE_integer('process_pool_size', 4,
|
||||||
'Number of processes to use in the process pool')
|
'Number of processes to use in the process pool')
|
||||||
|
|
||||||
|
|
||||||
# This is based on _BackRelay from twister.internal.utils, but modified to
|
# This is based on _BackRelay from twister.internal.utils, but modified to
|
||||||
# capture both stdout and stderr, without odd stderr handling, and also to
|
# capture both stdout and stderr, without odd stderr handling, and also to
|
||||||
# handle stdin
|
# handle stdin
|
||||||
@ -55,8 +56,8 @@ class BackRelayWithInput(protocol.ProcessProtocol):
|
|||||||
will be called back when the process ends. This C{Deferred} is also
|
will be called back when the process ends. This C{Deferred} is also
|
||||||
associated with the L{_ProcessExecutionError} which C{deferred} fires
|
associated with the L{_ProcessExecutionError} which C{deferred} fires
|
||||||
with earlier in this case so that users can determine when the process
|
with earlier in this case so that users can determine when the process
|
||||||
has actually ended, in addition to knowing when bytes have been received
|
has actually ended, in addition to knowing when bytes have been
|
||||||
via stderr.
|
received via stderr.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, deferred, cmd, started_deferred=None,
|
def __init__(self, deferred, cmd, started_deferred=None,
|
||||||
@ -93,7 +94,7 @@ class BackRelayWithInput(protocol.ProcessProtocol):
|
|||||||
if self.deferred is not None:
|
if self.deferred is not None:
|
||||||
stdout, stderr = self.stdout.getvalue(), self.stderr.getvalue()
|
stdout, stderr = self.stdout.getvalue(), self.stderr.getvalue()
|
||||||
exit_code = reason.value.exitCode
|
exit_code = reason.value.exitCode
|
||||||
if self.check_exit_code and exit_code <> 0:
|
if self.check_exit_code and exit_code != 0:
|
||||||
self.deferred.errback(self._build_execution_error(exit_code))
|
self.deferred.errback(self._build_execution_error(exit_code))
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@ -101,14 +102,15 @@ class BackRelayWithInput(protocol.ProcessProtocol):
|
|||||||
reason.trap(error.ProcessDone)
|
reason.trap(error.ProcessDone)
|
||||||
self.deferred.callback((stdout, stderr))
|
self.deferred.callback((stdout, stderr))
|
||||||
except:
|
except:
|
||||||
# NOTE(justinsb): This logic is a little suspicious to me...
|
# NOTE(justinsb): This logic is a little suspicious to me.
|
||||||
# If the callback throws an exception, then errback will be
|
# If the callback throws an exception, then errback will
|
||||||
# called also. However, this is what the unit tests test for...
|
# be called also. However, this is what the unit tests
|
||||||
self.deferred.errback(self._build_execution_error(exit_code))
|
# test for.
|
||||||
|
exec_error = self._build_execution_error(exit_code)
|
||||||
|
self.deferred.errback(exec_error)
|
||||||
elif self.on_process_ended is not None:
|
elif self.on_process_ended is not None:
|
||||||
self.on_process_ended.errback(reason)
|
self.on_process_ended.errback(reason)
|
||||||
|
|
||||||
|
|
||||||
def connectionMade(self):
|
def connectionMade(self):
|
||||||
if self.started_deferred:
|
if self.started_deferred:
|
||||||
self.started_deferred.callback(self)
|
self.started_deferred.callback(self)
|
||||||
@ -116,6 +118,7 @@ class BackRelayWithInput(protocol.ProcessProtocol):
|
|||||||
self.transport.write(str(self.process_input))
|
self.transport.write(str(self.process_input))
|
||||||
self.transport.closeStdin()
|
self.transport.closeStdin()
|
||||||
|
|
||||||
|
|
||||||
def get_process_output(executable, args=None, env=None, path=None,
|
def get_process_output(executable, args=None, env=None, path=None,
|
||||||
process_reactor=None, check_exit_code=True,
|
process_reactor=None, check_exit_code=True,
|
||||||
process_input=None, started_deferred=None,
|
process_input=None, started_deferred=None,
|
||||||
@ -142,7 +145,7 @@ def get_process_output(executable, args=None, env=None, path=None,
|
|||||||
if not args is None:
|
if not args is None:
|
||||||
args = [str(x) for x in args]
|
args = [str(x) for x in args]
|
||||||
process_reactor.spawnProcess(process_handler, executable,
|
process_reactor.spawnProcess(process_handler, executable,
|
||||||
(executable,)+tuple(args), env, path)
|
(executable,) + tuple(args), env, path)
|
||||||
return deferred
|
return deferred
|
||||||
|
|
||||||
|
|
||||||
@ -193,9 +196,11 @@ class ProcessPool(object):
|
|||||||
|
|
||||||
class SharedPool(object):
|
class SharedPool(object):
|
||||||
_instance = None
|
_instance = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
if SharedPool._instance is None:
|
if SharedPool._instance is None:
|
||||||
self.__class__._instance = ProcessPool()
|
self.__class__._instance = ProcessPool()
|
||||||
|
|
||||||
def __getattr__(self, key):
|
def __getattr__(self, key):
|
||||||
return getattr(self._instance, key)
|
return getattr(self._instance, key)
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ flags.DEFINE_integer('quota_gigabytes', 1000,
|
|||||||
flags.DEFINE_integer('quota_floating_ips', 10,
|
flags.DEFINE_integer('quota_floating_ips', 10,
|
||||||
'number of floating ips allowed per project')
|
'number of floating ips allowed per project')
|
||||||
|
|
||||||
|
|
||||||
def get_quota(context, project_id):
|
def get_quota(context, project_id):
|
||||||
rval = {'instances': FLAGS.quota_instances,
|
rval = {'instances': FLAGS.quota_instances,
|
||||||
'cores': FLAGS.quota_cores,
|
'cores': FLAGS.quota_cores,
|
||||||
@ -52,6 +53,7 @@ def get_quota(context, project_id):
|
|||||||
pass
|
pass
|
||||||
return rval
|
return rval
|
||||||
|
|
||||||
|
|
||||||
def allowed_instances(context, num_instances, instance_type):
|
def allowed_instances(context, num_instances, instance_type):
|
||||||
"""Check quota and return min(num_instances, allowed_instances)"""
|
"""Check quota and return min(num_instances, allowed_instances)"""
|
||||||
project_id = context.project_id
|
project_id = context.project_id
|
||||||
@ -92,4 +94,3 @@ def allowed_floating_ips(context, num_floating_ips):
|
|||||||
quota = get_quota(context, project_id)
|
quota = get_quota(context, project_id)
|
||||||
allowed_floating_ips = quota['floating_ips'] - used_floating_ips
|
allowed_floating_ips = quota['floating_ips'] - used_floating_ips
|
||||||
return min(num_floating_ips, allowed_floating_ips)
|
return min(num_floating_ips, allowed_floating_ips)
|
||||||
|
|
||||||
|
@ -268,6 +268,7 @@ def _unpack_context(msg):
|
|||||||
LOG.debug('unpacked context: %s', context_dict)
|
LOG.debug('unpacked context: %s', context_dict)
|
||||||
return context.RequestContext.from_dict(context_dict)
|
return context.RequestContext.from_dict(context_dict)
|
||||||
|
|
||||||
|
|
||||||
def _pack_context(msg, context):
|
def _pack_context(msg, context):
|
||||||
"""Pack context into msg.
|
"""Pack context into msg.
|
||||||
|
|
||||||
@ -280,6 +281,7 @@ def _pack_context(msg, context):
|
|||||||
for (key, value) in context.to_dict().iteritems()])
|
for (key, value) in context.to_dict().iteritems()])
|
||||||
msg.update(context)
|
msg.update(context)
|
||||||
|
|
||||||
|
|
||||||
def call(context, topic, msg):
|
def call(context, topic, msg):
|
||||||
"""Sends a message on a topic and wait for a response"""
|
"""Sends a message on a topic and wait for a response"""
|
||||||
LOG.debug("Making asynchronous call...")
|
LOG.debug("Making asynchronous call...")
|
||||||
|
@ -54,11 +54,11 @@ def stop(pidfile):
|
|||||||
"""
|
"""
|
||||||
# Get the pid from the pidfile
|
# Get the pid from the pidfile
|
||||||
try:
|
try:
|
||||||
pid = int(open(pidfile,'r').read().strip())
|
pid = int(open(pidfile, 'r').read().strip())
|
||||||
except IOError:
|
except IOError:
|
||||||
message = "pidfile %s does not exist. Daemon not running?\n"
|
message = "pidfile %s does not exist. Daemon not running?\n"
|
||||||
sys.stderr.write(message % pidfile)
|
sys.stderr.write(message % pidfile)
|
||||||
return # not an error in a restart
|
return
|
||||||
|
|
||||||
# Try killing the daemon process
|
# Try killing the daemon process
|
||||||
try:
|
try:
|
||||||
@ -143,6 +143,5 @@ def daemonize(args, name, main):
|
|||||||
stderr=stderr,
|
stderr=stderr,
|
||||||
uid=FLAGS.uid,
|
uid=FLAGS.uid,
|
||||||
gid=FLAGS.gid,
|
gid=FLAGS.gid,
|
||||||
files_preserve=files_to_keep
|
files_preserve=files_to_keep):
|
||||||
):
|
|
||||||
main(args)
|
main(args)
|
||||||
|
21
nova/test.py
21
nova/test.py
@ -58,7 +58,7 @@ def skip_if_fake(func):
|
|||||||
|
|
||||||
class TrialTestCase(unittest.TestCase):
|
class TrialTestCase(unittest.TestCase):
|
||||||
"""Test case base class for all unit tests"""
|
"""Test case base class for all unit tests"""
|
||||||
def setUp(self): # pylint: disable-msg=C0103
|
def setUp(self):
|
||||||
"""Run before each test method to initialize test environment"""
|
"""Run before each test method to initialize test environment"""
|
||||||
super(TrialTestCase, self).setUp()
|
super(TrialTestCase, self).setUp()
|
||||||
# NOTE(vish): We need a better method for creating fixtures for tests
|
# NOTE(vish): We need a better method for creating fixtures for tests
|
||||||
@ -82,8 +82,9 @@ class TrialTestCase(unittest.TestCase):
|
|||||||
self._monkey_patch_attach()
|
self._monkey_patch_attach()
|
||||||
self._original_flags = FLAGS.FlagValuesDict()
|
self._original_flags = FLAGS.FlagValuesDict()
|
||||||
|
|
||||||
def tearDown(self): # pylint: disable-msg=C0103
|
def tearDown(self):
|
||||||
"""Runs after each test method to finalize/tear down test environment"""
|
"""Runs after each test method to finalize/tear down test
|
||||||
|
environment."""
|
||||||
try:
|
try:
|
||||||
self.mox.UnsetStubs()
|
self.mox.UnsetStubs()
|
||||||
self.stubs.UnsetAll()
|
self.stubs.UnsetAll()
|
||||||
@ -91,7 +92,8 @@ class TrialTestCase(unittest.TestCase):
|
|||||||
self.mox.VerifyAll()
|
self.mox.VerifyAll()
|
||||||
# NOTE(vish): Clean up any ips associated during the test.
|
# NOTE(vish): Clean up any ips associated during the test.
|
||||||
ctxt = context.get_admin_context()
|
ctxt = context.get_admin_context()
|
||||||
db.fixed_ip_disassociate_all_by_timeout(ctxt, FLAGS.host, self.start)
|
db.fixed_ip_disassociate_all_by_timeout(ctxt, FLAGS.host,
|
||||||
|
self.start)
|
||||||
db.network_disassociate_all(ctxt)
|
db.network_disassociate_all(ctxt)
|
||||||
rpc.Consumer.attach_to_twisted = self.originalAttach
|
rpc.Consumer.attach_to_twisted = self.originalAttach
|
||||||
for x in self.injected:
|
for x in self.injected:
|
||||||
@ -149,6 +151,7 @@ class TrialTestCase(unittest.TestCase):
|
|||||||
|
|
||||||
def _monkey_patch_attach(self):
|
def _monkey_patch_attach(self):
|
||||||
self.originalAttach = rpc.Consumer.attach_to_twisted
|
self.originalAttach = rpc.Consumer.attach_to_twisted
|
||||||
|
|
||||||
def _wrapped(innerSelf):
|
def _wrapped(innerSelf):
|
||||||
rv = self.originalAttach(innerSelf)
|
rv = self.originalAttach(innerSelf)
|
||||||
self.injected.append(rv)
|
self.injected.append(rv)
|
||||||
@ -164,7 +167,7 @@ class BaseTestCase(TrialTestCase):
|
|||||||
|
|
||||||
DEPRECATED: This is being removed once Tornado is gone, use TrialTestCase.
|
DEPRECATED: This is being removed once Tornado is gone, use TrialTestCase.
|
||||||
"""
|
"""
|
||||||
def setUp(self): # pylint: disable-msg=C0103
|
def setUp(self):
|
||||||
"""Run before each test method to initialize test environment"""
|
"""Run before each test method to initialize test environment"""
|
||||||
super(BaseTestCase, self).setUp()
|
super(BaseTestCase, self).setUp()
|
||||||
# TODO(termie): we could possibly keep a more global registry of
|
# TODO(termie): we could possibly keep a more global registry of
|
||||||
@ -179,7 +182,9 @@ class BaseTestCase(TrialTestCase):
|
|||||||
""" Push the ioloop along to wait for our test to complete. """
|
""" Push the ioloop along to wait for our test to complete. """
|
||||||
self._waiting = self.ioloop.add_timeout(time.time() + timeout,
|
self._waiting = self.ioloop.add_timeout(time.time() + timeout,
|
||||||
self._timeout)
|
self._timeout)
|
||||||
|
|
||||||
def _wait():
|
def _wait():
|
||||||
|
|
||||||
"""Wrapped wait function. Called on timeout."""
|
"""Wrapped wait function. Called on timeout."""
|
||||||
if self._timed_out:
|
if self._timed_out:
|
||||||
self.fail('test timed out')
|
self.fail('test timed out')
|
||||||
@ -219,9 +224,11 @@ class BaseTestCase(TrialTestCase):
|
|||||||
|
|
||||||
Example (callback chain, ugly):
|
Example (callback chain, ugly):
|
||||||
|
|
||||||
d = self.compute.terminate_instance(instance_id) # a Deferred instance
|
# A deferred instance
|
||||||
|
d = self.compute.terminate_instance(instance_id)
|
||||||
def _describe(_):
|
def _describe(_):
|
||||||
d_desc = self.compute.describe_instances() # another Deferred instance
|
# Another deferred instance
|
||||||
|
d_desc = self.compute.describe_instances()
|
||||||
return d_desc
|
return d_desc
|
||||||
def _checkDescribe(rv):
|
def _checkDescribe(rv):
|
||||||
self.assertEqual(rv, [])
|
self.assertEqual(rv, [])
|
||||||
|
@ -32,10 +32,10 @@ from nova.tests.api.fakes import APIStub
|
|||||||
|
|
||||||
class Test(unittest.TestCase):
|
class Test(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self): # pylint: disable-msg=C0103
|
def setUp(self):
|
||||||
self.stubs = stubout.StubOutForTesting()
|
self.stubs = stubout.StubOutForTesting()
|
||||||
|
|
||||||
def tearDown(self): # pylint: disable-msg=C0103
|
def tearDown(self):
|
||||||
self.stubs.UnsetAll()
|
self.stubs.UnsetAll()
|
||||||
|
|
||||||
def _request(self, url, subdomain, **kwargs):
|
def _request(self, url, subdomain, **kwargs):
|
||||||
|
@ -101,7 +101,7 @@ class XmlConversionTestCase(test.BaseTestCase):
|
|||||||
|
|
||||||
class ApiEc2TestCase(test.BaseTestCase):
|
class ApiEc2TestCase(test.BaseTestCase):
|
||||||
"""Unit test for the cloud controller on an EC2 API"""
|
"""Unit test for the cloud controller on an EC2 API"""
|
||||||
def setUp(self): # pylint: disable-msg=C0103,C0111
|
def setUp(self):
|
||||||
super(ApiEc2TestCase, self).setUp()
|
super(ApiEc2TestCase, self).setUp()
|
||||||
|
|
||||||
self.manager = manager.AuthManager()
|
self.manager = manager.AuthManager()
|
||||||
|
@ -37,7 +37,7 @@ FLAGS = flags.FLAGS
|
|||||||
|
|
||||||
class ComputeTestCase(test.TrialTestCase):
|
class ComputeTestCase(test.TrialTestCase):
|
||||||
"""Test case for compute"""
|
"""Test case for compute"""
|
||||||
def setUp(self): # pylint: disable-msg=C0103
|
def setUp(self):
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
super(ComputeTestCase, self).setUp()
|
super(ComputeTestCase, self).setUp()
|
||||||
self.flags(connection_type='fake',
|
self.flags(connection_type='fake',
|
||||||
@ -48,7 +48,7 @@ class ComputeTestCase(test.TrialTestCase):
|
|||||||
self.project = self.manager.create_project('fake', 'fake', 'fake')
|
self.project = self.manager.create_project('fake', 'fake', 'fake')
|
||||||
self.context = context.get_admin_context()
|
self.context = context.get_admin_context()
|
||||||
|
|
||||||
def tearDown(self): # pylint: disable-msg=C0103
|
def tearDown(self):
|
||||||
self.manager.delete_user(self.user)
|
self.manager.delete_user(self.user)
|
||||||
self.manager.delete_project(self.project)
|
self.manager.delete_project(self.project)
|
||||||
super(ComputeTestCase, self).tearDown()
|
super(ComputeTestCase, self).tearDown()
|
||||||
|
@ -35,7 +35,7 @@ FLAGS = flags.FLAGS
|
|||||||
|
|
||||||
class NetworkTestCase(test.TrialTestCase):
|
class NetworkTestCase(test.TrialTestCase):
|
||||||
"""Test cases for network code"""
|
"""Test cases for network code"""
|
||||||
def setUp(self): # pylint: disable-msg=C0103
|
def setUp(self):
|
||||||
super(NetworkTestCase, self).setUp()
|
super(NetworkTestCase, self).setUp()
|
||||||
# NOTE(vish): if you change these flags, make sure to change the
|
# NOTE(vish): if you change these flags, make sure to change the
|
||||||
# flags in the corresponding section in nova-dhcpbridge
|
# flags in the corresponding section in nova-dhcpbridge
|
||||||
@ -65,7 +65,7 @@ class NetworkTestCase(test.TrialTestCase):
|
|||||||
instance_ref = self._create_instance(1)
|
instance_ref = self._create_instance(1)
|
||||||
self.instance2_id = instance_ref['id']
|
self.instance2_id = instance_ref['id']
|
||||||
|
|
||||||
def tearDown(self): # pylint: disable-msg=C0103
|
def tearDown(self):
|
||||||
super(NetworkTestCase, self).tearDown()
|
super(NetworkTestCase, self).tearDown()
|
||||||
# TODO(termie): this should really be instantiating clean datastores
|
# TODO(termie): this should really be instantiating clean datastores
|
||||||
# in between runs, one failure kills all the tests
|
# in between runs, one failure kills all the tests
|
||||||
|
@ -57,7 +57,7 @@ os.makedirs(os.path.join(OSS_TEMPDIR, 'buckets'))
|
|||||||
class ObjectStoreTestCase(test.TrialTestCase):
|
class ObjectStoreTestCase(test.TrialTestCase):
|
||||||
"""Test objectstore API directly."""
|
"""Test objectstore API directly."""
|
||||||
|
|
||||||
def setUp(self): # pylint: disable-msg=C0103
|
def setUp(self):
|
||||||
"""Setup users and projects."""
|
"""Setup users and projects."""
|
||||||
super(ObjectStoreTestCase, self).setUp()
|
super(ObjectStoreTestCase, self).setUp()
|
||||||
self.flags(buckets_path=os.path.join(OSS_TEMPDIR, 'buckets'),
|
self.flags(buckets_path=os.path.join(OSS_TEMPDIR, 'buckets'),
|
||||||
@ -73,7 +73,7 @@ class ObjectStoreTestCase(test.TrialTestCase):
|
|||||||
self.auth_manager.create_project('proj2', 'user2', 'a proj', ['user2'])
|
self.auth_manager.create_project('proj2', 'user2', 'a proj', ['user2'])
|
||||||
self.context = context.RequestContext('user1', 'proj1')
|
self.context = context.RequestContext('user1', 'proj1')
|
||||||
|
|
||||||
def tearDown(self): # pylint: disable-msg=C0103
|
def tearDown(self):
|
||||||
"""Tear down users and projects."""
|
"""Tear down users and projects."""
|
||||||
self.auth_manager.delete_project('proj1')
|
self.auth_manager.delete_project('proj1')
|
||||||
self.auth_manager.delete_project('proj2')
|
self.auth_manager.delete_project('proj2')
|
||||||
@ -194,7 +194,7 @@ class TestSite(server.Site):
|
|||||||
class S3APITestCase(test.TrialTestCase):
|
class S3APITestCase(test.TrialTestCase):
|
||||||
"""Test objectstore through S3 API."""
|
"""Test objectstore through S3 API."""
|
||||||
|
|
||||||
def setUp(self): # pylint: disable-msg=C0103
|
def setUp(self):
|
||||||
"""Setup users, projects, and start a test server."""
|
"""Setup users, projects, and start a test server."""
|
||||||
super(S3APITestCase, self).setUp()
|
super(S3APITestCase, self).setUp()
|
||||||
|
|
||||||
@ -309,7 +309,7 @@ class S3APITestCase(test.TrialTestCase):
|
|||||||
deferred.addCallback(self._ensure_no_buckets)
|
deferred.addCallback(self._ensure_no_buckets)
|
||||||
return deferred
|
return deferred
|
||||||
|
|
||||||
def tearDown(self): # pylint: disable-msg=C0103
|
def tearDown(self):
|
||||||
"""Tear down auth and test server."""
|
"""Tear down auth and test server."""
|
||||||
self.auth_manager.delete_user('admin')
|
self.auth_manager.delete_user('admin')
|
||||||
self.auth_manager.delete_project('admin')
|
self.auth_manager.delete_project('admin')
|
||||||
|
@ -33,7 +33,7 @@ FLAGS = flags.FLAGS
|
|||||||
|
|
||||||
|
|
||||||
class QuotaTestCase(test.TrialTestCase):
|
class QuotaTestCase(test.TrialTestCase):
|
||||||
def setUp(self): # pylint: disable-msg=C0103
|
def setUp(self):
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
super(QuotaTestCase, self).setUp()
|
super(QuotaTestCase, self).setUp()
|
||||||
self.flags(connection_type='fake',
|
self.flags(connection_type='fake',
|
||||||
@ -51,7 +51,7 @@ class QuotaTestCase(test.TrialTestCase):
|
|||||||
self.context = context.RequestContext(project=self.project,
|
self.context = context.RequestContext(project=self.project,
|
||||||
user=self.user)
|
user=self.user)
|
||||||
|
|
||||||
def tearDown(self): # pylint: disable-msg=C0103
|
def tearDown(self):
|
||||||
manager.AuthManager().delete_project(self.project)
|
manager.AuthManager().delete_project(self.project)
|
||||||
manager.AuthManager().delete_user(self.user)
|
manager.AuthManager().delete_user(self.user)
|
||||||
super(QuotaTestCase, self).tearDown()
|
super(QuotaTestCase, self).tearDown()
|
||||||
|
@ -33,7 +33,7 @@ FLAGS = flags.FLAGS
|
|||||||
|
|
||||||
class RpcTestCase(test.TrialTestCase):
|
class RpcTestCase(test.TrialTestCase):
|
||||||
"""Test cases for rpc"""
|
"""Test cases for rpc"""
|
||||||
def setUp(self): # pylint: disable-msg=C0103
|
def setUp(self):
|
||||||
super(RpcTestCase, self).setUp()
|
super(RpcTestCase, self).setUp()
|
||||||
self.conn = rpc.Connection.instance()
|
self.conn = rpc.Connection.instance()
|
||||||
self.receiver = TestReceiver()
|
self.receiver = TestReceiver()
|
||||||
|
@ -44,7 +44,7 @@ class TestDriver(driver.Scheduler):
|
|||||||
|
|
||||||
class SchedulerTestCase(test.TrialTestCase):
|
class SchedulerTestCase(test.TrialTestCase):
|
||||||
"""Test case for scheduler"""
|
"""Test case for scheduler"""
|
||||||
def setUp(self): # pylint: disable=C0103
|
def setUp(self):
|
||||||
super(SchedulerTestCase, self).setUp()
|
super(SchedulerTestCase, self).setUp()
|
||||||
self.flags(scheduler_driver='nova.tests.scheduler_unittest.TestDriver')
|
self.flags(scheduler_driver='nova.tests.scheduler_unittest.TestDriver')
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ class SchedulerTestCase(test.TrialTestCase):
|
|||||||
|
|
||||||
class SimpleDriverTestCase(test.TrialTestCase):
|
class SimpleDriverTestCase(test.TrialTestCase):
|
||||||
"""Test case for simple driver"""
|
"""Test case for simple driver"""
|
||||||
def setUp(self): # pylint: disable-msg=C0103
|
def setUp(self):
|
||||||
super(SimpleDriverTestCase, self).setUp()
|
super(SimpleDriverTestCase, self).setUp()
|
||||||
self.flags(connection_type='fake',
|
self.flags(connection_type='fake',
|
||||||
max_cores=4,
|
max_cores=4,
|
||||||
@ -87,7 +87,7 @@ class SimpleDriverTestCase(test.TrialTestCase):
|
|||||||
self.project = self.manager.create_project('fake', 'fake', 'fake')
|
self.project = self.manager.create_project('fake', 'fake', 'fake')
|
||||||
self.context = context.get_admin_context()
|
self.context = context.get_admin_context()
|
||||||
|
|
||||||
def tearDown(self): # pylint: disable-msg=C0103
|
def tearDown(self):
|
||||||
self.manager.delete_user(self.user)
|
self.manager.delete_user(self.user)
|
||||||
self.manager.delete_project(self.project)
|
self.manager.delete_project(self.project)
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class ServiceManagerTestCase(test.BaseTestCase):
|
|||||||
class ServiceTestCase(test.BaseTestCase):
|
class ServiceTestCase(test.BaseTestCase):
|
||||||
"""Test cases for Services"""
|
"""Test cases for Services"""
|
||||||
|
|
||||||
def setUp(self): # pylint: disable=C0103
|
def setUp(self):
|
||||||
super(ServiceTestCase, self).setUp()
|
super(ServiceTestCase, self).setUp()
|
||||||
self.mox.StubOutWithMock(service, 'db')
|
self.mox.StubOutWithMock(service, 'db')
|
||||||
self.context = context.get_admin_context()
|
self.context = context.get_admin_context()
|
||||||
|
@ -34,7 +34,7 @@ FLAGS = flags.FLAGS
|
|||||||
|
|
||||||
class VolumeTestCase(test.TrialTestCase):
|
class VolumeTestCase(test.TrialTestCase):
|
||||||
"""Test Case for volumes"""
|
"""Test Case for volumes"""
|
||||||
def setUp(self): # pylint: disable-msg=C0103
|
def setUp(self):
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
super(VolumeTestCase, self).setUp()
|
super(VolumeTestCase, self).setUp()
|
||||||
self.compute = utils.import_object(FLAGS.compute_manager)
|
self.compute = utils.import_object(FLAGS.compute_manager)
|
||||||
|
@ -53,6 +53,7 @@ class TwistdServerOptions(ServerOptions):
|
|||||||
class FlagParser(object):
|
class FlagParser(object):
|
||||||
# this is a required attribute for gflags
|
# this is a required attribute for gflags
|
||||||
syntactic_help = ''
|
syntactic_help = ''
|
||||||
|
|
||||||
def __init__(self, parser):
|
def __init__(self, parser):
|
||||||
self.parser = parser
|
self.parser = parser
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ class FlagParser(object):
|
|||||||
def WrapTwistedOptions(wrapped):
|
def WrapTwistedOptions(wrapped):
|
||||||
class TwistedOptionsToFlags(wrapped):
|
class TwistedOptionsToFlags(wrapped):
|
||||||
subCommands = None
|
subCommands = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# NOTE(termie): _data exists because Twisted stuff expects
|
# NOTE(termie): _data exists because Twisted stuff expects
|
||||||
# to be able to set arbitrary things that are
|
# to be able to set arbitrary things that are
|
||||||
@ -80,7 +82,8 @@ def WrapTwistedOptions(wrapped):
|
|||||||
|
|
||||||
def _absorbFlags(self):
|
def _absorbFlags(self):
|
||||||
twistd_flags = []
|
twistd_flags = []
|
||||||
reflect.accumulateClassList(self.__class__, 'optFlags', twistd_flags)
|
reflect.accumulateClassList(self.__class__, 'optFlags',
|
||||||
|
twistd_flags)
|
||||||
for flag in twistd_flags:
|
for flag in twistd_flags:
|
||||||
key = flag[0].replace('-', '_')
|
key = flag[0].replace('-', '_')
|
||||||
if hasattr(FLAGS, key):
|
if hasattr(FLAGS, key):
|
||||||
@ -89,7 +92,8 @@ def WrapTwistedOptions(wrapped):
|
|||||||
|
|
||||||
def _absorbParameters(self):
|
def _absorbParameters(self):
|
||||||
twistd_params = []
|
twistd_params = []
|
||||||
reflect.accumulateClassList(self.__class__, 'optParameters', twistd_params)
|
reflect.accumulateClassList(self.__class__, 'optParameters',
|
||||||
|
twistd_params)
|
||||||
for param in twistd_params:
|
for param in twistd_params:
|
||||||
key = param[0].replace('-', '_')
|
key = param[0].replace('-', '_')
|
||||||
if hasattr(FLAGS, key):
|
if hasattr(FLAGS, key):
|
||||||
@ -103,13 +107,14 @@ def WrapTwistedOptions(wrapped):
|
|||||||
|
|
||||||
def _absorbHandlers(self):
|
def _absorbHandlers(self):
|
||||||
twistd_handlers = {}
|
twistd_handlers = {}
|
||||||
reflect.addMethodNamesToDict(self.__class__, twistd_handlers, "opt_")
|
reflect.addMethodNamesToDict(self.__class__, twistd_handlers,
|
||||||
|
"opt_")
|
||||||
|
|
||||||
# NOTE(termie): Much of the following is derived/copied from
|
# NOTE(termie): Much of the following is derived/copied from
|
||||||
# twisted.python.usage with the express purpose of
|
# twisted.python.usage with the express purpose of
|
||||||
# providing compatibility
|
# providing compatibility
|
||||||
for name in twistd_handlers.keys():
|
for name in twistd_handlers.keys():
|
||||||
method = getattr(self, 'opt_'+name)
|
method = getattr(self, 'opt_' + name)
|
||||||
|
|
||||||
takesArg = not usage.flagFunction(method, name)
|
takesArg = not usage.flagFunction(method, name)
|
||||||
doc = getattr(method, '__doc__', None)
|
doc = getattr(method, '__doc__', None)
|
||||||
@ -125,7 +130,6 @@ def WrapTwistedOptions(wrapped):
|
|||||||
flags.DEFINE_string(name, None, doc)
|
flags.DEFINE_string(name, None, doc)
|
||||||
self._paramHandlers[name] = method
|
self._paramHandlers[name] = method
|
||||||
|
|
||||||
|
|
||||||
def _doHandlers(self):
|
def _doHandlers(self):
|
||||||
for flag, handler in self._flagHandlers.iteritems():
|
for flag, handler in self._flagHandlers.iteritems():
|
||||||
if self[flag]:
|
if self[flag]:
|
||||||
@ -195,7 +199,7 @@ def stop(pidfile):
|
|||||||
"""
|
"""
|
||||||
# Get the pid from the pidfile
|
# Get the pid from the pidfile
|
||||||
try:
|
try:
|
||||||
pf = file(pidfile,'r')
|
pf = file(pidfile, 'r')
|
||||||
pid = int(pf.read().strip())
|
pid = int(pf.read().strip())
|
||||||
pf.close()
|
pf.close()
|
||||||
except IOError:
|
except IOError:
|
||||||
@ -204,7 +208,8 @@ def stop(pidfile):
|
|||||||
if not pid:
|
if not pid:
|
||||||
message = "pidfile %s does not exist. Daemon not running?\n"
|
message = "pidfile %s does not exist. Daemon not running?\n"
|
||||||
sys.stderr.write(message % pidfile)
|
sys.stderr.write(message % pidfile)
|
||||||
return # not an error in a restart
|
# Not an error in a restart
|
||||||
|
return
|
||||||
|
|
||||||
# Try killing the daemon process
|
# Try killing the daemon process
|
||||||
try:
|
try:
|
||||||
|
@ -39,6 +39,7 @@ from nova.exception import ProcessExecutionError
|
|||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
|
TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
|
||||||
|
|
||||||
|
|
||||||
def import_class(import_str):
|
def import_class(import_str):
|
||||||
"""Returns a class from a string including module and class"""
|
"""Returns a class from a string including module and class"""
|
||||||
mod_str, _sep, class_str = import_str.rpartition('.')
|
mod_str, _sep, class_str = import_str.rpartition('.')
|
||||||
@ -48,6 +49,7 @@ def import_class(import_str):
|
|||||||
except (ImportError, ValueError, AttributeError):
|
except (ImportError, ValueError, AttributeError):
|
||||||
raise exception.NotFound('Class %s cannot be found' % class_str)
|
raise exception.NotFound('Class %s cannot be found' % class_str)
|
||||||
|
|
||||||
|
|
||||||
def import_object(import_str):
|
def import_object(import_str):
|
||||||
"""Returns an object including a module or module and class"""
|
"""Returns an object including a module or module and class"""
|
||||||
try:
|
try:
|
||||||
@ -57,6 +59,7 @@ def import_object(import_str):
|
|||||||
cls = import_class(import_str)
|
cls = import_class(import_str)
|
||||||
return cls()
|
return cls()
|
||||||
|
|
||||||
|
|
||||||
def fetchfile(url, target):
|
def fetchfile(url, target):
|
||||||
logging.debug("Fetching %s" % url)
|
logging.debug("Fetching %s" % url)
|
||||||
# c = pycurl.Curl()
|
# c = pycurl.Curl()
|
||||||
@ -68,6 +71,7 @@ def fetchfile(url, target):
|
|||||||
# fp.close()
|
# fp.close()
|
||||||
execute("curl --fail %s -o %s" % (url, target))
|
execute("curl --fail %s -o %s" % (url, target))
|
||||||
|
|
||||||
|
|
||||||
def execute(cmd, process_input=None, addl_env=None, check_exit_code=True):
|
def execute(cmd, process_input=None, addl_env=None, check_exit_code=True):
|
||||||
logging.debug("Running cmd: %s", cmd)
|
logging.debug("Running cmd: %s", cmd)
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
@ -83,7 +87,7 @@ def execute(cmd, process_input=None, addl_env=None, check_exit_code=True):
|
|||||||
obj.stdin.close()
|
obj.stdin.close()
|
||||||
if obj.returncode:
|
if obj.returncode:
|
||||||
logging.debug("Result was %s" % (obj.returncode))
|
logging.debug("Result was %s" % (obj.returncode))
|
||||||
if check_exit_code and obj.returncode <> 0:
|
if check_exit_code and obj.returncode != 0:
|
||||||
(stdout, stderr) = result
|
(stdout, stderr) = result
|
||||||
raise ProcessExecutionError(exit_code=obj.returncode,
|
raise ProcessExecutionError(exit_code=obj.returncode,
|
||||||
stdout=stdout,
|
stdout=stdout,
|
||||||
@ -106,7 +110,8 @@ def default_flagfile(filename='nova.conf'):
|
|||||||
script_dir = os.path.dirname(inspect.stack()[-1][1])
|
script_dir = os.path.dirname(inspect.stack()[-1][1])
|
||||||
filename = os.path.abspath(os.path.join(script_dir, filename))
|
filename = os.path.abspath(os.path.join(script_dir, filename))
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
sys.argv = sys.argv[:1] + ['--flagfile=%s' % filename] + sys.argv[1:]
|
flagfile = ['--flagfile=%s' % filename]
|
||||||
|
sys.argv = sys.argv[:1] + flagfile + sys.argv[1:]
|
||||||
|
|
||||||
|
|
||||||
def debug(arg):
|
def debug(arg):
|
||||||
@ -114,11 +119,11 @@ def debug(arg):
|
|||||||
return arg
|
return arg
|
||||||
|
|
||||||
|
|
||||||
def runthis(prompt, cmd, check_exit_code = True):
|
def runthis(prompt, cmd, check_exit_code=True):
|
||||||
logging.debug("Running %s" % (cmd))
|
logging.debug("Running %s" % (cmd))
|
||||||
exit_code = subprocess.call(cmd.split(" "))
|
exit_code = subprocess.call(cmd.split(" "))
|
||||||
logging.debug(prompt % (exit_code))
|
logging.debug(prompt % (exit_code))
|
||||||
if check_exit_code and exit_code <> 0:
|
if check_exit_code and exit_code != 0:
|
||||||
raise ProcessExecutionError(exit_code=exit_code,
|
raise ProcessExecutionError(exit_code=exit_code,
|
||||||
stdout=None,
|
stdout=None,
|
||||||
stderr=None,
|
stderr=None,
|
||||||
@ -128,7 +133,7 @@ def runthis(prompt, cmd, check_exit_code = True):
|
|||||||
def generate_uid(topic, size=8):
|
def generate_uid(topic, size=8):
|
||||||
if topic == "i":
|
if topic == "i":
|
||||||
# Instances have integer internal ids.
|
# Instances have integer internal ids.
|
||||||
return random.randint(0, 2**32-1)
|
return random.randint(0, 2 ** 32 - 1)
|
||||||
else:
|
else:
|
||||||
characters = '01234567890abcdefghijklmnopqrstuvwxyz'
|
characters = '01234567890abcdefghijklmnopqrstuvwxyz'
|
||||||
choices = [random.choice(characters) for x in xrange(size)]
|
choices = [random.choice(characters) for x in xrange(size)]
|
||||||
@ -136,9 +141,10 @@ def generate_uid(topic, size=8):
|
|||||||
|
|
||||||
|
|
||||||
def generate_mac():
|
def generate_mac():
|
||||||
mac = [0x02, 0x16, 0x3e, random.randint(0x00, 0x7f),
|
mac = [0x02, 0x16, 0x3e,
|
||||||
random.randint(0x00, 0xff), random.randint(0x00, 0xff)
|
random.randint(0x00, 0x7f),
|
||||||
]
|
random.randint(0x00, 0xff),
|
||||||
|
random.randint(0x00, 0xff)]
|
||||||
return ':'.join(map(lambda x: "%02x" % x, mac))
|
return ':'.join(map(lambda x: "%02x" % x, mac))
|
||||||
|
|
||||||
|
|
||||||
@ -201,6 +207,7 @@ class LazyPluggable(object):
|
|||||||
backend = self.__get_backend()
|
backend = self.__get_backend()
|
||||||
return getattr(backend, key)
|
return getattr(backend, key)
|
||||||
|
|
||||||
|
|
||||||
def deferredToThread(f):
|
def deferredToThread(f):
|
||||||
def g(*args, **kwargs):
|
def g(*args, **kwargs):
|
||||||
return deferToThread(f, *args, **kwargs)
|
return deferToThread(f, *args, **kwargs)
|
||||||
|
@ -16,13 +16,15 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
"""
|
"""Decorators for argument validation, courtesy of
|
||||||
Decorators for argument validation, courtesy of
|
http://rmi.net/~lutz/rangetest.html"""
|
||||||
http://rmi.net/~lutz/rangetest.html
|
|
||||||
"""
|
|
||||||
|
|
||||||
def rangetest(**argchecks): # validate ranges for both+defaults
|
|
||||||
def onDecorator(func): # onCall remembers func and argchecks
|
def rangetest(**argchecks):
|
||||||
|
"""Validate ranges for both + defaults"""
|
||||||
|
|
||||||
|
def onDecorator(func):
|
||||||
|
"""onCall remembers func and argchecks"""
|
||||||
import sys
|
import sys
|
||||||
code = func.__code__ if sys.version_info[0] == 3 else func.func_code
|
code = func.__code__ if sys.version_info[0] == 3 else func.func_code
|
||||||
allargs = code.co_varnames[:code.co_argcount]
|
allargs = code.co_varnames[:code.co_argcount]
|
||||||
@ -38,7 +40,8 @@ def rangetest(**argchecks): # validate ranges for both+defaults
|
|||||||
# for all args to be checked
|
# for all args to be checked
|
||||||
if argname in kargs:
|
if argname in kargs:
|
||||||
# was passed by name
|
# was passed by name
|
||||||
if float(kargs[argname]) < low or float(kargs[argname]) > high:
|
if float(kargs[argname]) < low or \
|
||||||
|
float(kargs[argname]) > high:
|
||||||
errmsg = '{0} argument "{1}" not in {2}..{3}'
|
errmsg = '{0} argument "{1}" not in {2}..{3}'
|
||||||
errmsg = errmsg.format(funcname, argname, low, high)
|
errmsg = errmsg.format(funcname, argname, low, high)
|
||||||
raise TypeError(errmsg)
|
raise TypeError(errmsg)
|
||||||
@ -46,9 +49,12 @@ def rangetest(**argchecks): # validate ranges for both+defaults
|
|||||||
elif argname in positionals:
|
elif argname in positionals:
|
||||||
# was passed by position
|
# was passed by position
|
||||||
position = positionals.index(argname)
|
position = positionals.index(argname)
|
||||||
if float(pargs[position]) < low or float(pargs[position]) > high:
|
if float(pargs[position]) < low or \
|
||||||
errmsg = '{0} argument "{1}" with value of {4} not in {2}..{3}'
|
float(pargs[position]) > high:
|
||||||
errmsg = errmsg.format(funcname, argname, low, high, pargs[position])
|
errmsg = '{0} argument "{1}" with value of {4} ' \
|
||||||
|
'not in {2}..{3}'
|
||||||
|
errmsg = errmsg.format(funcname, argname, low, high,
|
||||||
|
pargs[position])
|
||||||
raise TypeError(errmsg)
|
raise TypeError(errmsg)
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
@ -76,12 +82,13 @@ def typetest(**argchecks):
|
|||||||
elif argname in positionals:
|
elif argname in positionals:
|
||||||
position = positionals.index(argname)
|
position = positionals.index(argname)
|
||||||
if not isinstance(pargs[position], typeof):
|
if not isinstance(pargs[position], typeof):
|
||||||
errmsg = '{0} argument "{1}" with value of {2} not of type {3}'
|
errmsg = '{0} argument "{1}" with value of {2} ' \
|
||||||
errmsg = errmsg.format(funcname, argname, pargs[position], typeof)
|
'not of type {3}'
|
||||||
|
errmsg = errmsg.format(funcname, argname,
|
||||||
|
pargs[position], typeof)
|
||||||
raise TypeError(errmsg)
|
raise TypeError(errmsg)
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
return func(*pargs, **kargs)
|
return func(*pargs, **kargs)
|
||||||
return onCall
|
return onCall
|
||||||
return onDecorator
|
return onDecorator
|
||||||
|
|
||||||
|
10
nova/wsgi.py
10
nova/wsgi.py
@ -240,6 +240,7 @@ class Controller(object):
|
|||||||
serializer = Serializer(request.environ, _metadata)
|
serializer = Serializer(request.environ, _metadata)
|
||||||
return serializer.deserialize(data)
|
return serializer.deserialize(data)
|
||||||
|
|
||||||
|
|
||||||
class Serializer(object):
|
class Serializer(object):
|
||||||
"""
|
"""
|
||||||
Serializes and deserializes dictionaries to certain MIME types.
|
Serializes and deserializes dictionaries to certain MIME types.
|
||||||
@ -263,7 +264,8 @@ class Serializer(object):
|
|||||||
elif 'application/xml' in req.accept:
|
elif 'application/xml' in req.accept:
|
||||||
self.handler = self._to_xml
|
self.handler = self._to_xml
|
||||||
else:
|
else:
|
||||||
self.handler = self._to_json # default
|
# This is the default
|
||||||
|
self.handler = self._to_json
|
||||||
|
|
||||||
def to_content_type(self, data):
|
def to_content_type(self, data):
|
||||||
"""
|
"""
|
||||||
@ -312,7 +314,8 @@ class Serializer(object):
|
|||||||
result[attr] = node.attributes[attr].nodeValue
|
result[attr] = node.attributes[attr].nodeValue
|
||||||
for child in node.childNodes:
|
for child in node.childNodes:
|
||||||
if child.nodeType != node.TEXT_NODE:
|
if child.nodeType != node.TEXT_NODE:
|
||||||
result[child.nodeName] = self._from_xml_node(child, listnames)
|
result[child.nodeName] = self._from_xml_node(child,
|
||||||
|
listnames)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _to_json(self, data):
|
def _to_json(self, data):
|
||||||
@ -347,7 +350,8 @@ class Serializer(object):
|
|||||||
else:
|
else:
|
||||||
node = self._to_xml_node(doc, metadata, k, v)
|
node = self._to_xml_node(doc, metadata, k, v)
|
||||||
result.appendChild(node)
|
result.appendChild(node)
|
||||||
else: # atom
|
else:
|
||||||
|
# Type is atom
|
||||||
node = doc.createTextNode(str(data))
|
node = doc.createTextNode(str(data))
|
||||||
result.appendChild(node)
|
result.appendChild(node)
|
||||||
return result
|
return result
|
||||||
|
2
pylintrc
2
pylintrc
@ -13,7 +13,7 @@ argument-rgx=[a-z_][a-z0-9_]{1,30}$
|
|||||||
|
|
||||||
# Method names should be at least 3 characters long
|
# Method names should be at least 3 characters long
|
||||||
# and be lowecased with underscores
|
# and be lowecased with underscores
|
||||||
method-rgx=[a-z_][a-z0-9_]{2,50}$
|
method-rgx=([a-z_][a-z0-9_]{2,50}|setUp|tearDown)$
|
||||||
|
|
||||||
# Module names matching nova-* are ok (files in bin/)
|
# Module names matching nova-* are ok (files in bin/)
|
||||||
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+)|(nova-[a-z0-9_-]+))$
|
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+)|(nova-[a-z0-9_-]+))$
|
||||||
|
Loading…
x
Reference in New Issue
Block a user