cleanup, fix instance sync
diff --git a/xos/synchronizers/base/backend.py.bak b/xos/synchronizers/base/backend.py.bak
deleted file mode 100644
index 6e46b85..0000000
--- a/xos/synchronizers/base/backend.py.bak
+++ /dev/null
@@ -1,34 +0,0 @@
-import threading
-import time
-from observer.event_loop import XOSObserver
-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
-            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."
-
-            model_policy_thread = threading.Thread(target=run_policy)
-            model_policy_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()
-
diff --git a/xos/synchronizers/base/controller.diff b/xos/synchronizers/base/controller.diff
deleted file mode 100644
index 865b83e..0000000
--- a/xos/synchronizers/base/controller.diff
+++ /dev/null
@@ -1,37 +0,0 @@
-diff -up xos/model_policies/model_policy_Controller.py.orig xos/model_policies/model_policy_Controller.py
---- xos/model_policies/model_policy_Controller.py.orig	2015-01-19 20:09:13.000000000 +0000
-+++ xos/model_policies/model_policy_Controller.py	2015-04-07 21:48:51.462215000 +0000
-@@ -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 @@ def handle(controller):
-             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/synchronizers/base/steps/sync_controller_slices.py.bak b/xos/synchronizers/base/steps/sync_controller_slices.py.bak
deleted file mode 100644
index e04da8e..0000000
--- a/xos/synchronizers/base/steps/sync_controller_slices.py.bak
+++ /dev/null
@@ -1,95 +0,0 @@
-import os
-import base64
-from collections import defaultdict
-from netaddr import IPAddress, IPNetwork
-from django.db.models import F, Q
-from xos.config import Config
-from observer.openstacksyncstep import OpenStackSyncStep
-from core.models import *
-from observer.ansible import *
-from openstack.driver import OpenStackDriver
-from util.logger import observer_logger as logger
-import json
-
-class SyncControllerSlices(OpenStackSyncStep):
-    provides=[Slice]
-    requested_interval=0
-    observes=ControllerSlice
-
-    def fetch_pending(self, deleted):
-        if (deleted):
-            return ControllerSlice.deleted_objects.all()
-        else:
-            return ControllerSlice.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
-
-    def sync_record(self, controller_slice):
-        logger.info("sync'ing slice controller %s" % controller_slice)
-
-	controller_register = json.loads(controller_slice.controller.backend_register)
-	if (controller_register.get('disabled',False)):
-		raise Exception('Controller %s is disabled'%controller_slice.controller.name)
-
-        if not controller_slice.controller.admin_user:
-            logger.info("controller %r has no admin_user, skipping" % controller_slice.controller)
-            return
-
-        controller_users = ControllerUser.objects.filter(user=controller_slice.slice.creator,
-                                                             controller=controller_slice.controller)
-        if not controller_users:
-            raise Exception("slice createor %s has not accout at controller %s" % (controller_slice.slice.creator, controller_slice.controller.name))
-        else:
-            controller_user = controller_users[0]
-            roles = ['Admin']
-
-        max_instances=int(controller_slice.slice.max_slivers)
-        tenant_fields = {'endpoint':controller_slice.controller.auth_url,
-                         'admin_user': controller_slice.controller.admin_user,
-                         'admin_password': controller_slice.controller.admin_password,
-                         'admin_tenant': 'admin',
-                         'tenant': controller_slice.slice.name,
-                         'tenant_description': controller_slice.slice.description,
-                         'roles':roles,
-                         'name':controller_user.user.email,
-                         'ansible_tag':'%s@%s'%(controller_slice.slice.name,controller_slice.controller.name),
-                         'max_instances':max_instances}
-
-        expected_num = len(roles)+1
-        res = run_template('sync_controller_slices.yaml', tenant_fields, path='controller_slices', expected_num=expected_num)
-        tenant_id = res[0]['id']
-        if (not controller_slice.tenant_id):
-            try:
-                    driver = OpenStackDriver().admin_driver(controller=controller_slice.controller)
-                    driver.shell.nova.quotas.update(tenant_id=controller_slice.tenant_id, instances=int(controller_slice.slice.max_slivers))
-            except:
-                    logger.log_exc('Could not update quota for %s'%controller_slice.slice.name)
-                    raise Exception('Could not update quota for %s'%controller_slice.slice.name)
-                
-            controller_slice.tenant_id = tenant_id
-            controller_slice.backend_status = '1 - OK'
-            controller_slice.save()
-
-
-    def delete_record(self, controller_slice):
-        controller_register = json.loads(controller_slice.controller.backend_register)
- 	if (controller_register.get('disabled',False)):
- 		raise Exception('Controller %s is disabled'%controller_slice.controller.name)
- 
- 	controller_users = ControllerUser.objects.filter(user=controller_slice.slice.creator,
-                                                              controller=controller_slice.controller)
-         if not controller_users:
-             raise Exception("slice createor %s has not accout at controller %s" % (controller_slice.slice.creator, controller_slice.controller.name))
-         else:
-             controller_user = controller_users[0]
- 
- 	tenant_fields = {'endpoint':controller_slice.controller.auth_url,
-                          'admin_user': controller_slice.controller.admin_user,
-                          'admin_password': controller_slice.controller.admin_password,
-                          'admin_tenant': 'admin',
-                          'tenant': controller_slice.slice.name,
-                          'tenant_description': controller_slice.slice.description,
-                          'name':controller_user.user.email,
-                          'ansible_tag':'%s@%s'%(controller_slice.slice.name,controller_slice.controller.name),
- 			 'delete': True}
- 
-         expected_num = 1
-         res = run_template('sync_controller_slices.yaml', tenant_fields, path='controller_slices', expected_num=expected_num)
diff --git a/xos/synchronizers/base/steps/sync_slivers.py.bak b/xos/synchronizers/base/steps/sync_slivers.py.bak
deleted file mode 100644
index c4240fa..0000000
--- a/xos/synchronizers/base/steps/sync_slivers.py.bak
+++ /dev/null
@@ -1,179 +0,0 @@
-import os
-import base64
-import socket
-from django.db.models import F, Q
-from xos.config import Config
-from xos.settings import RESTAPI_HOSTNAME, RESTAPI_PORT
-from observer.openstacksyncstep import OpenStackSyncStep
-from core.models.sliver import Sliver
-from core.models.slice import Slice, SlicePrivilege, ControllerSlice
-from core.models.network import Network, NetworkSlice, ControllerNetwork
-from observer.ansible import *
-from util.logger import observer_logger as logger
-
-def escape(s):
-    s = s.replace('\n',r'\n').replace('"',r'\"')
-    return s
-
-class SyncSlivers(OpenStackSyncStep):
-    provides=[Sliver]
-    requested_interval=0
-    observes=Sliver
-
-    def get_userdata(self, sliver, pubkeys):
-        userdata = '#cloud-config\n\nopencloud:\n   slicename: "%s"\n   hostname: "%s"\n   restapi_hostname: "%s"\n   restapi_port: "%s"\n' % (sliver.slice.name, sliver.node.name, RESTAPI_HOSTNAME, str(RESTAPI_PORT))
-        userdata += 'ssh_authorized_keys:\n'
-        for key in pubkeys:
-            userdata += '  - %s\n' % key
-        return userdata
-
-    def sync_record(self, sliver):
-        logger.info("sync'ing sliver:%s slice:%s controller:%s " % (sliver, sliver.slice.name, sliver.node.site_deployment.controller))
-    	controller_register = json.loads(sliver.node.site_deployment.controller.backend_register)
- 
-        if (controller_register.get('disabled',False)):
-                raise Exception('Controller %s is disabled'%sliver.node.site_deployment.controller.name)
-
-        metadata_update = {}
-        if (sliver.numberCores):
-            metadata_update["cpu_cores"] = str(sliver.numberCores)
-
-        for tag in sliver.slice.tags.all():
-            if tag.name.startswith("sysctl-"):
-                metadata_update[tag.name] = tag.value
-
-        # public keys
-        slice_memberships = SlicePrivilege.objects.filter(slice=sliver.slice)
-        pubkeys = set([sm.user.public_key for sm in slice_memberships if sm.user.public_key])
-        if sliver.creator.public_key:
-            pubkeys.add(sliver.creator.public_key)
-
-        if sliver.slice.creator.public_key:
-            pubkeys.add(sliver.slice.creator.public_key)
-
-        if sliver.slice.service and sliver.slice.service.public_key:
-            pubkeys.add(sliver.slice.service.public_key)
-
-        if sliver.slice.service and sliver.slice.service.public_key:
-            pubkeys.add(sliver.slice.service.public_key)
-
-        nics = []
-        networks = [ns.network for ns in NetworkSlice.objects.filter(slice=sliver.slice)]
-        controller_networks = ControllerNetwork.objects.filter(network__in=networks,
-                                                                controller=sliver.node.site_deployment.controller)
-
-        for controller_network in controller_networks:
-            if controller_network.network.template.visibility == 'private' and \
-               controller_network.network.template.translation == 'none':
-                   if not controller_network.net_id:
-                        raise Exception("Private Network %s has no id; Try again later" % controller_network.network.name)
-                   nics.append(controller_network.net_id)
-
-        # now include network template
-        network_templates = [network.template.shared_network_name for network in networks \
-                             if network.template.shared_network_name]
-
-        #driver = self.driver.client_driver(caller=sliver.creator, tenant=sliver.slice.name, controller=sliver.controllerNetwork)
-        driver = self.driver.admin_driver(tenant='admin', controller=sliver.node.site_deployment.controller)
-        nets = driver.shell.quantum.list_networks()['networks']
-        for net in nets:
-            if net['name'] in network_templates:
-                nics.append(net['id'])
-
-        if (not nics):
-            for net in nets:
-                if net['name']=='public':
-                    nics.append(net['id'])
-
-        image_id = None
-        controller_images = sliver.image.controllerimages.filter(controller=sliver.node.site_deployment.controller)
-        if controller_images:
-            image_id = controller_images[0].glance_image_id
-            logger.info("using image_id from ControllerImage object: " + str(image_id))
-
-        if image_id is None:
-            controller_driver = self.driver.admin_driver(controller=sliver.node.site_deployment.controller)
-            image_id = None
-            images = controller_driver.shell.glanceclient.images.list()
-            for image in images:
-                if image.name == sliver.image.name or not image_id:
-                    image_id = image.id
-                    logger.info("using image_id from glance: " + str(image_id))
-
-        try:
-            legacy = Config().observer_legacy
-        except:
-            legacy = False
-
-        if (legacy):
-            host_filter = sliver.node.name.split('.',1)[0]
-        else:
-            host_filter = sliver.node.name.strip()
-
-        availability_zone_filter = 'nova:%s'%host_filter
-        sliver_name = '%s-%d'%(sliver.slice.name,sliver.id)
-
-        userData = self.get_userdata(sliver, pubkeys)
-        if sliver.userData:
-            userData = sliver.userData
-
-        controller = sliver.node.site_deployment.controller
-        tenant_fields = {'endpoint':controller.auth_url,
-                     'admin_user': sliver.creator.email,
-                     'admin_password': sliver.creator.remote_password,
-                     'admin_tenant': sliver.slice.name,
-                     'tenant': sliver.slice.name,
-                     'tenant_description': sliver.slice.description,
-                     'name':sliver_name,
-                     'ansible_tag':sliver_name,
-                     'availability_zone': availability_zone_filter,
-                     'image_id':image_id,
-                     'flavor_id':sliver.flavor.id,
-                     'nics':nics,
-                     'meta':metadata_update,
-                     'user_data':r'%s'%escape(userData)}
-
-        res = run_template('sync_slivers.yaml', tenant_fields,path='slivers', expected_num=1)
-        sliver_id = res[0]['info']['OS-EXT-SRV-ATTR:instance_name']
-        sliver_uuid = res[0]['id']
-
-        try:
-            hostname = res[0]['info']['OS-EXT-SRV-ATTR:hypervisor_hostname']
-            ip = socket.gethostbyname(hostname)
-            sliver.ip = ip
-        except:
-            pass
-
-        sliver.instance_id = sliver_id
-        sliver.instance_uuid = sliver_uuid
-        sliver.instance_name = sliver_name
-        sliver.save()
-
-    def delete_record(self, sliver):
-	controller_register = json.loads(sliver.node.site_deployment.controller.backend_register)
-
-        if (controller_register.get('disabled',False)):
-                raise Exception('Controller %s is disabled'%sliver.node.site_deployment.controller.name)
-
-        sliver_name = '%s-%d'%(sliver.slice.name,sliver.id)
-        controller = sliver.node.site_deployment.controller
-        tenant_fields = {'endpoint':controller.auth_url,
-                     'admin_user': sliver.creator.email,
-                     'admin_password': sliver.creator.remote_password,
-                     'admin_tenant': sliver.slice.name,
-                     'tenant': sliver.slice.name,
-                     'tenant_description': sliver.slice.description,
-                     'name':sliver_name,
-                     'ansible_tag':sliver_name,
-                     'delete': True}
-
-        try:
-               res = run_template('sync_slivers.yaml', tenant_fields,path='slivers', expected_num=1)

