From 1aadd5e961a6f1983454f5f49f077f0be0d6cba8 Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Fri, 20 May 2011 12:53:49 +0400 Subject: added support for reserving certain network for certain project --- bin/nova-manage | 7 ++++--- nova/network/manager.py | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index db964064d..c64f25c23 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -515,11 +515,11 @@ class NetworkCommands(object): """Class for managing networks.""" def create(self, fixed_range=None, num_networks=None, - network_size=None, vlan_start=None, + network_size=None, vlan_start=None, project_id=None, vpn_start=None, fixed_range_v6=None, label='public'): """Creates fixed ips for host by range arguments: fixed_range=FLAG, [num_networks=FLAG], - [network_size=FLAG], [vlan_start=FLAG], + [network_size=FLAG], [vlan_start=FLAG], [project_id=None], [vpn_start=FLAG], [fixed_range_v6=FLAG]""" if not fixed_range: msg = _('Fixed range in the form of 10.0.0.0/8 is ' @@ -545,7 +545,8 @@ class NetworkCommands(object): vlan_start=int(vlan_start), vpn_start=int(vpn_start), cidr_v6=fixed_range_v6, - label=label) + label=label, + project_id=project_id) except ValueError, e: print e raise e diff --git a/nova/network/manager.py b/nova/network/manager.py index 5a6fdde5a..3422b72c1 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -564,6 +564,8 @@ class VlanManager(NetworkManager): net['dhcp_start'] = str(project_net[3]) net['vlan'] = vlan net['bridge'] = 'br%s' % vlan + if kwargs.has_key('project_id'): + net['project_id'] = kwargs['project_id'] if(FLAGS.use_ipv6): cidr_v6 = '%s/%s' % (fixed_net_v6[start_v6], significant_bits_v6) -- cgit From 4c1fd8a303a8eb1287fd83b04bd767171221d117 Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Mon, 30 May 2011 11:25:21 +0400 Subject: add support for keyword arguments --- bin/nova-manage | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/bin/nova-manage b/bin/nova-manage index c64f25c23..3d09f9064 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -1132,9 +1132,18 @@ def main(): action = argv.pop(0) matches = lazy_match(action, actions) action, fn = matches[0] + + fn_args, fn_kwargs = [], {} + for arg in argv: + if '=' in arg: + key, value = arg.split('=') + fn_kwargs[key] = value + else: + fn_args.append(arg) + # call the action with the remaining arguments try: - fn(*argv) + fn(*fn_args, **fn_kwargs) sys.exit(0) except TypeError: print _("Possible wrong number of arguments supplied") -- cgit From b85e089f807249eacc66172e56a1a69d450fafba Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Mon, 30 May 2011 11:30:22 +0400 Subject: project_id moved to be last --- bin/nova-manage | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 3d09f9064..8faf072bc 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -515,12 +515,12 @@ class NetworkCommands(object): """Class for managing networks.""" def create(self, fixed_range=None, num_networks=None, - network_size=None, vlan_start=None, project_id=None, - vpn_start=None, fixed_range_v6=None, label='public'): + network_size=None, vlan_start=None, vpn_start=None, + fixed_range_v6=None, label='public', project_id=None): """Creates fixed ips for host by range arguments: fixed_range=FLAG, [num_networks=FLAG], - [network_size=FLAG], [vlan_start=FLAG], [project_id=None], - [vpn_start=FLAG], [fixed_range_v6=FLAG]""" + [network_size=FLAG], [vlan_start=FLAG], [vpn_start=FLAG], + [fixed_range_v6=FLAG], [project_id=None]""" if not fixed_range: msg = _('Fixed range in the form of 10.0.0.0/8 is ' 'required to create networks.') -- cgit From f53e7d16181e0a7141956d835f71c09d76508c2d Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Thu, 9 Jun 2011 22:02:01 +0400 Subject: parse options with optparse, options prepended '--' --- bin/nova-manage | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 8faf072bc..76bed16f7 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -62,6 +62,8 @@ import sys import time import IPy +from inspect import getargspec +from optparse import OptionParser # If ../nova/__init__.py exists, add ../ to Python search path, so that # it will override what happens to be installed in /usr/(local/)lib/python... @@ -1133,14 +1135,18 @@ def main(): matches = lazy_match(action, actions) action, fn = matches[0] - fn_args, fn_kwargs = [], {} - for arg in argv: - if '=' in arg: - key, value = arg.split('=') - fn_kwargs[key] = value - else: - fn_args.append(arg) - + func_args = getargspec(fn).args + parser = OptionParser() + for arg in func_args: + dasharg = "--%s" % arg + parser.add_option(dasharg) + + (opts, fn_args) = parser.parse_args(argv) + fn_kwargs = vars(opts) + for k, v in fn_kwargs.items(): + if v is None: + del fn_kwargs[k] + # call the action with the remaining arguments try: fn(*fn_args, **fn_kwargs) -- cgit From 3f69522284833a52373ccf1e1006d9b2f20ccb06 Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Fri, 10 Jun 2011 17:33:54 +0400 Subject: decorators for action methods added --- .bzrignore | 3 +++ bin/nova-manage | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/.bzrignore b/.bzrignore index 14d8028f7..351b2bef7 100644 --- a/.bzrignore +++ b/.bzrignore @@ -13,3 +13,6 @@ nova/vcsversion.py clean.sqlite run_tests.log tests.sqlite +nova/tests/instance-* +tags + diff --git a/bin/nova-manage b/bin/nova-manage index 76bed16f7..2903e411c 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -105,6 +105,21 @@ flags.DEFINE_flag(flags.HelpshortFlag()) flags.DEFINE_flag(flags.HelpXMLFlag()) +# Decorators for actions +def positionargs(*args, **kwargs): + def _decorator(func): + req = args[-1] + func.__dict__['arguments'] = ' '.join("%s" % i for i in args[:req]) + func.__dict__['optargs'] = ' '.join("%s" % i for i in args[req:-1]) + return func + return _decorator + +def optionargs(*args, **kwargs): + def _decorator(func): + func.__dict__.setdefault('options', []).insert(0, (args, kwargs)) + return func + return _decorator + def param2id(object_id): """Helper function to convert various id types to internal id. args: [object_id], e.g. 'vol-0000000a' or 'volume-0000000a' or '10' @@ -515,7 +530,11 @@ class FloatingIpCommands(object): class NetworkCommands(object): """Class for managing networks.""" - + @optionargs('--project', dest="project_id", help='Project for network') + @optionargs('--vlan', dest="vlan_start", help='VLAN ID') + @positionargs('fixed_range', 'num_networks', + 'network_size', 'vlan_start', 'vpn_start', + 'fixed_range_v6', 'label', 'project_id', 1) def create(self, fixed_range=None, num_networks=None, network_size=None, vlan_start=None, vpn_start=None, fixed_range_v6=None, label='public', project_id=None): @@ -1135,25 +1154,25 @@ def main(): matches = lazy_match(action, actions) action, fn = matches[0] - func_args = getargspec(fn).args - parser = OptionParser() - for arg in func_args: - dasharg = "--%s" % arg - parser.add_option(dasharg) - + usage = "%prog " + "%s %s %s [%s] [options]" % (sys.argv[2], + sys.argv[3], fn.arguments, fn.optargs) + parser = OptionParser(usage=usage) + for ar, kw in fn.options: + parser.add_option(*ar, **kw) (opts, fn_args) = parser.parse_args(argv) fn_kwargs = vars(opts) + for k, v in fn_kwargs.items(): if v is None: del fn_kwargs[k] - + # call the action with the remaining arguments try: fn(*fn_args, **fn_kwargs) sys.exit(0) except TypeError: print _("Possible wrong number of arguments supplied") - print "%s %s: %s" % (category, action, fn.__doc__) + print "" raise except Exception: print _("Command failed, please check log for more info") -- cgit From 8de8ed78c2d3d6ca8342134234e0cc361611de54 Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Sat, 11 Jun 2011 00:30:30 +0400 Subject: removed posargs decorator, all methods decorated --- bin/nova-manage | 146 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 126 insertions(+), 20 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index ce9f07f56..0b92c349a 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -61,7 +61,6 @@ import sys import time import IPy -from inspect import getargspec from optparse import OptionParser # If ../nova/__init__.py exists, add ../ to Python search path, so that @@ -107,15 +106,7 @@ flags.DEFINE_flag(flags.HelpXMLFlag()) # Decorators for actions -def positionargs(*args, **kwargs): - def _decorator(func): - req = args[-1] - func.__dict__['arguments'] = ' '.join("%s" % i for i in args[:req]) - func.__dict__['optargs'] = ' '.join("%s" % i for i in args[req:-1]) - return func - return _decorator - -def optionargs(*args, **kwargs): +def args(*args, **kwargs): def _decorator(func): func.__dict__.setdefault('options', []).insert(0, (args, kwargs)) return func @@ -138,6 +129,7 @@ class VpnCommands(object): self.manager = manager.AuthManager() self.pipe = pipelib.CloudPipe() + @args('--project', dest="project", metavar='', help='Project name') def list(self, project=None): """Print a listing of the VPN data for one or all projects. @@ -183,10 +175,12 @@ class VpnCommands(object): self.pipe.launch_vpn_instance(p.id) time.sleep(10) + @args('--project', dest="project_id", metavar='', help='Project name') def run(self, project_id): """Start the VPN for a given project.""" self.pipe.launch_vpn_instance(project_id) + @args('--project', dest="project_id", metavar='', help='Project name') def change(self, project_id, ip, port): """Change the ip and port for a vpn. @@ -222,6 +216,7 @@ class ShellCommands(object): Falls back to Python shell if unavailable""" self.run('python') + @args('--shell', dest="shell", metavar='', help='Python shell') def run(self, shell=None): """Runs a Python interactive interpreter. @@ -259,6 +254,7 @@ class ShellCommands(object): readline.parse_and_bind("tab:complete") code.interact() + @args('--path', dest='path', metavar='', help='Script path') def script(self, path): """Runs the script from the specifed path with flags set properly. arguments: path""" @@ -271,12 +267,18 @@ class RoleCommands(object): def __init__(self): self.manager = manager.AuthManager() + @args('--user', dest="user", metavar='', help='User name') + @args('--role', dest="role", metavar='', help='User role') + @args('--project', dest="project", metavar='', help='Project name') def add(self, user, role, project=None): """adds role to user if project is specified, adds project specific role arguments: user, role [project]""" self.manager.add_role(user, role, project) + @args('--user', dest="user", metavar='', help='User name') + @args('--role', dest="role", metavar='', help='User role') + @args('--project', dest="project", metavar='', help='Project name') def has(self, user, role, project=None): """checks to see if user has role if project is specified, returns True if user has @@ -284,6 +286,9 @@ class RoleCommands(object): arguments: user, role [project]""" print self.manager.has_role(user, role, project) + @args('--user', dest="user", metavar='', help='User name') + @args('--role', dest="role", metavar='', help='User role') + @args('--project', dest="project", metavar='', help='Project name') def remove(self, user, role, project=None): """removes role from user if project is specified, removes project specific role @@ -311,6 +316,9 @@ class UserCommands(object): def __init__(self): self.manager = manager.AuthManager() + @args('--name', dest="name", metavar='', help='Admin name') + @args('--access', dest="access", metavar='', help='Access') + @args('--secret', dest="secret", metavar='', help='Secret') def admin(self, name, access=None, secret=None): """creates a new admin and prints exports arguments: name [access] [secret]""" @@ -320,6 +328,9 @@ class UserCommands(object): _db_error(e) self._print_export(user) + @args('--name', dest="name", metavar='', help='User name') + @args('--access', dest="access", metavar='', help='Access') + @args('--secret', dest="secret", metavar='', help='Secret') def create(self, name, access=None, secret=None): """creates a new user and prints exports arguments: name [access] [secret]""" @@ -329,11 +340,13 @@ class UserCommands(object): _db_error(e) self._print_export(user) + @args('--name', dest="name", metavar='', help='User name') def delete(self, name): """deletes an existing user arguments: name""" self.manager.delete_user(name) + @args('--name', dest="name", metavar='', help='User name') def exports(self, name): """prints access and secrets for user in export format arguments: name""" @@ -349,6 +362,10 @@ class UserCommands(object): for user in self.manager.get_users(): print user.name + @args('--name', dest="name", metavar='', help='User name') + @args('--access', dest="access_key", metavar='', help='Access key') + @args('--secret', dest="secret_key", metavar='', help='Secret key') + @args('--is_admin', dest='is_admin', metavar="<'T'|'F'>", help='Is admin?') def modify(self, name, access_key, secret_key, is_admin): """update a users keys & admin flag arguments: accesskey secretkey admin @@ -362,6 +379,8 @@ class UserCommands(object): is_admin = False self.manager.modify_user(name, access_key, secret_key, is_admin) + @args('--name', dest="user_id", metavar='', help='User name') + @args('--project', dest="project_id", metavar='', help='Project name') def revoke(self, user_id, project_id=None): """revoke certs for a user arguments: user_id [project_id]""" @@ -377,6 +396,8 @@ class ProjectCommands(object): def __init__(self): self.manager = manager.AuthManager() + @args('--project', dest="project_id", metavar='', help='Project name') + @args('--user', dest="user_id", metavar='', help='User name') def add(self, project_id, user_id): """Adds user to project arguments: project_id user_id""" @@ -386,6 +407,9 @@ class ProjectCommands(object): print ex raise + @args('--project', dest="name", metavar='', help='Project name') + @args('--user', dest="project_manager", metavar='', help='Project manager') + @args('--desc', dest="description", metavar='', help='Description') def create(self, name, project_manager, description=None): """Creates a new project arguments: name project_manager [description]""" @@ -395,6 +419,9 @@ class ProjectCommands(object): print ex raise + @args('--project', dest="name", metavar='', help='Project name') + @args('--user', dest="project_manager", metavar='', help='Project manager') + @args('--desc', dest="description", metavar='', help='Description') def modify(self, name, project_manager, description=None): """Modifies a project arguments: name project_manager [description]""" @@ -404,6 +431,7 @@ class ProjectCommands(object): print ex raise + @args('--project', dest="name", metavar='', help='Project name') def delete(self, name): """Deletes an existing project arguments: name""" @@ -413,6 +441,9 @@ class ProjectCommands(object): print ex raise + @args('--project', dest="project_id", metavar='', help='Project name') + @args('--user', dest="user_id", metavar='', help='User name') + @args('--file', dest="filename", metavar='', help='File name(Default: novarc)') def environment(self, project_id, user_id, filename='novarc'): """Exports environment variables to an sourcable file arguments: project_id user_id [filename='novarc]""" @@ -424,12 +455,16 @@ class ProjectCommands(object): with open(filename, 'w') as f: f.write(rc) + @args('--user', dest="username", metavar='', help='User name') def list(self, username=None): """Lists all projects arguments: [username]""" for project in self.manager.get_projects(username): print project.name + @args('--project', dest="project_id", metavar='', help='Project name') + @args('--key', dest="key", metavar='', help='Key') + @args('--value', dest="value", metavar='', help='Value') def quota(self, project_id, key=None, value=None): """Set or display quotas for project arguments: project_id [key] [value]""" @@ -447,6 +482,8 @@ class ProjectCommands(object): value = 'unlimited' print '%s: %s' % (key, value) + @args('--project', dest="project_id", metavar='', help='Project name') + @args('--user', dest="user_id", metavar='', help='User name') def remove(self, project_id, user_id): """Removes user from project arguments: project_id user_id""" @@ -456,6 +493,7 @@ class ProjectCommands(object): print ex raise + @args('--project', dest="project_id", metavar='', help='Project name') def scrub(self, project_id): """Deletes data associated with project arguments: project_id""" @@ -466,6 +504,9 @@ class ProjectCommands(object): for group in groups: db.security_group_destroy(ctxt, group['id']) + @args('--project', dest="project_id", metavar='', help='Project name') + @args('--user', dest="user_id", metavar='', help='User name') + @args('--file', dest="filename", metavar='', help='File name(Default: nova.zip)') def zipfile(self, project_id, user_id, filename='nova.zip'): """Exports credentials for project to a zip file arguments: project_id user_id [filename='nova.zip]""" @@ -492,6 +533,7 @@ AccountCommands = ProjectCommands class FixedIpCommands(object): """Class for managing fixed ip.""" + @args('--host', dest="host", metavar='', help='Host') def list(self, host=None): """Lists all fixed ips (optionally by host) arguments: [host]""" ctxt = context.get_admin_context() @@ -528,6 +570,8 @@ class FixedIpCommands(object): class FloatingIpCommands(object): """Class for managing floating ip.""" + @args('--host', dest="host", metavar='', help='Host') + @args('--ip_range', dest="range", metavar='', help='IP range') def create(self, host, range): """Creates floating ips for host by range arguments: host ip_range""" @@ -536,6 +580,7 @@ class FloatingIpCommands(object): {'address': str(address), 'host': host}) + @args('--ip_range', dest="ip_range", metavar='', help='IP range') def delete(self, ip_range): """Deletes floating ips by range arguments: range""" @@ -543,6 +588,7 @@ class FloatingIpCommands(object): db.floating_ip_destroy(context.get_admin_context(), str(address)) + @args('--host', dest="host", metavar='', help='Host') def list(self, host=None): """Lists all floating ips (optionally by host) arguments: [host]""" @@ -563,11 +609,14 @@ class FloatingIpCommands(object): class NetworkCommands(object): """Class for managing networks.""" - @optionargs('--project', dest="project_id", help='Project for network') - @optionargs('--vlan', dest="vlan_start", help='VLAN ID') - @positionargs('fixed_range', 'num_networks', - 'network_size', 'vlan_start', 'vpn_start', - 'fixed_range_v6', 'gateway_v6', 'label', 'project_id', 1) + @args('--network', dest="fixed_range", metavar='', help='Network') + @args('--num_networks', dest="num_networks", metavar='', help='How many networks create') + @args('--network_size', dest="network_size", metavar='', help='How many hosts in network') + @args('--vlan', dest="vlan_start", metavar='', help='vlan id') + @args('--vpn', dest="vpn_start", help='vpn start') + @args('--fixed_range_v6', dest="fixed_range_v6", help='fixed ipv6 range') + @args('--gateway_v6', dest="gateway_v6", help='ipv6 gateway') + @args('--project', dest="project_id", metavar='', help='Project for network') def create(self, fixed_range=None, num_networks=None, network_size=None, vlan_start=None, vpn_start=None, fixed_range_v6=None, gateway_v6=None, label='public', project_id=None): @@ -618,6 +667,7 @@ class NetworkCommands(object): network.dhcp_start, network.dns) + @args('--network', dest="fixed_range", metavar='', help='Network to delete') def delete(self, fixed_range): """Deletes a network""" network = db.network_get_by_cidr(context.get_admin_context(), \ @@ -631,6 +681,7 @@ class NetworkCommands(object): class VmCommands(object): """Class for mangaging VM instances.""" + @args('--host', dest="host", metavar='', help='Host') def list(self, host=None): """Show a list of all instances @@ -674,6 +725,8 @@ class VmCommands(object): instance['availability_zone'], instance['launch_index']) + @args('--ec2_id', dest='ec2_id', metavar='', help='EC2 ID') + @args('--dest', dest='dest', metavar='', help='destanation node') def live_migration(self, ec2_id, dest): """Migrates a running instance to a new machine. @@ -710,6 +763,8 @@ class VmCommands(object): class ServiceCommands(object): """Enable and disable running services""" + @args('--host', dest='host', metavar='', help='Host') + @args('--service', dest='service', metavar='', help='Nova service') def list(self, host=None, service=None): """Show a list of all running services. Filter by host & service name. args: [host] [service]""" @@ -731,6 +786,8 @@ class ServiceCommands(object): active, art, svc['updated_at']) + @args('--host', dest='host', metavar='', help='Host') + @args('--service', dest='service', metavar='', help='Nova service') def enable(self, host, service): """Enable scheduling for a service args: host service""" @@ -741,6 +798,8 @@ class ServiceCommands(object): return db.service_update(ctxt, svc['id'], {'disabled': False}) + @args('--host', dest='host', metavar='', help='Host') + @args('--service', dest='service', metavar='', help='Nova service') def disable(self, host, service): """Disable scheduling for a service args: host service""" @@ -751,6 +810,7 @@ class ServiceCommands(object): return db.service_update(ctxt, svc['id'], {'disabled': True}) + @args('--host', dest='host', metavar='', help='Host') def describe_resource(self, host): """Describes cpu/memory/hdd info for host. @@ -784,6 +844,7 @@ class ServiceCommands(object): val['memory_mb'], val['local_gb']) + @args('--host', dest='host', metavar='', help='Host') def update_resource(self, host): """Updates available vcpu/memory/disk info for host. @@ -811,6 +872,7 @@ class DbCommands(object): def __init__(self): pass + @args('--version', dest='version', metavar='', help='Database version') def sync(self, version=None): """Sync the database up to the most recent version.""" return migration.db_sync(version) @@ -834,10 +896,11 @@ class VersionCommands(object): class VolumeCommands(object): """Methods for dealing with a cloud in an odd state""" + @args('--volume', dest='volume_id', metavar='', help='Volume ID') def delete(self, volume_id): """Delete a volume, bypassing the check that it must be available. - args: volume_id_id""" + args: volume_id""" ctxt = context.get_admin_context() volume = db.volume_get(ctxt, param2id(volume_id)) host = volume['host'] @@ -858,6 +921,7 @@ class VolumeCommands(object): {"method": "delete_volume", "args": {"volume_id": volume['id']}}) + @args('--volume', dest='volume_id', metavar='', help='Volume ID') def reattach(self, volume_id): """Re-attach a volume that has previously been attached to an instance. Typically called after a compute host @@ -889,6 +953,14 @@ class InstanceTypeCommands(object): val["flavorid"], val["swap"], val["rxtx_quota"], val["rxtx_cap"], deleted) + @args('--name', dest='name', metavar='', help='Name of instance type/flavor') + @args('--memory', dest='memory', metavar='', help='Memory size') + @args('--cpu', dest='vcpus', metavar='', help='Number cpus') + @args('--local_gb', dest='local_gb', metavar='', help='local_gb') + @args('--flavor', dest='flavorid', metavar='', help='Flavor ID') + @args('--swap', dest='swap', metavar='', help='Swap') + @args('--rxtx_quota', dest='rxtx_quota', metavar='', help='rxtx_quota') + @args('--rxtx_cap', dest='rxtx_cap', metavar='', help='rxtx_cap') def create(self, name, memory, vcpus, local_gb, flavorid, swap=0, rxtx_quota=0, rxtx_cap=0): """Creates instance types / flavors @@ -917,6 +989,7 @@ class InstanceTypeCommands(object): else: print "%s created" % name + @args('--name', dest='name', metavar='', help='Name of instance type/flavor') def delete(self, name, purge=None): """Marks instance types / flavors as deleted arguments: name""" @@ -938,6 +1011,7 @@ class InstanceTypeCommands(object): else: print "%s %s" % (name, verb) + @args('--name', dest='name', metavar='', help='Name of instance type/flavor') def list(self, name=None): """Lists all active or specific instance types / flavors arguments: [name]""" @@ -988,6 +1062,13 @@ class ImageCommands(object): except Exception as exc: print _("Failed to register %(path)s: %(exc)s") % locals() + @args('--image', dest='image', metavar='', help='Image') + @args('--kernel', dest='kernel', metavar='', help='Kernel') + @args('--ram', dest='ramdisk', metavar='', help='RAM disk') + @args('--owner', dest='owner', metavar='', help='Image owner') + @args('--name', dest='name', metavar='', help='Image name') + @args('--public', dest='is_public', metavar="<'T'|'F'>", help='Image public or not') + @args('--arch', dest='architecture', metavar='', help='Architecture') def all_register(self, image, kernel, ramdisk, owner, name=None, is_public='T', architecture='x86_64'): """Uploads an image, kernel, and ramdisk into the image_service @@ -1001,6 +1082,15 @@ class ImageCommands(object): architecture, 'ami', 'ami', kernel_id, ramdisk_id) + @args('--path', dest='path', metavar='', help='Image path') + @args('--owner', dest='owner', metavar='', help='Image owner') + @args('--name', dest='name', metavar='', help='Image name') + @args('--public', dest='is_public', metavar="<'T'|'F'>", help='Image public or not') + @args('--arch', dest='architecture', metavar='', help='Architecture') + @args('--cont_format', dest='container_format', metavar='', help='Container format(default: bare)') + @args('--disk_format', dest='disk_format', metavar='', help='Disk format(default: raw)') + @args('--kernel', dest='kernel_id', metavar='', help='Kernel') + @args('--ram', dest='ramdisk_id', metavar='', help='RAM disk') def image_register(self, path, owner, name=None, is_public='T', architecture='x86_64', container_format='bare', disk_format='raw', kernel_id=None, ramdisk_id=None): @@ -1013,6 +1103,11 @@ class ImageCommands(object): owner, name, is_public, architecture, kernel_id, ramdisk_id) + @args('--path', dest='path', metavar='', help='Image path') + @args('--owner', dest='owner', metavar='', help='Image owner') + @args('--name', dest='name', metavar='', help='Image name') + @args('--public', dest='is_public', metavar="<'T'|'F'>", help='Image public or not') + @args('--arch', dest='architecture', metavar='', help='Architecture') def kernel_register(self, path, owner, name=None, is_public='T', architecture='x86_64'): """Uploads a kernel into the image_service @@ -1021,6 +1116,11 @@ class ImageCommands(object): return self._register('aki', 'aki', path, owner, name, is_public, architecture) + @args('--path', dest='path', metavar='', help='Image path') + @args('--owner', dest='owner', metavar='', help='Image owner') + @args('--name', dest='name', metavar='', help='Image name') + @args('--public', dest='is_public', metavar="<'T'|'F'>", help='Image public or not') + @args('--arch', dest='architecture', metavar='', help='Architecture') def ramdisk_register(self, path, owner, name=None, is_public='T', architecture='x86_64'): """Uploads a ramdisk into the image_service @@ -1074,6 +1174,7 @@ class ImageCommands(object): except Exception as exc: print _("Failed to convert %(old)s: %(exc)s") % locals() + @args('--dir', dest='directory', metavar='', help='Images directory') def convert(self, directory): """Uploads old objectstore images in directory to new service arguments: directory""" @@ -1199,10 +1300,14 @@ def main(): matches = lazy_match(action, actions) action, fn = matches[0] - usage = "%prog " + "%s %s %s [%s] [options]" % (sys.argv[2], - sys.argv[3], fn.arguments, fn.optargs) + # For not decorated methods + arguments = getattr(fn ,'arguments', '') + optargs = getattr(fn ,'optargs', '') + options = getattr(fn ,'options', '') + + usage = "%prog " + "%s %s [options]" % (sys.argv[2], sys.argv[3]) parser = OptionParser(usage=usage) - for ar, kw in fn.options: + for ar, kw in options: parser.add_option(*ar, **kw) (opts, fn_args) = parser.parse_args(argv) fn_kwargs = vars(opts) @@ -1217,7 +1322,8 @@ def main(): sys.exit(0) except TypeError: print _("Possible wrong number of arguments supplied") - print "" + print fn.__doc__ + parser.print_help() raise except Exception: print _("Command failed, please check log for more info") -- cgit From 8ded8e4bde3825efc8a886aad40d54d0c9d126dc Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Sat, 11 Jun 2011 00:42:44 +0400 Subject: small pep8 fixes --- bin/nova-manage | 6 +++--- nova/network/manager.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 0b92c349a..23ebe3c93 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -1301,9 +1301,9 @@ def main(): action, fn = matches[0] # For not decorated methods - arguments = getattr(fn ,'arguments', '') - optargs = getattr(fn ,'optargs', '') - options = getattr(fn ,'options', '') + arguments = getattr(fn, 'arguments', '') + optargs = getattr(fn, 'optargs', '') + options = getattr(fn, 'options', '') usage = "%prog " + "%s %s [options]" % (sys.argv[2], sys.argv[3]) parser = OptionParser(usage=usage) diff --git a/nova/network/manager.py b/nova/network/manager.py index ad93114fe..a7f5aac60 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -571,7 +571,7 @@ class VlanManager(NetworkManager): net['dhcp_start'] = str(project_net[3]) net['vlan'] = vlan net['bridge'] = 'br%s' % vlan - if kwargs.has_key('project_id'): + if 'project_id' in kwargs: net['project_id'] = kwargs['project_id'] if(FLAGS.use_ipv6): cidr_v6 = '%s/%s' % (fixed_net_v6[start_v6], -- cgit From 3a83aaf4f14ac25dee8b5a84779a61ca4633012a Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Sat, 11 Jun 2011 00:49:03 +0400 Subject: 'network list' prints project id --- bin/nova-manage | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 23ebe3c93..67cf0bd51 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -657,15 +657,17 @@ class NetworkCommands(object): def list(self): """List all created networks""" - print "%-18s\t%-15s\t%-15s\t%-15s" % (_('network'), + print "%-18s\t%-15s\t%-15s\t%-15s\t%-15s" % (_('network'), _('netmask'), _('start address'), - 'DNS') + 'DNS', + 'project') for network in db.network_get_all(context.get_admin_context()): - print "%-18s\t%-15s\t%-15s\t%-15s" % (network.cidr, + print "%-18s\t%-15s\t%-15s\t%-15s\t%-15s" % (network.cidr, network.netmask, network.dhcp_start, - network.dns) + network.dns, + network.project_id) @args('--network', dest="fixed_range", metavar='', help='Network to delete') def delete(self, fixed_range): -- cgit From faed18358f534ed7a743fcd168d649d06da092ab Mon Sep 17 00:00:00 2001 From: Arvind Somy Date: Fri, 17 Jun 2011 14:02:24 -0400 Subject: Fix for Bug lp:796813 - Adding support for distributed virtual portgroups on vmware ESX(i) --- Authors | 1 + nova/virt/vmwareapi/network_utils.py | 29 ++++++++++++++++++++++++----- nova/virt/vmwareapi/vm_util.py | 23 ++++++++++++++++++----- nova/virt/vmwareapi/vmops.py | 7 ++++--- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/Authors b/Authors index 94fcf7f5b..0d79af2c7 100644 --- a/Authors +++ b/Authors @@ -6,6 +6,7 @@ Anne Gentle Anthony Young Antony Messerli Armando Migliaccio +Arvind Somya Bilal Akhtar Brian Lamar Brian Schott diff --git a/nova/virt/vmwareapi/network_utils.py b/nova/virt/vmwareapi/network_utils.py index e77842535..345cd2bd0 100644 --- a/nova/virt/vmwareapi/network_utils.py +++ b/nova/virt/vmwareapi/network_utils.py @@ -45,11 +45,30 @@ def get_network_with_the_name(session, network_name="vmnet0"): networks = session._call_method(vim_util, "get_properties_for_a_collection_of_objects", "Network", vm_networks, ["summary.name"]) - for network in networks: - if network.propSet[0].val == network_name: - return network.obj - return None - + network_obj = {} + for network in vm_networks: + # Get network properties + if network._type == 'DistributedVirtualPortgroup': + props = session._call_method(vim_util, + "get_dynamic_property",network, + "DistributedVirtualPortgroup","config") + # NOTE: This only works on ESXi if the port binding is + # set to ephemeral + if props.name == network_name: + network_obj['type'] = 'DistributedVirtualPortgroup' + network_obj['dvpg'] = props.key + network_obj['dvsw'] = props.distributedVirtualSwitch.value + else: + props = session._call_method(vim_util, + "get_dynamic_property",network, + "Network","summary.name") + if props == network_name: + network_obj['type'] = 'Network' + network_obj['name'] = network_name + if (len(network_obj) > 0): + return network_obj + else: + return None def get_vswitch_for_vlan_interface(session, vlan_interface): """ diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index a2fa7600c..d23472469 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -40,7 +40,7 @@ def split_datastore_path(datastore_path): def get_vm_create_spec(client_factory, instance, data_store_name, network_name="vmnet0", - os_type="otherGuest"): + os_type="otherGuest", network_ref=None): """Builds the VM Create spec.""" config_spec = client_factory.create('ns0:VirtualMachineConfigSpec') config_spec.name = instance.name @@ -89,7 +89,7 @@ def create_controller_spec(client_factory, key): return virtual_device_config -def create_network_spec(client_factory, network_name, mac_address): +def create_network_spec(client_factory, network_name, mac_address,network_ref=None): """ Builds a config spec for the addition of a new network adapter to the VM. @@ -101,9 +101,22 @@ def create_network_spec(client_factory, network_name, mac_address): # Get the recommended card type for the VM based on the guest OS of the VM net_device = client_factory.create('ns0:VirtualPCNet32') - backing = \ - client_factory.create('ns0:VirtualEthernetCardNetworkBackingInfo') - backing.deviceName = network_name + # NOTE: Only works on ESXi if the portgroup binding is set to + # ephemeral. Invalid configuration if set to static and the NIC does + # not come up on boot if set to dynamic. + backing = None + if (network_ref['type'] == "DistributedVirtualPortgroup"): + backing = \ + client_factory.create('ns0:VirtualEthernetCardDistributedVirtualPortBackingInfo') + portgroup = \ + client_factory.create('ns0:DistributedVirtualSwitchPortConnection') + portgroup.switchUuid = network_ref['dvsw'] + portgroup.portgroupKey = network_ref['dvpg'] + backing.port = portgroup + else: + backing = \ + client_factory.create('ns0:VirtualEthernetCardNetworkBackingInfo') + backing.deviceName = network_name connectable_spec = \ client_factory.create('ns0:VirtualDeviceConnectInfo') diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 5f76b0df5..d23edbdf8 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -116,8 +116,9 @@ class VMWareVMOps(object): net_name) if network_ref is None: raise exception.NetworkNotFoundForBridge(bridge=net_name) - - _check_if_network_bridge_exists() + return network_ref + + network_obj = _check_if_network_bridge_exists() def _get_datastore_ref(): """Get the datastore list and choose the first local storage.""" @@ -176,7 +177,7 @@ class VMWareVMOps(object): # Get the create vm config spec config_spec = vm_util.get_vm_create_spec(client_factory, instance, - data_store_name, net_name, os_type) + data_store_name, net_name, os_type, network_obj) def _execute_create_vm(): """Create VM on ESX host.""" -- cgit From c3af5e65508fb325a4a8e350c9ed6d84d87e7cd8 Mon Sep 17 00:00:00 2001 From: Arvind Somy Date: Fri, 17 Jun 2011 15:12:01 -0400 Subject: Fix for lp:796834 - Fixes and enhancements to the ESX(i) guest_tool.py script. --- nova/virt/vmwareapi/vm_util.py | 4 ++-- nova/virt/vmwareapi/vmops.py | 5 ++++- tools/esx/guest_tool.py | 49 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index d23472469..c823ac710 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -287,9 +287,9 @@ def get_dummy_vm_create_spec(client_factory, name, data_store_name): return config_spec -def get_machine_id_change_spec(client_factory, mac, ip_addr, netmask, gateway): +def get_machine_id_change_spec(client_factory, mac, ip_addr, netmask, gateway, broadcast, dns): """Builds the machine id change config spec.""" - machine_id_str = "%s;%s;%s;%s" % (mac, ip_addr, netmask, gateway) + machine_id_str = "%s;%s;%s;%s;%s;%s" % (mac, ip_addr, netmask, gateway, broadcast, dns) virtual_machine_config_spec = \ client_factory.create('ns0:VirtualMachineConfigSpec') diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index d23edbdf8..9f2a36bf4 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -715,11 +715,14 @@ class VMWareVMOps(object): mac_addr = instance.mac_address net_mask = network["netmask"] gateway = network["gateway"] + broadcast = network["broadcast"] + dns = network["dns"] ip_addr = db.instance_get_fixed_address(context.get_admin_context(), instance['id']) machine_id_chanfge_spec = \ vm_util.get_machine_id_change_spec(client_factory, mac_addr, - ip_addr, net_mask, gateway) + ip_addr, net_mask, gateway, + broadcast, dns) LOG.debug(_("Reconfiguring VM instance %(name)s to set the machine id " "with ip - %(ip_addr)s") % ({'name': instance.name, diff --git a/tools/esx/guest_tool.py b/tools/esx/guest_tool.py index 13b0f8d33..e126721d5 100644 --- a/tools/esx/guest_tool.py +++ b/tools/esx/guest_tool.py @@ -21,6 +21,7 @@ On Windows we require pyWin32 installed on Python. """ import array +import gettext import logging import os import platform @@ -30,6 +31,8 @@ import subprocess import sys import time +_ = gettext.gettext + PLATFORM_WIN = 'win32' PLATFORM_LINUX = 'linux2' ARCH_32_BIT = '32bit' @@ -314,6 +317,43 @@ def _set_rhel_networking(network_details=[]): dns_file.close() _execute(['/sbin/service', 'network', 'restart']) +def _set_ubuntu_networking(network_details=[]): + """ Set IPv4 network settings for Ubuntu """ + all_dns_servers = [] + for network_detail in network_details: + mac_address, ip_address, subnet_mask, gateway, broadcast,\ + dns_servers = network_detail + all_dns_servers.extend(dns_servers) + adapter_name, current_ip_address = \ + _get_linux_adapter_name_and_ip_address(mac_address) + + if adapter_name and not ip_address == current_ip_address: + interface_file_name = \ + '/etc/network/interfaces' + # Remove file + os.remove(interface_file_name) + # Touch file + _execute(['touch', interface_file_name]) + interface_file = open(interface_file_name, 'w') + interface_file.write('\nauto %s' % adapter_name) + interface_file.write('\niface %s inet static' % adapter_name) + interface_file.write('\nbroadcast %s' % broadcast) + interface_file.write('\ngateway %s' % gateway) + interface_file.write('\nnetmask %s' % subnet_mask) + interface_file.write('\naddress %s' % ip_address) + interface_file.close() + if all_dns_servers: + dns_file_name = "/etc/resolv.conf" + os.remove(dns_file_name) + _execute(['touch', dns_file_name]) + dns_file = open(dns_file_name, 'w') + dns_file.write("; generated by OpenStack guest tools") + unique_entries = _filter_duplicates(all_dns_servers) + for dns_server in unique_entries: + dns_file.write("\nnameserver %s" % dns_server) + dns_file.close() + print "\nRestarting networking....\n" + _execute(['/etc/init.d/networking', 'restart']) def _linux_set_networking(): """Set IP address for the Linux VM.""" @@ -330,8 +370,13 @@ def _linux_set_networking(): cmd = [vmware_tools_bin, '--cmd', 'machine.id.get'] network_details = _parse_network_details(_execute(cmd, check_exit_code=False)) - # TODO(sateesh): For other distros like ubuntu, suse, debian, BSD, etc. - _set_rhel_networking(network_details) + # TODO(sateesh): For other distros like suse, debian, BSD, etc. + if(platform.dist()[0] == 'Ubuntu') : + _set_ubuntu_networking(network_details) + elif (platform.dist()[0] == 'redhat') : + _set_rhel_networking(network_details) + else: + logging.warn(_("Distro '%s' not supported") % platform.dist()[0]) else: logging.warn(_("VMware Tools is not installed")) -- cgit From 03db1b862f38fa864316530c0a0b22ef74f25c81 Mon Sep 17 00:00:00 2001 From: "Arvind Somya asomya@cisco.com" <> Date: Fri, 24 Jun 2011 12:15:13 -0400 Subject: Fixing PEP8 compliance issues. --- nova/virt/vmwareapi/network_utils.py | 11 ++++++----- nova/virt/vmwareapi/vm_util.py | 5 +++-- nova/virt/vmwareapi/vmops.py | 8 +++++--- tools/esx/guest_tool.py | 6 ++++-- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/nova/virt/vmwareapi/network_utils.py b/nova/virt/vmwareapi/network_utils.py index 345cd2bd0..08e3bf0b1 100644 --- a/nova/virt/vmwareapi/network_utils.py +++ b/nova/virt/vmwareapi/network_utils.py @@ -50,9 +50,9 @@ def get_network_with_the_name(session, network_name="vmnet0"): # Get network properties if network._type == 'DistributedVirtualPortgroup': props = session._call_method(vim_util, - "get_dynamic_property",network, - "DistributedVirtualPortgroup","config") - # NOTE: This only works on ESXi if the port binding is + "get_dynamic_property", network, + "DistributedVirtualPortgroup", "config") + # NOTE(asomya): This only works on ESXi if the port binding is # set to ephemeral if props.name == network_name: network_obj['type'] = 'DistributedVirtualPortgroup' @@ -60,8 +60,8 @@ def get_network_with_the_name(session, network_name="vmnet0"): network_obj['dvsw'] = props.distributedVirtualSwitch.value else: props = session._call_method(vim_util, - "get_dynamic_property",network, - "Network","summary.name") + "get_dynamic_property", network, + "Network", "summary.name") if props == network_name: network_obj['type'] = 'Network' network_obj['name'] = network_name @@ -70,6 +70,7 @@ def get_network_with_the_name(session, network_name="vmnet0"): else: return None + def get_vswitch_for_vlan_interface(session, vlan_interface): """ Gets the vswitch associated with the physical network adapter diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index c823ac710..411305081 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -89,7 +89,8 @@ def create_controller_spec(client_factory, key): return virtual_device_config -def create_network_spec(client_factory, network_name, mac_address,network_ref=None): +def create_network_spec(client_factory, network_name, mac_address, + network_ref=None): """ Builds a config spec for the addition of a new network adapter to the VM. @@ -101,7 +102,7 @@ def create_network_spec(client_factory, network_name, mac_address,network_ref=No # Get the recommended card type for the VM based on the guest OS of the VM net_device = client_factory.create('ns0:VirtualPCNet32') - # NOTE: Only works on ESXi if the portgroup binding is set to + # NOTE: Only works on ESXi if the portgroup binding is set to # ephemeral. Invalid configuration if set to static and the NIC does # not come up on boot if set to dynamic. backing = None diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 9f2a36bf4..6f8b823c5 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -117,7 +117,7 @@ class VMWareVMOps(object): if network_ref is None: raise exception.NetworkNotFoundForBridge(bridge=net_name) return network_ref - + network_obj = _check_if_network_bridge_exists() def _get_datastore_ref(): @@ -176,8 +176,10 @@ class VMWareVMOps(object): vm_folder_mor, res_pool_mor = _get_vmfolder_and_res_pool_mors() # Get the create vm config spec - config_spec = vm_util.get_vm_create_spec(client_factory, instance, - data_store_name, net_name, os_type, network_obj) + config_spec = vm_util.get_vm_create_spec( + client_factory, instance, + data_store_name, net_name, os_type, + network_obj) def _execute_create_vm(): """Create VM on ESX host.""" diff --git a/tools/esx/guest_tool.py b/tools/esx/guest_tool.py index e126721d5..3463be5dd 100644 --- a/tools/esx/guest_tool.py +++ b/tools/esx/guest_tool.py @@ -317,6 +317,7 @@ def _set_rhel_networking(network_details=[]): dns_file.close() _execute(['/sbin/service', 'network', 'restart']) + def _set_ubuntu_networking(network_details=[]): """ Set IPv4 network settings for Ubuntu """ all_dns_servers = [] @@ -355,6 +356,7 @@ def _set_ubuntu_networking(network_details=[]): print "\nRestarting networking....\n" _execute(['/etc/init.d/networking', 'restart']) + def _linux_set_networking(): """Set IP address for the Linux VM.""" vmware_tools_bin = None @@ -371,9 +373,9 @@ def _linux_set_networking(): network_details = _parse_network_details(_execute(cmd, check_exit_code=False)) # TODO(sateesh): For other distros like suse, debian, BSD, etc. - if(platform.dist()[0] == 'Ubuntu') : + if(platform.dist()[0] == 'Ubuntu'): _set_ubuntu_networking(network_details) - elif (platform.dist()[0] == 'redhat') : + elif (platform.dist()[0] == 'redhat'): _set_rhel_networking(network_details) else: logging.warn(_("Distro '%s' not supported") % platform.dist()[0]) -- cgit From 8ec448d2bcf4afce7d0486d9cf6b07e0e30bd6be Mon Sep 17 00:00:00 2001 From: "Arvind Somya asomya@cisco.com" <> Date: Fri, 24 Jun 2011 12:22:14 -0400 Subject: Fixed the default arguments to None instead of an empty list. --- tools/esx/guest_tool.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/esx/guest_tool.py b/tools/esx/guest_tool.py index 3463be5dd..60ecfcd20 100644 --- a/tools/esx/guest_tool.py +++ b/tools/esx/guest_tool.py @@ -278,7 +278,8 @@ def _filter_duplicates(all_entries): return final_list -def _set_rhel_networking(network_details=[]): +def _set_rhel_networking(network_details=None): + network_details = network_details or [] all_dns_servers = [] for network_detail in network_details: mac_address, ip_address, subnet_mask, gateway, broadcast,\ @@ -318,7 +319,8 @@ def _set_rhel_networking(network_details=[]): _execute(['/sbin/service', 'network', 'restart']) -def _set_ubuntu_networking(network_details=[]): +def _set_ubuntu_networking(network_details=None): + network_details = network_details or [] """ Set IPv4 network settings for Ubuntu """ all_dns_servers = [] for network_detail in network_details: -- cgit From 43713a2e45862219c538ede60363053d36bb0f1b Mon Sep 17 00:00:00 2001 From: Arvind Somy Date: Mon, 27 Jun 2011 14:41:07 -0400 Subject: - Modified NOTE in vm_util.py - Changed gettext line to nova default in guest_tool.py --- nova/virt/vmwareapi/vm_util.py | 2 +- tools/esx/guest_tool.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index 411305081..b93c1f81b 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -102,7 +102,7 @@ def create_network_spec(client_factory, network_name, mac_address, # Get the recommended card type for the VM based on the guest OS of the VM net_device = client_factory.create('ns0:VirtualPCNet32') - # NOTE: Only works on ESXi if the portgroup binding is set to + # NOTE(asomya): Only works on ESXi if the portgroup binding is set to # ephemeral. Invalid configuration if set to static and the NIC does # not come up on boot if set to dynamic. backing = None diff --git a/tools/esx/guest_tool.py b/tools/esx/guest_tool.py index 60ecfcd20..97b5302ba 100644 --- a/tools/esx/guest_tool.py +++ b/tools/esx/guest_tool.py @@ -31,7 +31,7 @@ import subprocess import sys import time -_ = gettext.gettext +gettext.install('nova', unicode=1) PLATFORM_WIN = 'win32' PLATFORM_LINUX = 'linux2' -- cgit From ff195162d97f4a1ffaa6127f92cca102705b023b Mon Sep 17 00:00:00 2001 From: Lvov Maxim Date: Tue, 28 Jun 2011 16:46:50 +0400 Subject: remove network to project bind --- bin/nova-manage | 5 ++--- nova/network/manager.py | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/bin/nova-manage b/bin/nova-manage index 67cf0bd51..a4b221b8c 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -619,7 +619,7 @@ class NetworkCommands(object): @args('--project', dest="project_id", metavar='', help='Project for network') def create(self, fixed_range=None, num_networks=None, network_size=None, vlan_start=None, vpn_start=None, fixed_range_v6=None, - gateway_v6=None, label='public', project_id=None): + gateway_v6=None, label='public'): """Creates fixed ips for host by range""" if not fixed_range: @@ -649,8 +649,7 @@ class NetworkCommands(object): vpn_start=int(vpn_start), cidr_v6=fixed_range_v6, gateway_v6=gateway_v6, - label=label, - project_id=project_id) + label=label) except ValueError, e: print e raise e diff --git a/nova/network/manager.py b/nova/network/manager.py index a7f5aac60..b5352ca0f 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -571,8 +571,6 @@ class VlanManager(NetworkManager): net['dhcp_start'] = str(project_net[3]) net['vlan'] = vlan net['bridge'] = 'br%s' % vlan - if 'project_id' in kwargs: - net['project_id'] = kwargs['project_id'] if(FLAGS.use_ipv6): cidr_v6 = '%s/%s' % (fixed_net_v6[start_v6], significant_bits_v6) -- cgit From b8b96769bfc49e75d2eee3ae561e4e9ee7615473 Mon Sep 17 00:00:00 2001 From: Yoshiaki Tamura Date: Mon, 4 Jul 2011 13:53:17 +0900 Subject: Fix boot from volume failure for network block devices. This patch looks up the device_path and swithes between 'block' and 'network' when creating libvirt.xml. --- nova/virt/libvirt.xml.template | 6 +++++- nova/virt/libvirt/connection.py | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index e1a683da8..36d8c5aaa 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -82,9 +82,13 @@ #end if #for $vol in $volumes - + + #if $vol.type == 'network' + + #else + #end if #end for diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index 0c6eaab84..3168bb9df 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -971,6 +971,7 @@ class LibvirtConnection(driver.ComputeDriver): return True return False + @exception.wrap_exception def _prepare_xml_info(self, instance, rescue=False, network_info=None, block_device_mapping=None): block_device_mapping = block_device_mapping or [] @@ -993,6 +994,16 @@ class LibvirtConnection(driver.ComputeDriver): for vol in block_device_mapping: vol['mount_device'] = _strip_dev(vol['mount_device']) + if vol['device_path'].startswith('/dev/'): + vol['type'] = 'block' + elif ':' in vol['device_path']: + (protocol, name) = vol['device_path'].split(':') + vol['type'] = 'network' + vol['protocol'] = protocol + vol['device_path'] = name + else: + raise exception.InvalidDevicePath(path=vol['device_path']) + ebs_root = self._volume_in_mapping(self.root_mount_device, block_device_mapping) if self._volume_in_mapping(self.local_mount_device, -- cgit From f568d9345d19064c0024523195b17eb9e7d036ef Mon Sep 17 00:00:00 2001 From: Ryu Ishimoto Date: Thu, 7 Jul 2011 01:03:00 +0900 Subject: Added a L2 network driver for bridge/vlan creation --- Authors | 1 + nova/network/l2_drivers.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++ nova/network/manager.py | 32 ++++++++++++++++---------- 3 files changed, 77 insertions(+), 12 deletions(-) create mode 100644 nova/network/l2_drivers.py diff --git a/Authors b/Authors index c3a65f1b4..e0119d63e 100644 --- a/Authors +++ b/Authors @@ -77,6 +77,7 @@ Rick Harris Rob Kost Ryan Lane Ryan Lucio +Ryu Ishimoto Salvatore Orlando Sandy Walsh Sateesh Chodapuneedi diff --git a/nova/network/l2_drivers.py b/nova/network/l2_drivers.py new file mode 100644 index 000000000..1e66dcd26 --- /dev/null +++ b/nova/network/l2_drivers.py @@ -0,0 +1,56 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (C) 2011 Midokura KK +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Drivers responsible for managing L2 connectivity for Nova.""" + +from nova.network import linux_net + +class L2Driver(object): + """Base class that defines interfaces for L2 drivers.""" + + def ensure_bridge(bridge, interface, net_attrs=None): + """Create a bridge unless it already exists.""" + raise NotImplementedError() + + def ensure_vlan(vlan_num, bridge_interface): + """Create a vlan unless it already exists.""" + raise NotImplementedError() + + +class LinuxBridgeDriver(L2Driver): + """L2 driver based on Linux Bridge.""" + + def ensure_bridge(bridge, interface, net_attrs=None): + """Create a Linux bridge unless it already eixsts.""" + linux_net.ensure_bridge(bridge, interface, net_attrs) + + def ensure_vlan(vlan_num, bridge_interface): + """Create a vlan unless it already exists.""" + return linux_net.ensure_vlan(vlan_num, bridge_interface) + + +class QuantumDriver(L2Driver): + """L2 driver based on Quantum network service.""" + + def ensure_bridge(bridge, interface, net_attrs=None): + """Do nothing.""" + pass + + def ensure_vlan(vlan_num, bridge_interface): + """Return None.""" + return None + diff --git a/nova/network/manager.py b/nova/network/manager.py index d42bc8c4e..3d6388259 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -111,6 +111,8 @@ flags.DEFINE_string('network_host', socket.gethostname(), 'Network host to use for ip allocation in flat modes') flags.DEFINE_bool('fake_call', False, 'If True, skip using the queue and make local calls') +flags.DEFINE_string('l2_driver', 'nova.network.l2_drivers.LinuxBridgeDriver', + 'L2 network connectivity driver.') class AddressAlreadyAllocated(exception.Error): @@ -294,6 +296,7 @@ class NetworkManager(manager.SchedulerDependentManager): if not network_driver: network_driver = FLAGS.network_driver self.driver = utils.import_object(network_driver) + self.l2_driver = utils.import_object(FLAGS.l2_driver) self.network_api = network_api.API() super(NetworkManager, self).__init__(service_name='network', *args, **kwargs) @@ -738,8 +741,8 @@ class FlatDHCPManager(FloatingIP, RPCAllocateFixedIP, NetworkManager): """ networks = db.network_get_all_by_instance(context, instance_id) for network in networks: - self.driver.ensure_bridge(network['bridge'], - network['bridge_interface']) + self.l2_driver.ensure_bridge(network['bridge'], + network['bridge_interface']) def allocate_fixed_ip(self, context, instance_id, network): """Allocate flat_network fixed_ip, then setup dhcp for this network.""" @@ -755,9 +758,9 @@ class FlatDHCPManager(FloatingIP, RPCAllocateFixedIP, NetworkManager): net['dhcp_start'] = FLAGS.flat_network_dhcp_start self.db.network_update(context, network_id, net) network = db.network_get(context, network_id) - self.driver.ensure_bridge(network['bridge'], - network['bridge_interface'], - network) + self.l2_driver.ensure_bridge(network['bridge'], + network['bridge_interface'], + network) if not FLAGS.fake_network: self.driver.update_dhcp(context, network_id) if(FLAGS.use_ipv6): @@ -822,9 +825,11 @@ class VlanManager(RPCAllocateFixedIP, FloatingIP, NetworkManager): """ networks = self.db.network_get_all_by_instance(context, instance_id) for network in networks: - self.driver.ensure_vlan_bridge(network['vlan'], - network['bridge'], - network['bridge_interface']) + interface = self.l2_driver.ensure_vlan(network['vlan'], + network['bridge_interface']) + if interface: + self.l2_driver.ensure_bridge(network['bridge'], interface, + network['bridge_interface']) def _get_networks_for_instance(self, context, instance_id, project_id): """Determine which networks an instance should connect to.""" @@ -861,10 +866,13 @@ class VlanManager(RPCAllocateFixedIP, FloatingIP, NetworkManager): db.network_update(context, network_id, net) else: address = network['vpn_public_address'] - self.driver.ensure_vlan_bridge(network['vlan'], - network['bridge'], - network['bridge_interface'], - network) + + interface = self.l2_driver.ensure_vlan(network['vlan'], + network['bridge_interface']) + if interface: + self.l2_driver.ensure_bridge(network['bridge'], interface, + network['bridge_interface'], + network) # NOTE(vish): only ensure this forward if the address hasn't been set # manually. -- cgit From 2b553a89b34d7a3691c0952c5debda6b5ea1bb79 Mon Sep 17 00:00:00 2001 From: Ryu Ishimoto Date: Thu, 7 Jul 2011 01:04:56 +0900 Subject: Added net_attrs argument for ensure_bridge/vlan methods --- nova/network/l2_drivers.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nova/network/l2_drivers.py b/nova/network/l2_drivers.py index 1e66dcd26..e1de5cc5b 100644 --- a/nova/network/l2_drivers.py +++ b/nova/network/l2_drivers.py @@ -26,7 +26,7 @@ class L2Driver(object): """Create a bridge unless it already exists.""" raise NotImplementedError() - def ensure_vlan(vlan_num, bridge_interface): + def ensure_vlan(vlan_num, bridge_interface, net_attrs=None): """Create a vlan unless it already exists.""" raise NotImplementedError() @@ -38,9 +38,9 @@ class LinuxBridgeDriver(L2Driver): """Create a Linux bridge unless it already eixsts.""" linux_net.ensure_bridge(bridge, interface, net_attrs) - def ensure_vlan(vlan_num, bridge_interface): + def ensure_vlan(vlan_num, bridge_interface, net_attrs=None): """Create a vlan unless it already exists.""" - return linux_net.ensure_vlan(vlan_num, bridge_interface) + return linux_net.ensure_vlan(vlan_num, bridge_interface, net_attrs) class QuantumDriver(L2Driver): @@ -50,7 +50,7 @@ class QuantumDriver(L2Driver): """Do nothing.""" pass - def ensure_vlan(vlan_num, bridge_interface): + def ensure_vlan(vlan_num, bridge_interface, net_attrs=None): """Return None.""" return None -- cgit From 23a5775d6dbd5f11ff0adb67dd6b5bceb96b8030 Mon Sep 17 00:00:00 2001 From: Ryu Ishimoto Date: Thu, 7 Jul 2011 02:12:03 +0900 Subject: Added the missing 'self' parameter --- nova/network/l2_drivers.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/nova/network/l2_drivers.py b/nova/network/l2_drivers.py index e1de5cc5b..23d05cda4 100644 --- a/nova/network/l2_drivers.py +++ b/nova/network/l2_drivers.py @@ -22,11 +22,11 @@ from nova.network import linux_net class L2Driver(object): """Base class that defines interfaces for L2 drivers.""" - def ensure_bridge(bridge, interface, net_attrs=None): + def ensure_bridge(self, bridge, interface, net_attrs=None): """Create a bridge unless it already exists.""" raise NotImplementedError() - def ensure_vlan(vlan_num, bridge_interface, net_attrs=None): + def ensure_vlan(self, vlan_num, bridge_interface, net_attrs=None): """Create a vlan unless it already exists.""" raise NotImplementedError() @@ -34,11 +34,11 @@ class L2Driver(object): class LinuxBridgeDriver(L2Driver): """L2 driver based on Linux Bridge.""" - def ensure_bridge(bridge, interface, net_attrs=None): + def ensure_bridge(self, bridge, interface, net_attrs=None): """Create a Linux bridge unless it already eixsts.""" linux_net.ensure_bridge(bridge, interface, net_attrs) - def ensure_vlan(vlan_num, bridge_interface, net_attrs=None): + def ensure_vlan(self, vlan_num, bridge_interface, net_attrs=None): """Create a vlan unless it already exists.""" return linux_net.ensure_vlan(vlan_num, bridge_interface, net_attrs) @@ -46,11 +46,11 @@ class LinuxBridgeDriver(L2Driver): class QuantumDriver(L2Driver): """L2 driver based on Quantum network service.""" - def ensure_bridge(bridge, interface, net_attrs=None): + def ensure_bridge(self, bridge, interface, net_attrs=None): """Do nothing.""" pass - def ensure_vlan(vlan_num, bridge_interface, net_attrs=None): + def ensure_vlan(self, vlan_num, bridge_interface, net_attrs=None): """Return None.""" return None -- cgit From a05b0325a76dea16a2d5f7d1931a5cbc922e0364 Mon Sep 17 00:00:00 2001 From: Ryu Ishimoto Date: Thu, 7 Jul 2011 02:13:18 +0900 Subject: Added VIF driver concept --- nova/virt/libvirt.xml.template | 18 ++++++++++ nova/virt/libvirt/connection.py | 48 +++++-------------------- nova/virt/libvirt/vif_drivers.py | 76 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 39 deletions(-) create mode 100644 nova/virt/libvirt/vif_drivers.py diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index e1a683da8..ea27e5fd7 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -92,6 +92,22 @@ #end if #for $nic in $nics + #if $vif_type='ethernet' + + + +