From 15cfb4cd35fd1cf0c4cab8e6ef234f51a365ec27 Mon Sep 17 00:00:00 2001 From: Chris Behrens <cbehrens@codestud.com> Date: Mon, 20 Jun 2011 16:26:57 +0000 Subject: [PATCH] Merged my 'create-num-instances' branch which adds support for --min_instances and --max_instances to zone-boot Squashed commit of the following: commit f8a9d157c1b6989ca61430b2829c69bafead9731 Author: Chris Behrens <cbehrens@codestud.com> Date: Mon Jun 20 16:24:26 2011 +0000 updated tests for min_count/max_count commit e093e9e883159d42a67ba8799f46fa0cdf333077 Author: Chris Behrens <cbehrens@codestud.com> Date: Mon Jun 20 16:13:16 2011 +0000 adds --min_instances and --max_instances options to nova zone-boot --- novaclient/base.py | 10 +++++++++- novaclient/servers.py | 10 ++++++++-- novaclient/shell.py | 31 +++++++++++++++++++++++++++---- novaclient/zones.py | 10 ++++++++-- tests/fakeserver.py | 4 ++-- 5 files changed, 54 insertions(+), 11 deletions(-) diff --git a/novaclient/base.py b/novaclient/base.py index e6cce435a..3b97611d9 100644 --- a/novaclient/base.py +++ b/novaclient/base.py @@ -122,7 +122,8 @@ class BootingManagerWithFind(ManagerWithFind): """Like a `ManagerWithFind`, but has the ability to boot servers.""" def _boot(self, resource_url, response_key, name, image, flavor, ipgroup=None, meta=None, files=None, zone_blob=None, - reservation_id=None, return_raw=False): + reservation_id=None, return_raw=False, min_count=None, + max_count=None): """ Create (boot) a new server. @@ -159,6 +160,13 @@ class BootingManagerWithFind(ManagerWithFind): if zone_blob: body["server"]["zone_blob"] = zone_blob + if not min_count: + min_count = 1 + if not max_count: + max_count = min_count + body["server"]["min_count"] = min_count + body["server"]["max_count"] = max_count + # Files are a slight bit tricky. They're passed in a "personality" # list to the POST. Each item is a dict giving a file name and the # base64-encoded contents of the file. We want to allow passing diff --git a/novaclient/servers.py b/novaclient/servers.py index 7032f189c..e87d7690d 100644 --- a/novaclient/servers.py +++ b/novaclient/servers.py @@ -222,7 +222,8 @@ class ServerManager(base.BootingManagerWithFind): return self._list("/servers%s%s" % (detail, reservation), "servers") def create(self, name, image, flavor, ipgroup=None, meta=None, files=None, - zone_blob=None, reservation_id=None): + zone_blob=None, reservation_id=None, min_count=None, + max_count=None): """ Create (boot) a new server. @@ -243,9 +244,14 @@ class ServerManager(base.BootingManagerWithFind): this field. :param reservation_id: a UUID for the set of servers being requested. """ + if not min_count: + min_count = 1 + if not max_count: + max_count = min_count return self._boot("/servers", "server", name, image, flavor, ipgroup=ipgroup, meta=meta, files=files, - zone_blob=zone_blob, reservation_id=reservation_id) + zone_blob=zone_blob, reservation_id=reservation_id, + min_count=min_count, max_count=max_count) def update(self, server, name=None, password=None): """ diff --git a/novaclient/shell.py b/novaclient/shell.py index f9722f009..0bd5ee971 100644 --- a/novaclient/shell.py +++ b/novaclient/shell.py @@ -229,6 +229,14 @@ class OpenStackShell(object): def _boot(self, args, reservation_id=None): """Boot a new server.""" + min_count = args.min_instances + max_count = args.max_instances or min_count + + if max_count > min_count: + raise CommandError("min_instances should be <= max_instances") + if not min_count or not max_count: + raise CommandError("min_instances nor max_instances should be 0") + flavor = args.flavor or self.cs.flavors.find(ram=256) image = args.image or self.cs.images.find(name="Ubuntu 10.04 LTS "\ "(lucid)") @@ -272,7 +280,7 @@ class OpenStackShell(object): raise CommandError("Can't open '%s': %s" % (keyfile, e)) return (args.name, image, flavor, ipgroup, metadata, files, - reservation_id) + reservation_id, min_count, max_count) @arg('--flavor', default=None, @@ -317,7 +325,9 @@ class OpenStackShell(object): server = self.cs.servers.create(args.name, image, flavor, ipgroup=ipgroup, meta=metadata, - files=files) + files=files, + min_count=min_count, + max_count=max_count) print_dict(server._info) @arg('--flavor', @@ -408,11 +418,22 @@ class OpenStackShell(object): metavar='<reservation_id>', help="Reservation ID (a UUID). "\ "If unspecified will be generated by the server.") + @arg('--min_instances', + default=1, + metavar='<number>', + help="The minimum number of instances to build. "\ + "Defaults to 1.") + @arg('--max_instances', + default=None, + metavar='<number>', + help="The maximum number of instances to build. "\ + "Defaults to 'min_instances' setting.") @arg('name', metavar='<name>', help='Name for the new server') def do_zone_boot(self, args): """Boot a new server, potentially across Zones.""" reservation_id = args.reservation_id - name, image, flavor, ipgroup, metadata, files, reservation_id = \ + name, image, flavor, ipgroup, metadata, \ + files, reservation_id, min_count, max_count = \ self._boot(args, reservation_id=reservation_id) @@ -420,7 +441,9 @@ class OpenStackShell(object): ipgroup=ipgroup, meta=metadata, files=files, - reservation_id=reservation_id) + reservation_id=reservation_id, + min_count=min_count, + max_count=max_count) print "Reservation ID=", reservation_id def _translate_flavor_keys(self, collection): diff --git a/novaclient/zones.py b/novaclient/zones.py index 3fe79c417..ffc5b466e 100644 --- a/novaclient/zones.py +++ b/novaclient/zones.py @@ -107,7 +107,8 @@ class ZoneManager(base.BootingManagerWithFind): return self._create("/zones", body, "zone") def boot(self, name, image, flavor, ipgroup=None, meta=None, files=None, - zone_blob=None, reservation_id=None): + zone_blob=None, reservation_id=None, min_count=None, + max_count=None): """ Create (boot) a new server while being aware of Zones. @@ -128,10 +129,15 @@ class ZoneManager(base.BootingManagerWithFind): this field. :param reservation_id: a UUID for the set of servers being requested. """ + if not min_count: + min_count = 1 + if not max_count: + max_count = min_count return self._boot("/zones/boot", "reservation_id", name, image, flavor, ipgroup=ipgroup, meta=meta, files=files, zone_blob=zone_blob, reservation_id=reservation_id, - return_raw=True) + return_raw=True, min_count=min_count, + max_count=max_count) def select(self, *args, **kwargs): """ diff --git a/tests/fakeserver.py b/tests/fakeserver.py index c4e60ce98..2a1f6dfbc 100644 --- a/tests/fakeserver.py +++ b/tests/fakeserver.py @@ -204,7 +204,7 @@ class FakeClient(OpenStackClient): assert_has_keys(body['server'], required=['name', 'imageId', 'flavorId'], optional=['sharedIpGroupId', 'metadata', - 'personality']) + 'personality', 'min_count', 'max_count']) if 'personality' in body['server']: for pfile in body['server']['personality']: assert_has_keys(pfile, required=['path', 'contents']) @@ -443,7 +443,7 @@ class FakeClient(OpenStackClient): assert_has_keys(body['server'], required=['name', 'imageId', 'flavorId'], optional=['sharedIpGroupId', 'metadata', - 'personality']) + 'personality', 'min_count', 'max_count']) if 'personality' in body['server']: for pfile in body['server']['personality']: assert_has_keys(pfile, required=['path', 'contents'])