-        except Exception,e:

-               print "Could not sync %s"%sliver_name

-               #import traceback

-               #traceback.print_exc()

-               raise e

-
-        if (len(res)!=1):
-            raise Exception('Could not delete sliver %s'%sliver.slice.name)
diff --git a/xos/synchronizers/base/syncstep.py.bak b/xos/synchronizers/base/syncstep.py.bak
deleted file mode 100644
index a1f242b..0000000
--- a/xos/synchronizers/base/syncstep.py.bak
+++ /dev/null
@@ -1,203 +0,0 @@
-import os
-import base64
-from datetime import datetime
-from xos.config import Config
-from util.logger import Logger, logging
-from observer.steps import *
-from django.db.models import F, Q
-from core.models import * 
-import json
-import time
-import pdb
-import traceback
-
-logger = Logger(level=logging.INFO)
-
-def f7(seq):
-    seen = set()
-    seen_add = seen.add
-    return [ x for x in seq if not (x in seen or seen_add(x))]
-
-def elim_dups(backend_str):
-    strs = backend_str.split(' // ')
-    strs2 = f7(strs)
-    return ' // '.join(strs2)
-    
-def deepgetattr(obj, attr):
-    return reduce(getattr, attr.split('.'), obj)
-
-
-class InnocuousException(Exception):
-    pass
-
-class FailedDependency(Exception):
-    pass
-
-class SyncStep(object):
-    """ An XOS Sync step. 
-
-    Attributes:
-        psmodel        Model name the step synchronizes 
-        dependencies    list of names of models that must be synchronized first if the current model depends on them
-    """ 
-    slow=False
-    def get_prop(self, prop):
-        try:
-            sync_config_dir = Config().sync_config_dir
-        except:
-            sync_config_dir = '/etc/xos/sync'
-        prop_config_path = '/'.join(sync_config_dir,self.name,prop)
-        return open(prop_config_path).read().rstrip()
-
-    def __init__(self, **args):
-        """Initialize a sync step
-           Keyword arguments:
-                   name -- Name of the step
-                provides -- XOS models sync'd by this step
-        """
-        dependencies = []
-        self.driver = args.get('driver')
-        self.error_map = args.get('error_map')
-
-        try:
-            self.soft_deadline = int(self.get_prop('soft_deadline_seconds'))
-        except:
-            self.soft_deadline = 5 # 5 seconds
-
-        return
-
-    def fetch_pending(self, deletion=False):
-        # This is the most common implementation of fetch_pending
-        # Steps should override it if they have their own logic
-        # for figuring out what objects are outstanding.
-        main_obj = self.observes
-        if (not deletion):
-            objs = main_obj.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None),Q(lazy_blocked=False))
-        else:
-            objs = main_obj.deleted_objects.all()
-
-        return objs
-        #return Sliver.objects.filter(ip=None)
-    
-    def check_dependencies(self, obj, failed):
-        for dep in self.dependencies:
-            peer_name = dep[0].lower() + dep[1:]    # django names are camelCased with the first letter lower
- 
-            try:
-                peer_object = deepgetattr(obj, peer_name)
-                try: 
-                    peer_objects = peer_object.all() 
-                except AttributeError:
-                    peer_objects = [peer_object] 
-            except:
-                peer_objects = []
-
-            if (hasattr(obj,'controller')):
-                try:
-                	peer_objects = filter(lambda o:o.controller==obj.controller, peer_objects)
-                except AttributeError:
-                        pass
-
-            if (failed in peer_objects):
-                if (obj.backend_status!=failed.backend_status):
-                    obj.backend_status = failed.backend_status
-                    obj.save(update_fields=['backend_status'])
-                raise FailedDependency("Failed dependency for %s:%s peer %s:%s failed  %s:%s" % (obj.__class__.__name__, str(getattr(obj,"pk","no_pk")), peer_object.__class__.__name__, str(getattr(peer_object,"pk","no_pk")), failed.__class__.__name__, str(getattr(failed,"pk","no_pk"))))
-
-    def call(self, failed=[], deletion=False):
-        pending = self.fetch_pending(deletion)
-        for o in pending:
-            sync_failed = False
-            try:
-                backoff_disabled = Config().observer_backoff_disabled
-            except:
-                backoff_disabled = 0
-
-            try:
-                scratchpad = json.loads(o.backend_register)
-                if (scratchpad):
-                    next_run = scratchpad['next_run']
-                    if (not backoff_disabled and next_run>time.time()):
-                        sync_failed = True
-            except:
-                logger.log_exc("Exception while loading scratchpad")
-                pass
-
-            if (not sync_failed):
-                try:
-                    for f in failed:
-                        self.check_dependencies(o,f) # Raises exception if failed
-                    if (deletion):
-                        self.delete_record(o)
-                        o.delete(purge=True)
-                    else:
-                        self.sync_record(o)
-                        o.enacted = datetime.now() # Is this the same timezone? XXX
-                        scratchpad = {'next_run':0, 'exponent':0}
-                        o.backend_register = json.dumps(scratchpad)
-                        o.backend_status = "1 - OK"
-                        o.save(update_fields=['enacted','backend_status','backend_register'])
-                except (InnocuousException,Exception) as e:
-                    logger.log_exc("sync step failed!")
-                    try:
-                        if (o.backend_status.startswith('2 - ')):
-                            str_e = '%s // %r'%(o.backend_status[4:],e)
-			    str_e = elim_dups(str_e)
-                        else:
-                            str_e = '%r'%e
-                    except:
-                        str_e = '%r'%e
-
-                    try:
-                        error = self.error_map.map(str_e)
-                    except:
-                        error = '2 - %s'%str_e
-
-                    if isinstance(e, InnocuousException) and not force_error:
-                        o.backend_status = '1 - %s'%error
-                    else:
-                        o.backend_status = '3 - %s'%error
-
-                    try:
-                        scratchpad = json.loads(o.backend_register)
-                        scratchpad['exponent']
-                    except:
-                        logger.log_exc("Exception while updating scratchpad")
-                        scratchpad = {'next_run':0, 'exponent':0}
-
-                    # Second failure
-                    if (scratchpad['exponent']):
-                        delay = scratchpad['exponent'] * 600 # 10 minutes
-                        if (delay<1440):
-                            delay = 1440
-                        scratchpad['next_run'] = time.time() + delay
-
-                    scratchpad['exponent']+=1
-
-                    o.backend_register = json.dumps(scratchpad)
-
-                    # TOFIX:
-                    # DatabaseError: value too long for type character varying(140)
-                    if (o.pk):
-                        try:
-                            o.backend_status = o.backend_status[:1024]
-                            o.save(update_fields=['backend_status','backend_register','updated'])
-                        except:
-                            print "Could not update backend status field!"
-                            pass
-                    sync_failed = True
-
-
-            if (sync_failed):
-                failed.append(o)
-
-        return failed
-
-    def sync_record(self, o):
-        return
-
-    def delete_record(self, o):
-        return
-
-    def __call__(self, **args):
-        return self.call(**args)
diff --git a/xos/synchronizers/openstack/steps/sync_instances.yaml b/xos/synchronizers/openstack/steps/sync_instances.yaml
index 70da32d..476890f 100644
--- a/xos/synchronizers/openstack/steps/sync_instances.yaml
+++ b/xos/synchronizers/openstack/steps/sync_instances.yaml
@@ -19,6 +19,7 @@
       timeout: 200
       userdata: "{{ user_data }}"
       config_drive: yes
+      auto_ip: no
       nics:
       {% for nic in nics %}
           - {{ nic.kind }}-id: {{ nic.value }}