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