77# pylint: disable=R0903,W0232
88
99from __future__ import unicode_literals
10+ import importlib
1011import os
1112import subprocess
1213
1920from django .dispatch .dispatcher import Signal
2021from django .utils .encoding import python_2_unicode_compatible
2122
22- from api import fields
23+ from api import fields , tasks
2324from provider import import_provider_module
2425
26+ # import user-defined configuration management module
27+ CM = importlib .import_module (settings .CM_MODULE )
28+
2529
2630# define custom signals
2731release_signal = Signal (providing_args = ['user' , 'app' ])
2832
29- # define custom exceptions
30-
31-
32- class ScalingError (Exception ):
33- pass
3433
3534# base models
3635
@@ -90,7 +89,7 @@ def seed(self, user, **kwargs):
9089 """
9190 Seeds the database with Providers for clouds supported by Deis.
9291 """
93- providers = (( 'ec2' , 'ec2' ), ( 'mock' , 'mock' ))
92+ providers = [( p , p ) for p in settings . PROVIDER_MODULES ]
9493 for p_id , p_type in providers :
9594 self .create (owner = user , id = p_id , type = p_type , creds = '{}' )
9695
@@ -120,19 +119,14 @@ class Meta:
120119 def __str__ (self ):
121120 return "{}-{}" .format (self .id , self .get_type_display ())
122121
123- def flat (self ):
124- return {'id' : self .id ,
125- 'type' : self .type ,
126- 'creds' : dict (self .creds )}
127-
128122
129123@python_2_unicode_compatible
130124class FlavorManager (models .Manager ):
131125 """Manage database interactions for :class:`Flavor`."""
132126
133127 def seed (self , user , ** kwargs ):
134128 """Seed the database with default Flavors for each cloud region."""
135- for provider_type in ( 'mock' , 'ec2' ) :
129+ for provider_type in settings . PROVIDER_MODULES :
136130 provider = import_provider_module (provider_type )
137131 flavors = provider .seed_flavors ()
138132 p = Provider .objects .get (owner = user , id = provider_type )
@@ -162,48 +156,13 @@ class Meta:
162156 def __str__ (self ):
163157 return self .id
164158
165- def flat (self ):
166- return {'id' : self .id ,
167- 'creds' : dict (self .provider .creds ),
168- 'provider' : self .provider .id ,
169- 'params' : self .params }
170-
171-
172- @python_2_unicode_compatible
173- class FormationManager (models .Manager ):
174- """Manage database interactions for :class:`Formation`."""
175-
176- def next_container_node (self , formation , container_type , reverse = False ):
177- count = []
178- layers = formation .layer_set .filter (runtime = True )
179- runtime_nodes = []
180- for l in layers :
181- runtime_nodes .extend (Node .objects .filter (
182- formation = formation , layer = l ).order_by ('created' ))
183- container_map = {n : [] for n in runtime_nodes }
184- containers = list (Container .objects .filter (
185- formation = formation , type = container_type ).order_by ('created' ))
186- for c in containers :
187- container_map [c .node ].append (c )
188- for n in container_map .keys ():
189- # (2, node3), (2, node2), (3, node1)
190- count .append ((len (container_map [n ]), n ))
191- if not count :
192- raise ScalingError ('No nodes available for containers' )
193- count .sort ()
194- # reverse means order by greatest # of containers, otherwise fewest
195- if reverse :
196- count .reverse ()
197- return count [0 ][1 ]
198-
199159
200160@python_2_unicode_compatible
201161class Formation (UuidAuditedModel ):
202162
203163 """
204164 Formation of nodes used to host applications
205165 """
206- objects = FormationManager ()
207166
208167 owner = models .ForeignKey (settings .AUTH_USER_MODEL )
209168 id = models .SlugField (max_length = 64 , unique = True )
@@ -381,6 +340,29 @@ def scale(self, formation, structure, **kwargs):
381340 return formation .converge ()
382341 return formation .calculate ()
383342
343+ def next_runtime_node (self , formation , container_type , reverse = False ):
344+ count = []
345+ layers = formation .layer_set .filter (runtime = True )
346+ runtime_nodes = []
347+ for l in layers :
348+ runtime_nodes .extend (Node .objects .filter (
349+ formation = formation , layer = l ).order_by ('created' ))
350+ container_map = {n : [] for n in runtime_nodes }
351+ containers = list (Container .objects .filter (
352+ formation = formation , type = container_type ).order_by ('created' ))
353+ for c in containers :
354+ container_map [c .node ].append (c )
355+ for n in container_map .keys ():
356+ # (2, node3), (2, node2), (3, node1)
357+ count .append ((len (container_map [n ]), n ))
358+ if not count :
359+ raise EnvironmentError ('No nodes available for containers' )
360+ count .sort ()
361+ # reverse means order by greatest # of containers, otherwise fewest
362+ if reverse :
363+ count .reverse ()
364+ return count [0 ][1 ]
365+
384366
385367@python_2_unicode_compatible
386368class Node (UuidAuditedModel ):
@@ -555,7 +537,7 @@ def scale(self, app, structure, **kwargs):
555537 changed = True
556538 while diff < 0 :
557539 # get the next node with the most containers
558- node = Formation .objects .next_container_node (
540+ node = Node .objects .next_runtime_node (
559541 formation , container_type , reverse = True )
560542 # delete a container attached to that node
561543 for c in containers :
@@ -566,7 +548,7 @@ def scale(self, app, structure, **kwargs):
566548 break
567549 while diff > 0 :
568550 # get the next node with the fewest containers
569- node = Formation .objects .next_container_node (formation , container_type )
551+ node = Node .objects .next_runtime_node (formation , container_type )
570552 c = Container .objects .create (owner = app .owner ,
571553 formation = formation ,
572554 node = node ,
@@ -836,11 +818,3 @@ def _publish_user_to_cm(**kwargs):
836818post_save .connect (_publish_to_cm , sender = App , dispatch_uid = 'api.models' )
837819post_save .connect (_publish_to_cm , sender = Formation , dispatch_uid = 'api.models' )
838820post_save .connect (_publish_user_to_cm , sender = User , dispatch_uid = 'api.models' )
839-
840-
841- # now that we've defined models that may be imported by celery tasks
842- # import tasks and user-defined config management module
843- from api import tasks
844-
845- import importlib
846- CM = importlib .import_module (settings .CM_MODULE )
0 commit comments