3030
3131
3232def import_tasks (provider_type ):
33- """Return Celery tasks for a given provider type"""
33+ """Return the celerytasks module for a given provider.
34+
35+ :param provider_type: type of cloud provider **currently only "ec2"**
36+ :type provider_type: string
37+ :rtype: celerytasks module for the provider
38+ :raises: :py:class:`ImportError` if the provider isn't recognized
39+ """
3440 try :
35- tasks = importlib .import_module ('celerytasks.' + provider_type )
36- except ImportError as e :
37- raise e
41+ tasks = importlib .import_module ('celerytasks.' + provider_type )
42+ except ImportError :
43+ raise
3844 return tasks
3945
4046
4147class AuditedModel (models .Model ):
4248
43- """
44- Adds created and update fields to a model.
49+ """Adds created and updated fields to a model.
4550 """
4651
4752 created = models .DateTimeField (auto_now_add = True )
4853 updated = models .DateTimeField (auto_now = True )
4954
5055 class Meta :
5156 """
52- Metadata options for AuditedModel, marking this class as abstract.
57+ Metadata options for ` AuditedModel` , marking this class as abstract.
5358 """
5459 abstract = True
5560
@@ -122,7 +127,7 @@ class FlavorManager(models.Manager):
122127 def load_cloud_config_base (self ):
123128 # load cloud-config-base yaml_
124129 _cloud_config_path = os .path .abspath (
125- os .path .join (__file__ , '..' , 'files' , 'cloud-config-base.yml' ))
130+ os .path .join (__file__ , '..' , 'files' , 'cloud-config-base.yml' ))
126131 with open (_cloud_config_path ) as f :
127132 _data = f .read ()
128133 return yaml .safe_load (_data )
@@ -199,7 +204,7 @@ def publish(self, **kwargs):
199204 'ssh_keys' : {},
200205 'admins' : [],
201206 'formations' : {}
202- }
207+ }
203208 # add all ssh keys on the system
204209 for key in Key .objects .all ():
205210 key_id = "{0}_{1}" .format (key .owner .username , key .id )
@@ -217,9 +222,11 @@ def publish(self, **kwargs):
217222 def next_container_node (self , formation , container_type ):
218223 count = []
219224 layer = formation .layer_set .get (id = 'runtime' )
220- runtime_nodes = list (Node .objects .filter (formation = formation , layer = layer ).order_by ('created' ))
221- container_map = { n : [] for n in runtime_nodes }
222- containers = list (Container .objects .filter (formation = formation , type = container_type ).order_by ('created' ))
225+ runtime_nodes = list (Node .objects .filter (
226+ formation = formation , layer = layer ).order_by ('created' ))
227+ container_map = {n : [] for n in runtime_nodes }
228+ containers = list (Container .objects .filter (
229+ formation = formation , type = container_type ).order_by ('created' ))
223230 for c in containers :
224231 container_map [c .node ].append (c )
225232 for n in container_map .keys ():
@@ -261,13 +268,13 @@ def scale_layers(self, **kwargs):
261268 node = nodes .pop (0 )
262269 funcs .append (node .terminate )
263270 diff = requested - len (nodes )
264- while diff > 0 :
271+ while diff > 0 :
265272 node = Node .objects .new (self , layer )
266273 nodes .append (node )
267274 funcs .append (node .launch )
268275 diff = requested - len (nodes )
269276 # http://docs.celeryproject.org/en/latest/userguide/canvas.html#groups
270- job = [func () for func in funcs ]
277+ job = [func () for func in funcs ]
271278 # balance containers
272279 containers_balanced = self ._balance_containers ()
273280 # launch/terminate nodes in parallel
@@ -334,17 +341,17 @@ def balance(self, **kwargs):
334341 def _balance_containers (self , ** kwargs ):
335342 runtime_nodes = self .node_set .filter (layer__id = 'runtime' ).order_by ('created' )
336343 if len (runtime_nodes ) < 2 :
337- return # there's nothing to balance with 1 runtime node
344+ return # there's nothing to balance with 1 runtime node
338345 all_containers = Container .objects .filter (formation = self ).order_by ('-created' )
339346 # get the next container number (e.g. web.19)
340347 container_num = 1 if not all_containers else all_containers [0 ].num + 1
341348 changed = False
342349 # iterate by unique container type
343350 for container_type in set ([c .type for c in all_containers ]):
344- # map node container counts => { 2: [b3, b4], 3: [ b1, b2 ] }
351+ # map node container counts => {2: [b3, b4], 3: [ b1, b2 ]}
345352 n_map = {}
346353 for node in runtime_nodes :
347- ct = len (node .container_set .filter (type = container_type ))
354+ ct = len (node .container_set .filter (type = container_type ))
348355 n_map .setdefault (ct , []).append (node )
349356 # loop until diff between min and max is 1 or 0
350357 while max (n_map .keys ()) - min (n_map .keys ()) > 1 :
@@ -421,17 +428,17 @@ def converge(self, databag):
421428 if settings .CHEF_ENABLED :
422429 controller .update_formation .delay (self .id , databag ).wait () # @UndefinedVariable
423430 # TODO: batch node converging by layer.level
424- nodes = [ node for node in self .node_set .all () ]
425- job = group (* [ n .converge () for n in nodes ])
426- _results = job .apply_async ().join ()
431+ nodes = [node for node in self .node_set .all ()]
432+ job = group (* [n .converge () for n in nodes ])
433+ job .apply_async ().join ()
427434 return databag
428435
429436 def destroy (self ):
430437 node_tasks , layer_tasks , chef_tasks = [], [], []
431438 # create subtasks to terminate all nodes in parallel
432439 all_layers = self .layer_set .all ()
433- node_tasks .extend ([ layer .destroy ()[0 ] for layer in all_layers ])
434- layer_tasks .extend ([ layer .destroy ()[1 ] for layer in all_layers ])
440+ node_tasks .extend ([layer .destroy ()[0 ] for layer in all_layers ])
441+ layer_tasks .extend ([layer .destroy ()[1 ] for layer in all_layers ])
435442 # call a celery task to update the formation data bag
436443 if settings .CHEF_ENABLED :
437444 chef_tasks .extend ([controller .destroy_formation .s (self .id )]) # @UndefinedVariable
@@ -443,23 +450,23 @@ def destroy(self):
443450
444451@python_2_unicode_compatible
445452class Layer (UuidAuditedModel ):
446-
453+
447454 """
448455 Layer of nodes used by the formation
449-
456+
450457 All nodes in a layer share the same flavor and configuration
451458 """
452459
453460 owner = models .ForeignKey (settings .AUTH_USER_MODEL )
454461 id = models .SlugField (max_length = 64 )
455-
462+
456463 formation = models .ForeignKey ('Formation' )
457464 flavor = models .ForeignKey ('Flavor' )
458465 level = models .PositiveIntegerField (default = 0 )
459466
460467 # chef settings
461468 chef_version = models .CharField (max_length = 32 , default = '11.4.4' )
462- run_list = models .CharField (max_length = 512 )
469+ run_list = models .CharField (max_length = 512 )
463470 initial_attributes = fields .JSONField (default = '{}' , blank = True )
464471 environment = models .CharField (max_length = 64 , default = '_default' )
465472 # ssh settings
@@ -484,7 +491,7 @@ def destroy(self):
484491 tasks = import_tasks (self .flavor .provider .type )
485492 subtasks = []
486493 # create subtasks to terminate all nodes in parallel
487- subtasks .extend ([ node .terminate () for node in self .node_set .all () ])
494+ subtasks .extend ([node .terminate () for node in self .node_set .all ()])
488495 node_tasks = group (* subtasks )
489496 # purge other hosting provider infrastructure
490497 name = "{0}-{1}" .format (self .formation .id , self .id )
@@ -526,7 +533,7 @@ class Node(UuidAuditedModel):
526533 formation = models .ForeignKey ('Formation' )
527534 layer = models .ForeignKey ('Layer' )
528535 num = models .PositiveIntegerField ()
529-
536+
530537 # synchronized with node after creation
531538 provider_id = models .SlugField (max_length = 64 , blank = True , null = True )
532539 fqdn = models .CharField (max_length = 256 , blank = True , null = True )
@@ -565,10 +572,10 @@ def _prepare_launch_args(self):
565572 if self .layer .initial_attributes :
566573 chef ['initial_attributes' ] = self .layer .initial_attributes
567574 # add the formation's ssh pubkey
568- init .setdefault ('ssh_authorized_keys' , []). append (
569- self .layer .ssh_public_key )
575+ init .setdefault (
576+ 'ssh_authorized_keys' , []). append ( self .layer .ssh_public_key )
570577 # add all of the owner's SSH keys
571- init ['ssh_authorized_keys' ].extend ([k .public for k in self .formation .owner .key_set .all () ])
578+ init ['ssh_authorized_keys' ].extend ([k .public for k in self .formation .owner .key_set .all ()])
572579 ssh_username = self .layer .ssh_username
573580 ssh_private_key = self .layer .ssh_private_key
574581 args = (self .uuid , creds , params , init , ssh_username , ssh_private_key )
@@ -744,6 +751,9 @@ def rollback(self):
744751
745752@receiver (release_signal )
746753def new_release (sender , ** kwargs ):
754+ """Catches a release_signal and creates a new release from the
755+ last release.
756+ """
747757 formation , user = kwargs ['formation' ], kwargs ['user' ]
748758 last_release = Release .objects .filter (
749759 formation = formation ).order_by ('-created' )[0 ]
@@ -759,11 +769,12 @@ def new_release(sender, **kwargs):
759769 if new_values :
760770 # update with current config
761771 new_values .update (config .values )
762- config = Config .objects .create (version = config .version + 1 ,
763- owner = user , formation = formation , values = new_values )
772+ config = Config .objects .create (
773+ version = config .version + 1 , owner = user ,
774+ formation = formation , values = new_values )
764775 # create new release and auto-increment version
765776 new_version = last_release .version + 1
766- release = Release .objects .create (owner = user , formation = formation ,
767- image = image , config = config , build = build , version = new_version )
777+ release = Release .objects .create (
778+ owner = user , formation = formation , image = image , config = config ,
779+ build = build , version = new_version )
768780 return release
769-
0 commit comments