Merge branch 'master' of github.com:open-cloud/xos
diff --git a/xos/core/models/plcorebase.py b/xos/core/models/plcorebase.py
index 68c9c12..377bf19 100644
--- a/xos/core/models/plcorebase.py
+++ b/xos/core/models/plcorebase.py
@@ -30,7 +30,7 @@
         if value is not None:
             value = value.strip()
         return super(StrippedCharField, self).clean(value, *args, **kwds)
-            
+
 
 # This manager will be inherited by all subclasses because
 # the core model is abstract.
@@ -152,7 +152,7 @@
     write_protect = models.BooleanField(default=False)
 
     # XXX Django has no official support for composite primray keys yet
-    # so we will hack in an inefficient solution here.  
+    # so we will hack in an inefficient solution here.
     composite_primary_key = []
 
     class Meta:
@@ -186,34 +186,40 @@
             super(PlCoreBase, self).delete(*args, **kwds)
         else:
             if (not self.write_protect):
-                    self.deleted = True
-                    self.enacted=None
-                    self.save(update_fields=['enacted','deleted'], silent=silent)
+                self.deleted = True
+                self.enacted=None
+                self.save(update_fields=['enacted','deleted'], silent=silent)
 
     def check_composite_primary_key(self):
-        if not self.composite_primary_key:
-            return 
+        try:
+            composite_key_exists = self.composite_primary_key
+        except AttributeError:
+            composite_key_exists = False
+
+            if (not composite_key_exists):
+                return
+
         # dictionary containing cpk field name and value
         cpk_fields = dict([(name, getattr(self, name)) for name in self.composite_primary_key])
         objs = self.__class__.objects.filter(**cpk_fields)
-        # we can only continue if there are no matches or 
-        # if this record is updating itself         
+        # we can only continue if there are no matches or
+        # if this record is updating itself
         if (len(objs) == 0 or
             (len(objs) == 1 and self.id and objs[0].id == self.id)):
-            return 
-        # if we reach this point then we've matched more than 1 
-        # existing record or we are trying to  
+            return
+        # if we reach this point then we've matched more than 1
+        # existing record or we are trying to
         msg = "%s violates composite primray key constraint on fields: %s " % (self, self.composite_primary_key)
         raise db.Error, msg
-                 
-               
+
+
     def save(self, *args, **kwargs):
         # let the user specify silence as either a kwarg or an instance varible
         silent = self.silent
         if "silent" in kwargs:
             silent=silent or kwargs.pop("silent")
 
-        self.check_composite_primary_key()    
+        self.check_composite_primary_key()
 
         super(PlCoreBase, self).save(*args, **kwargs)
 
@@ -245,10 +251,4 @@
 
     @classmethod
     def is_ephemeral(cls):
-	return cls in ephemeral_models
-
-
-
-
-
-
+        return cls in ephemeral_models
diff --git a/xos/model_policies/model_policy_Controller.py b/xos/model_policies/model_policy_Controller.py
index 6d73e0c..be31311 100644
--- a/xos/model_policies/model_policy_Controller.py
+++ b/xos/model_policies/model_policy_Controller.py
@@ -1,6 +1,6 @@
 
 def handle(controller):
-    from core.models import Controller, Site, ControllerSite, Slice, ControllerSlice, User, ControllerUser
+    from core.models import Controller, Site, ControllerSite, Slice, ControllerSlice, User, ControllerUser, ControllerImages, ControllerNetwork
     from collections import defaultdict
 
     # relations for all sites
@@ -36,3 +36,25 @@
             controller not in ctrls_by_user[user]:
             controller_user = ControllerUser(controller=controller, user=user)
             controller_user.save()
+    # relations for all networks
+    ctrls_by_network = defaultdict(list)
+    ctrl_networks = ControllerNetwork.objects.all()
+    for ctrl_network in ctrl_networks:
+        ctrls_by_network[ctrl_network.network].append(ctrl_network.controller)
+    networks = Network.objects.all()
+    for network in networks:
+        if network not in ctrls_by_network or \
+            controller not in ctrls_by_network[network]:
+            controller_network = ControllerNetwork(controller=controller, network=network)
+            controller_network.save()
+    # relations for all images
+    ctrls_by_image = defaultdict(list)
+    ctrl_images = ControllerImages.objects.all()
+    for ctrl_image in ctrl_images:
+        ctrls_by_image[ctrl_image.image].append(ctrl_image.controller)
+    images = Image.objects.all()
+    for image in images:
+        if image not in ctrls_by_image or \
+            controller not in ctrls_by_image[image]:
+            controller_image = ControllerImages(controller=controller, image=image)
+            controller_image.save()
diff --git a/xos/openstack_observer/backend.py b/xos/openstack_observer/backend.py
index 7b67494..48dae2e 100644
--- a/xos/openstack_observer/backend.py
+++ b/xos/openstack_observer/backend.py
@@ -4,23 +4,28 @@
 from observer.event_manager import EventListener
 from util.logger import Logger, logging
 from model_policy import run_policy
+from xos.config import Config
 
 logger = Logger(level=logging.INFO)
 
 class Backend:
-    
+
     def run(self):
-            # start the openstack observer
-            observer = XOSObserver()
-            observer_thread = threading.Thread(target=observer.run)
-            observer_thread.start()
-            
-            # start model policies thread
+        # start the openstack observer
+        observer = XOSObserver()
+        observer_thread = threading.Thread(target=observer.run)
+        observer_thread.start()
+
+        # start model policies thread
+        observer_name = getattr(Config(), "observer_name", "")
+        if (not observer_name):
             model_policy_thread = threading.Thread(target=run_policy)
             model_policy_thread.start()
+        else:
+            print "Skipping model policies thread for service observer."
 
-            # start event listene
-            event_manager = EventListener(wake_up=observer.wake_up)
-            event_manager_thread = threading.Thread(target=event_manager.run)
-            event_manager_thread.start()
 
+        # start event listene
+        #event_manager = EventListener(wake_up=observer.wake_up)
+        #event_manager_thread = threading.Thread(target=event_manager.run)
+        #event_manager_thread.start()