fix merge conflict
diff --git a/containers/onboarding_synchronizer/Dockerfile b/containers/onboarding_synchronizer/Dockerfile
index 967e234..b86cbb1 100644
--- a/containers/onboarding_synchronizer/Dockerfile
+++ b/containers/onboarding_synchronizer/Dockerfile
@@ -10,12 +10,20 @@
 # This container must be started in privileged mode. 
 
 RUN apt-get install -y curl
-# iptables 
-ENV DOCKER_BUCKET=get.docker.com
-ENV DOCKER_VERSION=1.8.3
-ENV DOCKER_SHA256=f024bc65c45a3778cf07213d26016075e8172de8f6e4b5702bedde06c241650f
-RUN curl -fSL "https://${DOCKER_BUCKET}/builds/Linux/x86_64/docker-$DOCKER_VERSION" -o /usr/local/bin/docker && echo "${DOCKER_SHA256} /usr/local/bin/docker" | sha256sum -c - && chmod +x /usr/local/bin/docker
 
+# XXX version 1.10.3
+ENV DOCKER_BUCKET get.docker.com
+ENV DOCKER_VERSION 1.10.3

+ENV DOCKER_SHA256 d0df512afa109006a450f41873634951e19ddabf8c7bd419caeb5a526032d86d

+RUN curl -fSL "https://${DOCKER_BUCKET}/builds/Linux/x86_64/docker-$DOCKER_VERSION" -o /usr/local/bin/docker && echo "${DOCKER_SHA256}  /usr/local/bin/docker" | sha256sum -c - && chmod +x /usr/local/bin/docker

+
+# XXX vserioin 1.8.3
+#ENV DOCKER_BUCKET=get.docker.com
+#ENV DOCKER_VERSION=1.8.3
+#ENV DOCKER_SHA256=f024bc65c45a3778cf07213d26016075e8172de8f6e4b5702bedde06c241650f
+#RUN curl -fSL "https://${DOCKER_BUCKET}/builds/Linux/x86_64/docker-$DOCKER_VERSION" -o /usr/local/bin/docker && echo "${DOCKER_SHA256} /usr/local/bin/docker" | sha256sum -c - && chmod +x /usr/local/bin/docker
+
+# XXX version 1.8.3
 # XXX uncomment the following 6 lines to run docker-in-docker
 #     comment them out if using the docker socket in a volume instead
 #ENV DIND_COMMIT=3b5fac462d21ca164b3778647420016315289034
diff --git a/xos/api/service/vbng/debug.py b/xos/api/service/vbng/debug.py
deleted file mode 100644
index 8ecec0f..0000000
--- a/xos/api/service/vbng/debug.py
+++ /dev/null
@@ -1,61 +0,0 @@
-from rest_framework.decorators import api_view
-from rest_framework.response import Response
-from rest_framework.reverse import reverse
-from rest_framework import serializers
-from rest_framework import generics
-from rest_framework import viewsets
-from rest_framework.decorators import detail_route, list_route
-from rest_framework.views import APIView
-from core.models import *
-from django.forms import widgets
-from django.conf.urls import patterns, url
-from services.cord.models import VOLTTenant, VBNGTenant, CordSubscriberRoot
-from core.xoslib.objects.cordsubscriber import CordSubscriber
-from api.xosapi_helpers import PlusModelSerializer, XOSViewSet
-from django.shortcuts import get_object_or_404
-from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
-from xos.exceptions import *
-import json
-import subprocess
-
-if hasattr(serializers, "ReadOnlyField"):
-    # rest_framework 3.x
-    ReadOnlyField = serializers.ReadOnlyField
-else:
-    # rest_framework 2.x
-    ReadOnlyField = serializers.Field
-
-class CordDebugIdSerializer(PlusModelSerializer):
-    # Swagger is failing because CordDebugViewSet has neither a model nor
-    # a serializer_class. Stuck this in here as a placeholder for now.
-    id = ReadOnlyField()
-    class Meta:
-        model = CordSubscriber
-
-class CordDebugViewSet(XOSViewSet):
-    base_name = "debug"
-    method_name = "debug"
-    method_kind = "viewset"
-    serializer_class = CordDebugIdSerializer
-
-    @classmethod
-    def get_urlpatterns(self, api_path="^"):
-        patterns = []
-        patterns.append( url(api_path + "debug/vbng_dump/$", self.as_view({"get": "get_vbng_dump"}), name="vbng_dump"))
-        return patterns
-
-    # contact vBNG service and dump current list of mappings
-    def get_vbng_dump(self, request, pk=None):
-        result=subprocess.check_output(["curl", "http://10.0.3.136:8181/onos/virtualbng/privateip/map"])
-        if request.GET.get("theformat",None)=="text":
-            from django.http import HttpResponse
-            result = json.loads(result)["map"]
-
-            lines = []
-            for row in result:
-                for k in row.keys():
-                     lines.append( "%s %s" % (k, row[k]) )
-
-            return HttpResponse("\n".join(lines), content_type="text/plain")
-        else:
-            return Response( {"vbng_dump": json.loads(result)["map"] } )
diff --git a/xos/configurations/cord-pod/Makefile b/xos/configurations/cord-pod/Makefile
index c8f4574..5c290cd 100644
--- a/xos/configurations/cord-pod/Makefile
+++ b/xos/configurations/cord-pod/Makefile
@@ -20,6 +20,24 @@
 	echo "[ONBOARDING]"
 	# on-board any services here
 	bash ../common/wait_for_onboarding_ready.sh 81 xos
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(BOOTSTRAP_YML) run xos_bootstrap_ui python /opt/xos/tosca/run.py None /opt/xos/configurations/cord-pod/disable-onboarding.yaml
+	sudo cp id_rsa key_import/vsg_rsa
+	sudo cp id_rsa.pub key_import/vsg_rsa.pub
+	sudo cp id_rsa key_import/volt_rsa
+	sudo cp id_rsa.pub key_import/volt_rsa.pub
+	sudo cp id_rsa key_import/onos_rsa
+	sudo cp id_rsa key_import/onos_rsa.pub
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(BOOTSTRAP_YML) run xos_bootstrap_ui python /opt/xos/tosca/run.py None /opt/xos/onboard/volt/volt-onboard.yaml
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(BOOTSTRAP_YML) run xos_bootstrap_ui python /opt/xos/tosca/run.py None /opt/xos/onboard/vsg/vsg-onboard.yaml
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(BOOTSTRAP_YML) run xos_bootstrap_ui python /opt/xos/tosca/run.py None /opt/xos/onboard/vtn/vtn-onboard.yaml
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(BOOTSTRAP_YML) run xos_bootstrap_ui python /opt/xos/tosca/run.py None /opt/xos/onboard/onos/onos-onboard.yaml
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(BOOTSTRAP_YML) run xos_bootstrap_ui python /opt/xos/tosca/run.py None /opt/xos/configurations/cord-pod/synchronizers.yaml
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(BOOTSTRAP_YML) run xos_bootstrap_ui python /opt/xos/tosca/run.py None /opt/xos/configurations/cord-pod/enable-onboarding.yaml
+	bash ../common/wait_for_onboarding_ready.sh 81 services/volt
+	bash ../common/wait_for_onboarding_ready.sh 81 services/vsg
+	bash ../common/wait_for_onboarding_ready.sh 81 services/vtn
+	bash ../common/wait_for_onboarding_ready.sh 81 services/onos
+	bash ../common/wait_for_onboarding_ready.sh 81 xos
 	bash ../common/wait_for_xos_port.sh 80
 
 podconfig: nodes.yaml images.yaml
diff --git a/xos/configurations/cord-pod/cord-vtn-vsg.yaml b/xos/configurations/cord-pod/cord-vtn-vsg.yaml
index 44d4fbb..6996527 100644
--- a/xos/configurations/cord-pod/cord-vtn-vsg.yaml
+++ b/xos/configurations/cord-pod/cord-vtn-vsg.yaml
@@ -25,6 +25,10 @@
           view_url: /admin/cord/voltservice/$id$/
           kind: vOLT
           replaces: service_volt
+          public_key: { get_artifact: [ SELF, pubkey, LOCAL_FILE] }
+          private_key_fn: /opt/xos/services/volt/keys/volt_rsa
+      artifacts:
+          pubkey: /opt/xos/services/volt/keys/volt_rsa.pub
 
     addresses_vsg:
       type: tosca.nodes.AddressPool
@@ -50,11 +54,11 @@
           view_url: /admin/cord/vsgservice/$id$/
           backend_network_label: hpc_client
           public_key: { get_artifact: [ SELF, pubkey, LOCAL_FILE] }
-          private_key_fn: /opt/xos/synchronizers/vcpe/vcpe_private_key
+          private_key_fn: /opt/xos/services/vsg/keys/vsg_rsa
 #          node_label: label_vsg
           replaces: service_vsg
       artifacts:
-          pubkey: /opt/xos/synchronizers/vcpe/vcpe_public_key
+          pubkey: /opt/xos/services/vsg/keys/vsg_rsa.pub
 
     service#vrouter:
       type: tosca.nodes.VRouterService
diff --git a/xos/configurations/cord-pod/disable-onboarding.yaml b/xos/configurations/cord-pod/disable-onboarding.yaml
new file mode 100644
index 0000000..0dd1ded
--- /dev/null
+++ b/xos/configurations/cord-pod/disable-onboarding.yaml
@@ -0,0 +1,17 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Onboard the exampleservice
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+    xos:
+      type: tosca.nodes.XOS
+      properties:
+        no-create: true
+        no-delete: true
+        no-update: true
+        enable_build: false
+
diff --git a/xos/configurations/cord-pod/docker-compose-bootstrap.yml b/xos/configurations/cord-pod/docker-compose-bootstrap.yml
index 9f17c42..9243491 100644
--- a/xos/configurations/cord-pod/docker-compose-bootstrap.yml
+++ b/xos/configurations/cord-pod/docker-compose-bootstrap.yml
@@ -40,52 +40,52 @@
             max-size: "100k"
             max-file: "5"
 
-xos_synchronizer_onos:
-    image: xosproject/xos-synchronizer-openstack
-    command: bash -c "python /opt/xos/synchronizers/onos/onos-synchronizer.py -C /opt/xos/synchronizers/onos/onos_synchronizer_config"
-    labels:
-        org.xosproject.kind: synchronizer
-        org.xosproject.target: onos
-    links:
-        - xos_db
-    volumes:
-        - .:/root/setup:ro
-        - ./id_rsa:/opt/xos/synchronizers/onos/onos_key:ro  # private key
-    log_driver: "json-file"
-    log_opt:
-            max-size: "100k"
-            max-file: "5"
+#xos_synchronizer_onos:
+#    image: xosproject/xos-synchronizer-openstack
+#    command: bash -c "python /opt/xos/synchronizers/onos/onos-synchronizer.py -C /opt/xos/synchronizers/onos/onos_synchronizer_config"
+#    labels:
+#        org.xosproject.kind: synchronizer
+#        org.xosproject.target: onos
+#    links:
+#        - xos_db
+#    volumes:
+#        - .:/root/setup:ro
+#        - ./id_rsa:/opt/xos/synchronizers/onos/onos_key:ro  # private key
+#    log_driver: "json-file"
+#    log_opt:
+#            max-size: "100k"
+#            max-file: "5"
 
-xos_synchronizer_vcpe:
-    image: xosproject/xos-synchronizer-openstack
-    command: bash -c "sleep 120; cp /root/setup/node_key /opt/xos/synchronizers/vcpe/; chmod 0600 /opt/xos/synchronizers/vcpe/node_key; python /opt/xos/synchronizers/vcpe/vcpe-synchronizer.py -C /root/setup/files/vcpe_synchronizer_config"
-    labels:
-        org.xosproject.kind: synchronizer
-        org.xosproject.target: vcpe
-    links:
-        - xos_db
-    volumes:
-        - .:/root/setup:ro
-        - ./id_rsa:/opt/xos/synchronizers/vcpe/vcpe_private_key:ro  # private key
-    log_driver: "json-file"
-    log_opt:
-            max-size: "100k"
-            max-file: "5"
+#xos_synchronizer_vcpe:
+#    image: xosproject/xos-synchronizer-openstack
+#    command: bash -c "sleep 120; cp /root/setup/node_key /opt/xos/synchronizers/vcpe/; chmod 0600 /opt/xos/synchronizers/vcpe/node_key; python /opt/xos/synchronizers/vcpe/vcpe-synchronizer.py -C /root/setup/files/vcpe_synchronizer_config"
+#    labels:
+#        org.xosproject.kind: synchronizer
+#        org.xosproject.target: vcpe
+#    links:
+#        - xos_db
+#    volumes:
+#        - .:/root/setup:ro
+#        - ./id_rsa:/opt/xos/synchronizers/vcpe/vcpe_private_key:ro  # private key
+#    log_driver: "json-file"
+#    log_opt:
+#            max-size: "100k"
+#            max-file: "5"
 
-xos_synchronizer_vtn:
-    image: xosproject/xos-synchronizer-openstack
-    command: bash -c "sleep 120; python /opt/xos/synchronizers/vtn/vtn-synchronizer.py -C /opt/xos/synchronizers/vtn/vtn_synchronizer_config"
-    labels:
-        org.xosproject.kind: synchronizer
-        org.xosproject.target: vtn
-    links:
-        - xos_db
-    volumes:
-        - .:/root/setup:ro
-    log_driver: "json-file"
-    log_opt:
-            max-size: "100k"
-            max-file: "5"
+#xos_synchronizer_vtn:
+#    image: xosproject/xos-synchronizer-openstack
+#    command: bash -c "sleep 120; python /opt/xos/synchronizers/vtn/vtn-synchronizer.py -C /opt/xos/synchronizers/vtn/vtn_synchronizer_config"
+#    labels:
+#        org.xosproject.kind: synchronizer
+#        org.xosproject.target: vtn
+#    links:
+#        - xos_db
+#    volumes:
+#        - .:/root/setup:ro
+#    log_driver: "json-file"
+#    log_opt:
+#            max-size: "100k"
+#            max-file: "5"
 
 xos_synchronizer_monitoring_channel:
     image: xosproject/xos-synchronizer-openstack
@@ -103,21 +103,21 @@
             max-size: "100k"
             max-file: "5"
 
-xos_synchronizer_vtr:
-    image: xosproject/xos-synchronizer-openstack
-    command: bash -c "sleep 120; cp /root/setup/node_key /opt/xos/synchronizers/vtr/; chmod 0600 /opt/xos/synchronizers/vtr/node_key; python /opt/xos/synchronizers/vtr/vtr-synchronizer.py -C /root/setup/files/vtr_synchronizer_config"
-    labels:
-        org.xosproject.kind: synchronizer
-        org.xosproject.target: vtr
-    links:
-        - xos_db
-    volumes:
-        - .:/root/setup:ro
-        - ./id_rsa:/opt/xos/synchronizers/vtr/vcpe_private_key:ro  # private key
-    log_driver: "json-file"
-    log_opt:
-            max-size: "100k"
-            max-file: "5"
+#xos_synchronizer_vtr:
+#    image: xosproject/xos-synchronizer-openstack
+#    command: bash -c "sleep 120; cp /root/setup/node_key /opt/xos/synchronizers/vtr/; chmod 0600 /opt/xos/synchronizers/vtr/node_key; python /opt/xos/synchronizers/vtr/vtr-synchronizer.py -C /root/setup/files/vtr_synchronizer_config"
+#    labels:
+#        org.xosproject.kind: synchronizer
+#        org.xosproject.target: vtr
+#    links:
+#        - xos_db
+#    volumes:
+#        - .:/root/setup:ro
+#        - ./id_rsa:/opt/xos/synchronizers/vtr/vcpe_private_key:ro  # private key
+#    log_driver: "json-file"
+#    log_opt:
+#            max-size: "100k"
+#            max-file: "5"
 
 xos_synchronizer_fabric:
     image: xosproject/xos-synchronizer-openstack
diff --git a/xos/configurations/cord-pod/enable-onboarding.yaml b/xos/configurations/cord-pod/enable-onboarding.yaml
new file mode 100644
index 0000000..b31ac1d
--- /dev/null
+++ b/xos/configurations/cord-pod/enable-onboarding.yaml
@@ -0,0 +1,17 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Onboard the exampleservice
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+    xos:
+      type: tosca.nodes.XOS
+      properties:
+        no-create: true
+        no-delete: true
+        no-update: true
+        enable_build: true
+
diff --git a/xos/configurations/cord-pod/files/vcpe_synchronizer_config b/xos/configurations/cord-pod/files/vcpe_synchronizer_config
index 46ee0c3..9da6ede 100644
--- a/xos/configurations/cord-pod/files/vcpe_synchronizer_config
+++ b/xos/configurations/cord-pod/files/vcpe_synchronizer_config
@@ -23,10 +23,10 @@
 
 [observer]
 name=vcpe
-dependency_graph=/opt/xos/synchronizers/vcpe/model-deps
-steps_dir=/opt/xos/synchronizers/vcpe/steps
-sys_dir=/opt/xos/synchronizers/vcpe/sys
-deleters_dir=/opt/xos/synchronizers/vcpe/deleters
+dependency_graph=/opt/xos/synchronizers/vsg/model-deps
+steps_dir=/opt/xos/synchronizers/vsg/steps
+sys_dir=/opt/xos/synchronizers/vsg/sys
+deleters_dir=/opt/xos/synchronizers/vsg/deleters
 log_file=console
 #/var/log/hpc.log
 driver=None
diff --git a/xos/configurations/cord-pod/synchronizers.yaml b/xos/configurations/cord-pod/synchronizers.yaml
new file mode 100644
index 0000000..1e001b7
--- /dev/null
+++ b/xos/configurations/cord-pod/synchronizers.yaml
@@ -0,0 +1,14 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Onboard the exampleservice
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+    servicecontroller#vsg:
+      type: tosca.nodes.ServiceController
+      properties:
+        no-create: true
+        synchronizer_config: /root/setup/files/vcpe_synchronizer_config
diff --git a/xos/configurations/cord-pod/xos.yaml b/xos/configurations/cord-pod/xos.yaml
index 06b5eb5..95cbf18 100644
--- a/xos/configurations/cord-pod/xos.yaml
+++ b/xos/configurations/cord-pod/xos.yaml
@@ -54,25 +54,25 @@
              node: xos
              relationship: tosca.relationships.UsedByXOS
 
-    /opt/xos/synchronizers/onos/onos_key.pub:
-      type: tosca.nodes.XOSVolume
-      properties:
-          host_path: { path_join: [ SELF, CONFIG_DIR, id_rsa.pub, ENV_VAR ] }
-          read_only: true
-      requirements:
-          - xos:
-             node: xos
-             relationship: tosca.relationships.UsedByXOS
+#    /opt/xos/synchronizers/onos/onos_key.pub:
+#      type: tosca.nodes.XOSVolume
+#      properties:
+#          host_path: { path_join: [ SELF, CONFIG_DIR, id_rsa.pub, ENV_VAR ] }
+#          read_only: true
+#      requirements:
+#          - xos:
+#             node: xos
+#             relationship: tosca.relationships.UsedByXOS
 
-    /opt/xos/synchronizers/vcpe/vcpe_public_key:
-      type: tosca.nodes.XOSVolume
-      properties:
-          host_path: { path_join: [ SELF, CONFIG_DIR, id_rsa.pub, ENV_VAR ] }                                                      
-          read_only: true
-      requirements:
-          - xos:
-             node: xos
-             relationship: tosca.relationships.UsedByXOS
+#    /opt/xos/synchronizers/vcpe/vcpe_public_key:
+#      type: tosca.nodes.XOSVolume
+#      properties:
+#          host_path: { path_join: [ SELF, CONFIG_DIR, id_rsa.pub, ENV_VAR ] }
+#          read_only: true
+#      requirements:
+#          - xos:
+#             node: xos
+#             relationship: tosca.relationships.UsedByXOS
 
     /opt/xos/synchronizers/monitoring_channel/monitoring_channel_public_key:
       type: tosca.nodes.XOSVolume
diff --git a/xos/configurations/frontend/Makefile b/xos/configurations/frontend/Makefile
index 46f39bf..8845196 100644
--- a/xos/configurations/frontend/Makefile
+++ b/xos/configurations/frontend/Makefile
@@ -3,23 +3,33 @@
 DOCKER_COMPOSE_YML=./onboarding-docker-compose/docker-compose.yml
 BOOTSTRAP_YML=./docker-compose-bootstrap.yml
 DOCKER_PROJECT=frontend
+XOS_BOOTSTRAP_PORT=9998
+XOS_UI_PORT=9999
 
-frontend: prereqs bootstrap
-	bash ../common/wait_for_xos_port.sh 9999
-	sudo docker-compose -p $(DOCKER_PROJECT) -f $(DOCKER_COMPOSE_YML) run xos_ui python /opt/xos/tosca/run.py none /opt/xos/configurations/common/fixtures.yaml
-	sudo docker-compose -p $(DOCKER_PROJECT) -f $(DOCKER_COMPOSE_YML) run xos_ui python /opt/xos/tosca/run.py none /opt/xos/configurations/common/mydeployment.yaml
-	sudo docker-compose -p $(DOCKER_PROJECT) -f $(DOCKER_COMPOSE_YML) run xos_ui python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/frontend/sample.yaml
+frontend: prereqs bootstrap onboarding frontendconfig
 
 prereqs:
 	sudo make -f ../common/Makefile.prereqs
 
 bootstrap:
+	echo "[BOOTSTRAP]"
 	sudo rm -f onboarding-docker-compose/docker-compose.yml
-	sudo rm -f docker-compose.yml
 	sudo docker-compose -p $(DOCKER_PROJECT) -f docker-compose-bootstrap.yml up -d
-	bash ../common/wait_for_xos_port.sh 9998
+	bash ../common/wait_for_xos_port.sh $(XOS_BOOTSTRAP_PORT)
 	sudo docker-compose -p $(DOCKER_PROJECT) -f $(BOOTSTRAP_YML) run -e CONFIG_DIR=$(CONFIG_DIR) xos_bootstrap_ui python /opt/xos/tosca/run.py none /opt/xos/configurations/frontend/xos.yaml
 
+onboarding:
+	echo "[ONBOARDING]"
+	# on-board any services here
+	bash ../common/wait_for_onboarding_ready.sh $(XOS_BOOTSTRAP_PORT) xos
+	bash ../common/wait_for_xos_port.sh $(XOS_UI_PORT)
+
+frontendconfig:
+	echo "[FRONTENDCONFIG]"
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(DOCKER_COMPOSE_YML) run xos_ui python /opt/xos/tosca/run.py none /opt/xos/configurations/common/fixtures.yaml
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(DOCKER_COMPOSE_YML) run xos_ui python /opt/xos/tosca/run.py none /opt/xos/configurations/common/mydeployment.yaml
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(DOCKER_COMPOSE_YML) run xos_ui python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/frontend/sample.yaml
+
 containers:
 	cd ../../../containers/xos; make devel
 	cd ../../../containers/synchronizer; make
@@ -50,15 +60,29 @@
 	sudo docker exec frontend_xos_1 rm -f /opt/xos/xos_configuration/xos_mcord_config
 	sudo docker exec frontend_xos_1 rm -f /opt/xos/xos_configuration/xos_cord_config
 
-mock-cord-pod:
-	sudo docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/common/fixtures.yaml
-	sudo docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/cord-pod/mgmt-net.yaml
-	#sudo docker-compose run xos bash -c "echo somekey > /opt/xos/synchronizers/vcpe/vcpe_public_key; python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/cord-pod/cord-vtn-vsg.yaml"
-	sudo docker-compose run xos python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/cord-pod/cord-volt-devices.yaml
+mock-cord-pod: onboard-cord-pod
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(DOCKER_COMPOSE_YML) run xos_ui python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/common/fixtures.yaml
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(DOCKER_COMPOSE_YML) run xos_ui python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/cord-pod/mgmt-net.yaml
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(DOCKER_COMPOSE_YML) run xos_ui python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/cord-pod/cord-vtn-vsg.yaml
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(DOCKER_COMPOSE_YML) run xos_ui python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/cord-pod/cord-volt-devices.yaml
 	sudo docker exec frontend_xos_1 cp /opt/xos/configurations/cord-pod/xos_cord_config /opt/xos/xos_configuration/
 	sudo docker exec frontend_xos_1 touch /opt/xos/xos/settings.py
 
-
+onboard-cord-pod:
+	#sudo cp id_rsa key_import/vsg_rsa
+	#sudo cp id_rsa.pub key_import/vsg_rsa.pub
+	#sudo cp id_rsa key_import/volt_rsa
+	#sudo cp id_rsa.pub key_import/volt_rsa.pub
+	sudo bash -c "echo somekey > key_import/vsg_rsa"
+	sudo bash -c "echo somekey > key_import/vsg_rsa.pub"
+	sudo bash -c "echo somekey > key_import/volt_rsa"
+	sudo bash -c "echo somekey > key_import/volt_rsa.pub"
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(DOCKER_COMPOSE_YML) run xos_ui python /opt/xos/tosca/run.py None /opt/xos/onboard/volt/volt-onboard.yaml
+	sudo docker-compose -p $(DOCKER_PROJECT) -f $(DOCKER_COMPOSE_YML) run xos_ui python /opt/xos/tosca/run.py None /opt/xos/onboard/vsg/vsg-onboard.yaml
+	bash ../common/wait_for_onboarding_ready.sh 9998 services/volt
+	bash ../common/wait_for_onboarding_ready.sh 9998 services/vsg
+	bash ../common/wait_for_onboarding_ready.sh $(XOS_BOOTSTRAP_PORT) xos
+	bash ../common/wait_for_xos_port.sh $(XOS_UI_PORT)
 
 mock-mcord:
 	# check this
diff --git a/xos/configurations/frontend/docker-compose-bootstrap.yml b/xos/configurations/frontend/docker-compose-bootstrap.yml
index 3975893..00a43f3 100644
--- a/xos/configurations/frontend/docker-compose-bootstrap.yml
+++ b/xos/configurations/frontend/docker-compose-bootstrap.yml
@@ -17,7 +17,7 @@
 xos_synchronizer_onboarding:
     image: xosproject/xos-synchronizer-onboarding
     command: bash -c "cd /opt/xos/synchronizers/onboarding; ./run.sh"
-    #command: sleep 86400
+#    command: sleep 86400
     labels:
         org.xosproject.kind: synchronizer
         org.xosproject.target: onboarding
diff --git a/xos/configurations/frontend/xos.yaml b/xos/configurations/frontend/xos.yaml
index 8b286cd..3153e95 100644
--- a/xos/configurations/frontend/xos.yaml
+++ b/xos/configurations/frontend/xos.yaml
@@ -13,6 +13,7 @@
         ui_port: 9999
         bootstrap_ui_port: 9998
         docker_project_name: frontend
+        frontend_only: true
 
     /opt/xos/xos_configuration/xos_common_config:
       type: tosca.nodes.XOSVolume
diff --git a/xos/core/models/service.py b/xos/core/models/service.py
index c871c7e..83b827c 100644
--- a/xos/core/models/service.py
+++ b/xos/core/models/service.py
@@ -70,6 +70,9 @@
     name = StrippedCharField(max_length=30, help_text="Service Name")
     base_url = StrippedCharField(max_length=1024, help_text="Base URL, allows use of relative URLs for resources", null=True, blank=True)
 
+    synchronizer_run = StrippedCharField(max_length=1024, help_text="synchronizer run command", null=True, blank=True)
+    synchronizer_config = StrippedCharField(max_length=1024, help_text="synchronizer config file", null=True, blank=True)
+
     def __unicode__(self): return u'%s' % (self.name)
 
     def save(self, *args, **kwargs):
@@ -83,6 +86,7 @@
 class ServiceControllerResource(PlCoreBase):
     KIND_CHOICES = (('models', 'Models'),
                     ('admin', 'Admin'),
+                    ('admin_template', 'Admin Template'),
                     ('django_library', 'Django Library'),
                     ('synchronizer', 'Synchronizer'),
                     ('rest_service', 'REST API (service)'),
@@ -102,6 +106,7 @@
                                 help_text="The Service Controller this resource is associated with")
 
     name = StrippedCharField(max_length=30, help_text="Object Name")
+    subdirectory = StrippedCharField(max_length=1024, help_text="optional subdirectory", null=True, blank=True)
     kind = StrippedCharField(choices=KIND_CHOICES, max_length=30)
     format = StrippedCharField(choices=FORMAT_CHOICES, max_length=30)
     url = StrippedCharField(max_length=1024, help_text="URL of resource", null=True, blank=True)
diff --git a/xos/core/models/xosmodel.py b/xos/core/models/xosmodel.py
index 4942241..01c9514 100644
--- a/xos/core/models/xosmodel.py
+++ b/xos/core/models/xosmodel.py
@@ -14,6 +14,7 @@
     db_container_name = StrippedCharField(max_length=200, help_text="name of XOS db container", default="xos_db")
     docker_project_name = StrippedCharField(max_length=200, help_text="docker project name")
     enable_build = models.BooleanField(help_text="True if Onboarding Synchronizer should build XOS as necessary", default=True)
+    frontend_only = models.BooleanField(help_text="If True, XOS will not start synchronizer containers", default=False)
 
     def __unicode__(self):  return u'%s' % (self.name)
 
diff --git a/xos/core/xoslib/methods/cordsubscriber.py b/xos/core/xoslib/methods/cordsubscriber._unused
similarity index 87%
rename from xos/core/xoslib/methods/cordsubscriber.py
rename to xos/core/xoslib/methods/cordsubscriber._unused
index b69b09d..8fc88e0 100644
--- a/xos/core/xoslib/methods/cordsubscriber.py
+++ b/xos/core/xoslib/methods/cordsubscriber._unused
@@ -9,7 +9,7 @@
 from core.models import *
 from django.forms import widgets
 from django.conf.urls import patterns, url
-from services.cord.models import VOLTTenant, VBNGTenant, CordSubscriberRoot
+from services.volt.models import VOLTTenant, CordSubscriberRoot
 from core.xoslib.objects.cordsubscriber import CordSubscriber
 from plus import PlusSerializerMixin, XOSViewSet
 from django.shortcuts import get_object_or_404
@@ -208,7 +208,7 @@
         patterns.append( url("^rs/subidlookup/(?P<ssid>[0-9\-]+)/$", self.as_view({"get": "ssiddetail"}), name="ssiddetail") )
         patterns.append( url("^rs/subidlookup/$", self.as_view({"get": "ssidlist"}), name="ssidlist") )
 
-        patterns.append( url("^rs/vbng_mapping/$", self.as_view({"get": "get_vbng_mapping"}), name="vbng_mapping") )
+        #patterns.append( url("^rs/vbng_mapping/$", self.as_view({"get": "get_vbng_mapping"}), name="vbng_mapping") )
 
         return patterns
 
@@ -367,47 +367,14 @@
 
         return Response( ssidmap[0] )
 
-    def get_vbng_mapping(self, request):
-        object_list = VBNGTenant.get_tenant_objects().all()
+    #def get_vbng_mapping(self, request):
+    #    object_list = VBNGTenant.get_tenant_objects().all()
+    #
+    #    mappings = []
+    #    for vbng in object_list:
+    #        if vbng.mapped_ip and vbng.routeable_subnet:
+    #            mappings.append( {"private_ip": vbng.mapped_ip, "routeable_subnet": vbng.routeable_subnet, "mac": vbng.mapped_mac, "hostname": vbng.mapped_hostname} )
+    #
+    #    return Response( {"vbng_mapping": mappings} )
 
-        mappings = []
-        for vbng in object_list:
-            if vbng.mapped_ip and vbng.routeable_subnet:
-                mappings.append( {"private_ip": vbng.mapped_ip, "routeable_subnet": vbng.routeable_subnet, "mac": vbng.mapped_mac, "hostname": vbng.mapped_hostname} )
 
-        return Response( {"vbng_mapping": mappings} )
-
-class CordDebugIdSerializer(serializers.ModelSerializer, PlusSerializerMixin):
-    # Swagger is failing because CordDebugViewSet has neither a model nor
-    # a serializer_class. Stuck this in here as a placeholder for now.
-    id = ReadOnlyField()
-    class Meta:
-        model = CordSubscriber
-
-class CordDebugViewSet(XOSViewSet):
-    base_name = "cord_debug"
-    method_name = "rs/cord_debug"
-    method_kind = "viewset"
-    serializer_class = CordDebugIdSerializer
-
-    @classmethod
-    def get_urlpatterns(self):
-        patterns = []
-        patterns.append( url("^rs/cord_debug/vbng_dump/$", self.as_view({"get": "get_vbng_dump"}), name="vbng_dump"))
-        return patterns
-
-    # contact vBNG service and dump current list of mappings
-    def get_vbng_dump(self, request, pk=None):
-        result=subprocess.check_output(["curl", "http://10.0.3.136:8181/onos/virtualbng/privateip/map"])
-        if request.GET.get("theformat",None)=="text":
-            from django.http import HttpResponse
-            result = json.loads(result)["map"]
-
-            lines = []
-            for row in result:
-                for k in row.keys():
-                     lines.append( "%s %s" % (k, row[k]) )
-
-            return HttpResponse("\n".join(lines), content_type="text/plain")
-        else:
-            return Response( {"vbng_dump": json.loads(result)["map"] } )
diff --git a/xos/core/xoslib/methods/truckroll.py b/xos/core/xoslib/methods/truckroll.py
deleted file mode 100644
index 917a676..0000000
--- a/xos/core/xoslib/methods/truckroll.py
+++ /dev/null
@@ -1,92 +0,0 @@
-from rest_framework.decorators import api_view
-from rest_framework.response import Response
-from rest_framework.reverse import reverse
-from rest_framework import serializers
-from rest_framework import generics
-from rest_framework import status
-from core.models import *
-from django.forms import widgets
-from services.cord.models import CordSubscriberRoot
-from services.vtr.models import VTRTenant, VTRService
-from plus import PlusSerializerMixin
-from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
-
-if hasattr(serializers, "ReadOnlyField"):
-    # rest_framework 3.x
-    ReadOnlyField = serializers.ReadOnlyField
-else:
-    # rest_framework 2.x
-    ReadOnlyField = serializers.Field
-
-def get_default_vtr_service():
-    vtr_services = VTRService.get_service_objects().all()
-    if vtr_services:
-        return vtr_services[0].id
-    return None
-
-class VTRTenantIdSerializer(serializers.ModelSerializer, PlusSerializerMixin):
-        id = ReadOnlyField()
-        target_id = serializers.IntegerField()
-        test = serializers.CharField()
-        scope = serializers.CharField()
-        argument = serializers.CharField(required=False)
-        provider_service = serializers.PrimaryKeyRelatedField(queryset=VTRService.get_service_objects().all(), default=get_default_vtr_service)
-        result = serializers.CharField(required=False)
-        result_code = serializers.CharField(required=False)
-        backend_status = ReadOnlyField()
-
-        humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
-        is_synced = serializers.SerializerMethodField("isSynced")
-
-        class Meta:
-            model = VTRTenant
-            fields = ('humanReadableName', 'id', 'provider_service', 'target_id', 'scope', 'test', 'argument', 'result', 'result_code', 'is_synced', 'backend_status' )
-
-        def getHumanReadableName(self, obj):
-            return obj.__unicode__()
-
-        def isSynced(self, obj):
-            return (obj.enacted is not None) and (obj.enacted >= obj.updated)
-
-class VTRTenantList(XOSListCreateAPIView):
-    serializer_class = VTRTenantIdSerializer
-
-    method_kind = "list"
-    method_name = "truckroll"
-
-    def get_queryset(self):
-        queryset = VTRTenant.get_tenant_objects().select_related().all()
-
-        test = self.request.QUERY_PARAMS.get('test', None)
-        if test is not None:
-            ids = [x.id for x in queryset if x.get_attribute("test", None)==test]
-            queryset = queryset.filter(id__in=ids)
-
-        return queryset
-
-    def post(self, request, format=None):
-        data = request.DATA
-
-        existing_obj = None
-#        for obj in VTRTenant.get_tenant_objects().all():
-#            if (obj.tesst == data.get("test", None)) and (obj.target == data.get("target", None))):
-#               existing_obj = obj
-
-        if existing_obj:
-            serializer = VTRTenantIdSerializer(existing_obj)
-            headers = self.get_success_headers(serializer.data)
-            return Response( serializer.data, status=status.HTTP_200_OK )
-
-        return super(VTRTenantList, self).post(request, format)
-
-class VTRTenantDetail(XOSRetrieveUpdateDestroyAPIView):
-    serializer_class = VTRTenantIdSerializer
-    queryset = VTRTenant.get_tenant_objects().select_related().all()
-
-    method_kind = "detail"
-    method_name = "truckroll"
-
-
-
-
-
diff --git a/xos/core/xoslib/methods/volttenant.py b/xos/core/xoslib/methods/volttenant._unused
similarity index 97%
rename from xos/core/xoslib/methods/volttenant.py
rename to xos/core/xoslib/methods/volttenant._unused
index 25559a0..03a2a97 100644
--- a/xos/core/xoslib/methods/volttenant.py
+++ b/xos/core/xoslib/methods/volttenant._unused
@@ -6,7 +6,7 @@
 from rest_framework import status
 from core.models import *
 from django.forms import widgets
-from services.cord.models import VOLTTenant, VOLTService, CordSubscriberRoot
+from services.volt.models import VOLTTenant, VOLTService, CordSubscriberRoot
 from plus import PlusSerializerMixin
 from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
 
diff --git a/xos/core/xoslib/methods/vtn.py b/xos/core/xoslib/methods/vtn._unused
similarity index 100%
rename from xos/core/xoslib/methods/vtn.py
rename to xos/core/xoslib/methods/vtn._unused
diff --git a/xos/core/xoslib/objects/cordsubscriber.py b/xos/core/xoslib/objects/cordsubscriber.py
index 681b769..d97bd5a 100644
--- a/xos/core/xoslib/objects/cordsubscriber.py
+++ b/xos/core/xoslib/objects/cordsubscriber.py
@@ -1,23 +1,9 @@
 from core.models import Slice, SlicePrivilege, SliceRole, Instance, Site, Node, User
-from services.cord.models import VOLTTenant, CordSubscriberRoot
+from services.volt.models import VOLTTenant, CordSubscriberRoot
 from plus import PlusObjectMixin
 from operator import itemgetter, attrgetter
 from rest_framework.exceptions import APIException
 
-"""
-import os
-import sys
-sys.path.append("/opt/xos")
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
-import django
-from core.models import *
-from services.hpc.models import *
-from services.cord.models import *
-django.setup()
-from core.xoslib.objects.cordsubscriber import CordSubscriber
-c=CordSubscriber.get_tenant_objects().select_related().all()[0]
-"""
-
 class CordSubscriber(CordSubscriberRoot):
     class Meta:
         proxy = True
diff --git a/xos/onboard/exampleservice/api/tenant/exampletenant.py b/xos/onboard/exampleservice/api/tenant/exampletenant.py
index c50680f..f4778cc 100644
--- a/xos/onboard/exampleservice/api/tenant/exampletenant.py
+++ b/xos/onboard/exampleservice/api/tenant/exampletenant.py
@@ -6,7 +6,6 @@
 from rest_framework import status
 from core.models import *
 from django.forms import widgets
-from services.cord.models import CordSubscriberRoot
 from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
 from api.xosapi_helpers import PlusModelSerializer, XOSViewSet, ReadOnlyField
 
diff --git a/xos/services/onos/admin.py b/xos/onboard/onos/admin.py
similarity index 100%
rename from xos/services/onos/admin.py
rename to xos/onboard/onos/admin.py
diff --git a/xos/api/service/onos.py b/xos/onboard/onos/api/service/onos.py
similarity index 100%
rename from xos/api/service/onos.py
rename to xos/onboard/onos/api/service/onos.py
diff --git a/xos/api/tenant/onos/app.py b/xos/onboard/onos/api/tenant/onos/app.py
similarity index 100%
rename from xos/api/tenant/onos/app.py
rename to xos/onboard/onos/api/tenant/onos/app.py
diff --git a/xos/services/onos/models.py b/xos/onboard/onos/models.py
similarity index 100%
rename from xos/services/onos/models.py
rename to xos/onboard/onos/models.py
diff --git a/xos/onboard/onos/onos-onboard.yaml b/xos/onboard/onos/onos-onboard.yaml
new file mode 100644
index 0000000..1338bb6
--- /dev/null
+++ b/xos/onboard/onos/onos-onboard.yaml
@@ -0,0 +1,27 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Onboard the exampleservice
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+    servicecontroller#onos:
+      type: tosca.nodes.ServiceController
+      properties:
+          base_url: file:///opt/xos/onboard/onos/
+          # The following will concatenate with base_url automatically, if
+          # base_url is non-null.
+          models: models.py
+          admin: admin.py
+          admin_template: templates/onosadmin.html
+          synchronizer: synchronizer/manifest
+          synchronizer_run: onos-synchronizer.py
+          #tosca_custom_types: exampleservice.yaml
+          tosca_resource: tosca/resources/onosservice.py, tosca/resources/onosapp.py
+          rest_service: subdirectory:vsg api/service/onos.py
+          rest_tenant: subdirectory:onos api/tenant/onos/app.py
+          private_key: file:///opt/xos/key_import/onos_rsa
+          public_key: file:///opt/xos/key_import/onos_rsa.pub
+
diff --git a/xos/onboard/onos/synchronizer/manifest b/xos/onboard/onos/synchronizer/manifest
new file mode 100644
index 0000000..b96216a
--- /dev/null
+++ b/xos/onboard/onos/synchronizer/manifest
@@ -0,0 +1,16 @@
+manifest
+onos-ext-volt-event-publisher-1.0-SNAPSHOT.oar
+scripts/dockerip.sh
+steps/sync_onosapp.py
+steps/sync_onosapp_nocontainer.yaml
+steps/sync_onosservice.py
+steps/sync_onosservice.yaml
+steps/sync_onosapp.yaml
+onos-ext-notifier-1.0-SNAPSHOT.oar
+start.sh
+stop.sh
+model-deps
+onos_synchronizer_config
+supervisor/onos-observer.conf
+run.sh
+onos-synchronizer.py
diff --git a/xos/synchronizers/onos/model-deps b/xos/onboard/onos/synchronizer/model-deps
similarity index 100%
rename from xos/synchronizers/onos/model-deps
rename to xos/onboard/onos/synchronizer/model-deps
diff --git a/xos/synchronizers/onos/onos-ext-notifier-1.0-SNAPSHOT.oar b/xos/onboard/onos/synchronizer/onos-ext-notifier-1.0-SNAPSHOT.oar
similarity index 100%
rename from xos/synchronizers/onos/onos-ext-notifier-1.0-SNAPSHOT.oar
rename to xos/onboard/onos/synchronizer/onos-ext-notifier-1.0-SNAPSHOT.oar
Binary files differ
diff --git a/xos/synchronizers/onos/onos-ext-volt-event-publisher-1.0-SNAPSHOT.oar b/xos/onboard/onos/synchronizer/onos-ext-volt-event-publisher-1.0-SNAPSHOT.oar
similarity index 100%
rename from xos/synchronizers/onos/onos-ext-volt-event-publisher-1.0-SNAPSHOT.oar
rename to xos/onboard/onos/synchronizer/onos-ext-volt-event-publisher-1.0-SNAPSHOT.oar
Binary files differ
diff --git a/xos/synchronizers/onos/onos-synchronizer.py b/xos/onboard/onos/synchronizer/onos-synchronizer.py
similarity index 100%
rename from xos/synchronizers/onos/onos-synchronizer.py
rename to xos/onboard/onos/synchronizer/onos-synchronizer.py
diff --git a/xos/synchronizers/onos/onos_synchronizer_config b/xos/onboard/onos/synchronizer/onos_synchronizer_config
similarity index 100%
rename from xos/synchronizers/onos/onos_synchronizer_config
rename to xos/onboard/onos/synchronizer/onos_synchronizer_config
diff --git a/xos/synchronizers/onos/run.sh b/xos/onboard/onos/synchronizer/run.sh
similarity index 100%
rename from xos/synchronizers/onos/run.sh
rename to xos/onboard/onos/synchronizer/run.sh
diff --git a/xos/synchronizers/onos/scripts/dockerip.sh b/xos/onboard/onos/synchronizer/scripts/dockerip.sh
similarity index 100%
rename from xos/synchronizers/onos/scripts/dockerip.sh
rename to xos/onboard/onos/synchronizer/scripts/dockerip.sh
diff --git a/xos/synchronizers/onos/start.sh b/xos/onboard/onos/synchronizer/start.sh
similarity index 100%
rename from xos/synchronizers/onos/start.sh
rename to xos/onboard/onos/synchronizer/start.sh
diff --git a/xos/synchronizers/onos/steps/sync_onosapp.py b/xos/onboard/onos/synchronizer/steps/sync_onosapp.py
similarity index 98%
rename from xos/synchronizers/onos/steps/sync_onosapp.py
rename to xos/onboard/onos/synchronizer/steps/sync_onosapp.py
index 3a9abfc..78a8cc8 100644
--- a/xos/synchronizers/onos/steps/sync_onosapp.py
+++ b/xos/onboard/onos/synchronizer/steps/sync_onosapp.py
@@ -18,7 +18,7 @@
 from xos.logger import Logger, logging
 from services.vrouter.models import VRouterService
 from services.vtn.models import VTNService
-from services.cord.models import VOLTService, VOLTDevice, AccessDevice
+from services.volt.models import VOLTService, VOLTDevice, AccessDevice
 
 # hpclibrary will be in steps/..
 parentdir = os.path.join(os.path.dirname(__file__),"..")
@@ -31,7 +31,7 @@
     observes=ONOSApp
     requested_interval=0
     template_name = "sync_onosapp.yaml"
-    service_key_name = "/opt/xos/synchronizers/onos/onos_key"
+    #service_key_name = "/opt/xos/synchronizers/onos/onos_key"
 
     def __init__(self, *args, **kwargs):
         super(SyncONOSApp, self).__init__(*args, **kwargs)
diff --git a/xos/synchronizers/onos/steps/sync_onosapp.yaml b/xos/onboard/onos/synchronizer/steps/sync_onosapp.yaml
similarity index 100%
rename from xos/synchronizers/onos/steps/sync_onosapp.yaml
rename to xos/onboard/onos/synchronizer/steps/sync_onosapp.yaml
diff --git a/xos/synchronizers/onos/steps/sync_onosapp_nocontainer.yaml b/xos/onboard/onos/synchronizer/steps/sync_onosapp_nocontainer.yaml
similarity index 100%
rename from xos/synchronizers/onos/steps/sync_onosapp_nocontainer.yaml
rename to xos/onboard/onos/synchronizer/steps/sync_onosapp_nocontainer.yaml
diff --git a/xos/synchronizers/onos/steps/sync_onosservice.py b/xos/onboard/onos/synchronizer/steps/sync_onosservice.py
similarity index 97%
rename from xos/synchronizers/onos/steps/sync_onosservice.py
rename to xos/onboard/onos/synchronizer/steps/sync_onosservice.py
index 2e6acd9..ce446cf 100644
--- a/xos/synchronizers/onos/steps/sync_onosservice.py
+++ b/xos/onboard/onos/synchronizer/steps/sync_onosservice.py
@@ -24,7 +24,7 @@
     observes=ONOSService
     requested_interval=0
     template_name = "sync_onosservice.yaml"
-    service_key_name = "/opt/xos/synchronizers/onos/onos_key"
+    #service_key_name = "/opt/xos/synchronizers/onos/onos_key"
 
     def __init__(self, *args, **kwargs):
         super(SyncONOSService, self).__init__(*args, **kwargs)
diff --git a/xos/synchronizers/onos/steps/sync_onosservice.yaml b/xos/onboard/onos/synchronizer/steps/sync_onosservice.yaml
similarity index 100%
rename from xos/synchronizers/onos/steps/sync_onosservice.yaml
rename to xos/onboard/onos/synchronizer/steps/sync_onosservice.yaml
diff --git a/xos/synchronizers/onos/stop.sh b/xos/onboard/onos/synchronizer/stop.sh
similarity index 100%
rename from xos/synchronizers/onos/stop.sh
rename to xos/onboard/onos/synchronizer/stop.sh
diff --git a/xos/synchronizers/onos/supervisor/onos-observer.conf b/xos/onboard/onos/synchronizer/supervisor/onos-observer.conf
similarity index 100%
rename from xos/synchronizers/onos/supervisor/onos-observer.conf
rename to xos/onboard/onos/synchronizer/supervisor/onos-observer.conf
diff --git a/xos/services/onos/templates/onosadmin.html b/xos/onboard/onos/templates/onosadmin.html
similarity index 100%
rename from xos/services/onos/templates/onosadmin.html
rename to xos/onboard/onos/templates/onosadmin.html
diff --git a/xos/tosca/resources/onosapp.py b/xos/onboard/onos/tosca/resources/onosapp.py
similarity index 100%
rename from xos/tosca/resources/onosapp.py
rename to xos/onboard/onos/tosca/resources/onosapp.py
diff --git a/xos/tosca/resources/onosservice.py b/xos/onboard/onos/tosca/resources/onosservice.py
similarity index 100%
rename from xos/tosca/resources/onosservice.py
rename to xos/onboard/onos/tosca/resources/onosservice.py
diff --git a/xos/onboard/volt/admin.py b/xos/onboard/volt/admin.py
new file mode 100644
index 0000000..cf5dfa6
--- /dev/null
+++ b/xos/onboard/volt/admin.py
@@ -0,0 +1,237 @@
+from django.contrib import admin
+
+from services.volt.models import *
+from django import forms
+from django.utils.safestring import mark_safe
+from django.contrib.auth.admin import UserAdmin
+from django.contrib.admin.widgets import FilteredSelectMultiple
+from django.contrib.auth.forms import ReadOnlyPasswordHashField
+from django.contrib.auth.signals import user_logged_in
+from django.utils import timezone
+from django.contrib.contenttypes import generic
+from suit.widgets import LinkedSelect
+from core.admin import ServiceAppAdmin,SliceInline,ServiceAttrAsTabInline, ReadOnlyAwareAdmin, XOSTabularInline, ServicePrivilegeInline, TenantRootTenantInline, TenantRootPrivilegeInline
+from core.middleware import get_request
+
+from functools import update_wrapper
+from django.contrib.admin.views.main import ChangeList
+from django.core.urlresolvers import reverse
+from django.contrib.admin.utils import quote
+
+#-----------------------------------------------------------------------------
+# vOLT
+#-----------------------------------------------------------------------------
+
+class VOLTServiceAdmin(ReadOnlyAwareAdmin):
+    model = VOLTService
+    verbose_name = "vOLT Service"
+    verbose_name_plural = "vOLT Service"
+    list_display = ("backend_status_icon", "name", "enabled")
+    list_display_links = ('backend_status_icon', 'name', )
+    fieldsets = [(None, {'fields': ['backend_status_text', 'name','enabled','versionNumber', 'description',"view_url","icon_url" ], 'classes':['suit-tab suit-tab-general']})]
+    readonly_fields = ('backend_status_text', )
+    inlines = [SliceInline,ServiceAttrAsTabInline,ServicePrivilegeInline]
+
+    extracontext_registered_admins = True
+
+    user_readonly_fields = ["name", "enabled", "versionNumber", "description"]
+
+    suit_form_tabs =(('general', 'vOLT Service Details'),
+        ('administration', 'Administration'),
+        #('tools', 'Tools'),
+        ('slices','Slices'),
+        ('serviceattrs','Additional Attributes'),
+        ('serviceprivileges','Privileges'),
+    )
+
+    suit_form_includes = (('voltadmin.html', 'top', 'administration'),
+                           ) #('hpctools.html', 'top', 'tools') )
+
+    def queryset(self, request):
+        return VOLTService.get_service_objects_by_user(request.user)
+
+class VOLTTenantForm(forms.ModelForm):
+    s_tag = forms.CharField()
+    c_tag = forms.CharField()
+    creator = forms.ModelChoiceField(queryset=User.objects.all())
+
+    def __init__(self,*args,**kwargs):
+        super (VOLTTenantForm,self ).__init__(*args,**kwargs)
+        self.fields['kind'].widget.attrs['readonly'] = True
+        self.fields['provider_service'].queryset = VOLTService.get_service_objects().all()
+        if self.instance:
+            # fields for the attributes
+            self.fields['c_tag'].initial = self.instance.c_tag
+            self.fields['s_tag'].initial = self.instance.s_tag
+            self.fields['creator'].initial = self.instance.creator
+        if (not self.instance) or (not self.instance.pk):
+            # default fields for an 'add' form
+            self.fields['kind'].initial = VOLT_KIND
+            self.fields['creator'].initial = get_request().user
+            if VOLTService.get_service_objects().exists():
+               self.fields["provider_service"].initial = VOLTService.get_service_objects().all()[0]
+
+    def save(self, commit=True):
+        self.instance.s_tag = self.cleaned_data.get("s_tag")
+        self.instance.c_tag = self.cleaned_data.get("c_tag")
+        self.instance.creator = self.cleaned_data.get("creator")
+        return super(VOLTTenantForm, self).save(commit=commit)
+
+    class Meta:
+        model = VOLTTenant
+
+class VOLTTenantAdmin(ReadOnlyAwareAdmin):
+    list_display = ('backend_status_icon', 'id', 'service_specific_id', 's_tag', 'c_tag', 'subscriber_root' )
+    list_display_links = ('backend_status_icon', 'id')
+    fieldsets = [ (None, {'fields': ['backend_status_text', 'kind', 'provider_service', 'subscriber_root', 'service_specific_id', # 'service_specific_attribute',
+                                     's_tag', 'c_tag', 'creator'],
+                          'classes':['suit-tab suit-tab-general']})]
+    readonly_fields = ('backend_status_text', 'service_specific_attribute')
+    form = VOLTTenantForm
+
+    suit_form_tabs = (('general','Details'),)
+
+    def queryset(self, request):
+        return VOLTTenant.get_tenant_objects_by_user(request.user)
+
+class AccessDeviceInline(XOSTabularInline):
+    model = AccessDevice
+    fields = ['volt_device','uplink','vlan']
+    readonly_fields = []
+    extra = 0
+#    max_num = 0
+    suit_classes = 'suit-tab suit-tab-accessdevices'
+
+#    @property
+#    def selflink_reverse_path(self):
+#        return "admin:cord_volttenant_change"
+
+class VOLTDeviceAdmin(ReadOnlyAwareAdmin):
+    list_display = ('backend_status_icon', 'name', 'openflow_id', 'driver' )
+    list_display_links = ('backend_status_icon', 'name', 'openflow_id')
+    fieldsets = [ (None, {'fields': ['backend_status_text','name','volt_service','openflow_id','driver','access_agent'],
+                          'classes':['suit-tab suit-tab-general']})]
+    readonly_fields = ('backend_status_text',)
+    inlines = [AccessDeviceInline]
+
+    suit_form_tabs = (('general','Details'), ('accessdevices','Access Devices'))
+
+class AccessDeviceAdmin(ReadOnlyAwareAdmin):
+    list_display = ('backend_status_icon', 'id', 'volt_device', 'uplink', 'vlan' )
+    list_display_links = ('backend_status_icon', 'id')
+    fieldsets = [ (None, {'fields': ['backend_status_text','volt_device','uplink','vlan'],
+                          'classes':['suit-tab suit-tab-general']})]
+    readonly_fields = ('backend_status_text',)
+
+    suit_form_tabs = (('general','Details'),)
+
+class AgentPortMappingInline(XOSTabularInline):
+    model = AgentPortMapping
+    fields = ['access_agent', 'mac', 'port']
+    readonly_fields = []
+    extra = 0
+#    max_num = 0
+    suit_classes = 'suit-tab suit-tab-accessportmaps'
+
+#    @property
+#    def selflink_reverse_path(self):
+#        return "admin:cord_volttenant_change"
+
+class AccessAgentAdmin(ReadOnlyAwareAdmin):
+    list_display = ('backend_status_icon', 'name', 'mac' )
+    list_display_links = ('backend_status_icon', 'name')
+    fieldsets = [ (None, {'fields': ['backend_status_text','name','volt_service','mac'],
+                          'classes':['suit-tab suit-tab-general']})]
+    readonly_fields = ('backend_status_text',)
+    inlines= [AgentPortMappingInline]
+
+    suit_form_tabs = (('general','Details'), ('accessportmaps', 'Port Mappings'))
+
+# -------------------------------------------
+# CORDSubscriberRoot
+# -------------------------------------------
+
+class VOLTTenantInline(XOSTabularInline):
+    model = VOLTTenant
+    fields = ['provider_service', 'subscriber_root', 'service_specific_id']
+    readonly_fields = ['provider_service', 'subscriber_root', 'service_specific_id']
+    extra = 0
+    max_num = 0
+    suit_classes = 'suit-tab suit-tab-volttenants'
+    fk_name = 'subscriber_root'
+    verbose_name = 'subscribed tenant'
+    verbose_name_plural = 'subscribed tenants'
+
+    @property
+    def selflink_reverse_path(self):
+        return "admin:cord_volttenant_change"
+
+    def queryset(self, request):
+        qs = super(VOLTTenantInline, self).queryset(request)
+        return qs.filter(kind=VOLT_KIND)
+
+class CordSubscriberRootForm(forms.ModelForm):
+    url_filter_level = forms.CharField(required = False)
+    uplink_speed = forms.CharField(required = False)
+    downlink_speed = forms.CharField(required = False)
+    status = forms.ChoiceField(choices=CordSubscriberRoot.status_choices, required=True)
+    enable_uverse = forms.BooleanField(required=False)
+    cdn_enable = forms.BooleanField(required=False)
+
+    def __init__(self,*args,**kwargs):
+        super (CordSubscriberRootForm,self ).__init__(*args,**kwargs)
+        self.fields['kind'].widget.attrs['readonly'] = True
+        if self.instance:
+            self.fields['url_filter_level'].initial = self.instance.url_filter_level
+            self.fields['uplink_speed'].initial = self.instance.uplink_speed
+            self.fields['downlink_speed'].initial = self.instance.downlink_speed
+            self.fields['status'].initial = self.instance.status
+            self.fields['enable_uverse'].initial = self.instance.enable_uverse
+            self.fields['cdn_enable'].initial = self.instance.cdn_enable
+        if (not self.instance) or (not self.instance.pk):
+            # default fields for an 'add' form
+            self.fields['kind'].initial = CORD_SUBSCRIBER_KIND
+            self.fields['uplink_speed'].initial = CordSubscriberRoot.get_default_attribute("uplink_speed")
+            self.fields['downlink_speed'].initial = CordSubscriberRoot.get_default_attribute("downlink_speed")
+            self.fields['status'].initial = CordSubscriberRoot.get_default_attribute("status")
+            self.fields['enable_uverse'].initial = CordSubscriberRoot.get_default_attribute("enable_uverse")
+            self.fields['cdn_enable'].initial = CordSubscriberRoot.get_default_attribute("cdn_enable")
+
+    def save(self, commit=True):
+        self.instance.url_filter_level = self.cleaned_data.get("url_filter_level")
+        self.instance.uplink_speed = self.cleaned_data.get("uplink_speed")
+        self.instance.downlink_speed = self.cleaned_data.get("downlink_speed")
+        self.instance.status = self.cleaned_data.get("status")
+        self.instance.enable_uverse = self.cleaned_data.get("enable_uverse")
+        self.instance.cdn_enable = self.cleaned_data.get("cdn_enable")
+        return super(CordSubscriberRootForm, self).save(commit=commit)
+
+    class Meta:
+        model = CordSubscriberRoot
+
+class CordSubscriberRootAdmin(ReadOnlyAwareAdmin):
+    list_display = ('backend_status_icon', 'id',  'name', )
+    list_display_links = ('backend_status_icon', 'id', 'name', )
+    fieldsets = [ (None, {'fields': ['backend_status_text', 'kind', 'name', 'service_specific_id', # 'service_specific_attribute',
+                                     'url_filter_level', "uplink_speed", "downlink_speed", "status", "enable_uverse", "cdn_enable"],
+                          'classes':['suit-tab suit-tab-general']})]
+    readonly_fields = ('backend_status_text', 'service_specific_attribute',)
+    form = CordSubscriberRootForm
+    inlines = (VOLTTenantInline, TenantRootPrivilegeInline)
+
+    suit_form_tabs =(('general', 'Cord Subscriber Root Details'),
+        ('volttenants','VOLT Tenancy'),
+        ('tenantrootprivileges','Privileges')
+    )
+
+    def queryset(self, request):
+        return CordSubscriberRoot.get_tenant_objects_by_user(request.user)
+
+admin.site.register(VOLTService, VOLTServiceAdmin)
+admin.site.register(VOLTTenant, VOLTTenantAdmin)
+admin.site.register(VOLTDevice, VOLTDeviceAdmin)
+admin.site.register(AccessDevice, AccessDeviceAdmin)
+admin.site.register(AccessAgent, AccessAgentAdmin)
+
+admin.site.register(CordSubscriberRoot, CordSubscriberRootAdmin)
+
diff --git a/xos/api/tenant/cord/subscriber.py b/xos/onboard/volt/api/tenant/cord/subscriber.py
similarity index 99%
rename from xos/api/tenant/cord/subscriber.py
rename to xos/onboard/volt/api/tenant/cord/subscriber.py
index eab6cb3..52f9b63 100644
--- a/xos/api/tenant/cord/subscriber.py
+++ b/xos/onboard/volt/api/tenant/cord/subscriber.py
@@ -10,7 +10,7 @@
 from core.models import *
 from django.forms import widgets
 from django.conf.urls import patterns, url
-from services.cord.models import VOLTTenant, VBNGTenant, CordSubscriberRoot
+from services.volt.models import VOLTTenant, CordSubscriberRoot
 from api.xosapi_helpers import PlusModelSerializer, XOSViewSet, ReadOnlyField
 from django.shortcuts import get_object_or_404
 from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
diff --git a/xos/api/tenant/cord/volt.py b/xos/onboard/volt/api/tenant/cord/volt.py
similarity index 97%
rename from xos/api/tenant/cord/volt.py
rename to xos/onboard/volt/api/tenant/cord/volt.py
index e17cf26..5c9634a 100644
--- a/xos/api/tenant/cord/volt.py
+++ b/xos/onboard/volt/api/tenant/cord/volt.py
@@ -6,7 +6,7 @@
 from rest_framework import status
 from core.models import *
 from django.forms import widgets
-from services.cord.models import VOLTTenant, VOLTService, CordSubscriberRoot
+from services.volt.models import VOLTTenant, VOLTService, CordSubscriberRoot
 from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
 from api.xosapi_helpers import PlusModelSerializer, XOSViewSet, ReadOnlyField
 
diff --git a/xos/onboard/volt/models.py b/xos/onboard/volt/models.py
new file mode 100644
index 0000000..8f3cc1f
--- /dev/null
+++ b/xos/onboard/volt/models.py
@@ -0,0 +1,367 @@
+from django.db import models
+from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, Subscriber, NetworkParameter, NetworkParameterType, Port, AddressPool, User
+from core.models.plcorebase import StrippedCharField
+import os
+from django.db import models, transaction
+from django.forms.models import model_to_dict
+from django.db.models import Q
+from operator import itemgetter, attrgetter, methodcaller
+from core.models import Tag
+from core.models.service import LeastLoadedNodeScheduler
+from services.vrouter.models import VRouterService, VRouterTenant
+import traceback
+from xos.exceptions import *
+from xos.config import Config
+
+class ConfigurationError(Exception):
+    pass
+
+VOLT_KIND = "vOLT"
+CORD_SUBSCRIBER_KIND = "CordSubscriberRoot"
+
+CORD_USE_VTN = getattr(Config(), "networking_use_vtn", False)
+
+# -------------------------------------------
+# CordSubscriberRoot
+# -------------------------------------------
+
+class CordSubscriberRoot(Subscriber):
+    class Meta:
+        proxy = True
+
+    KIND = CORD_SUBSCRIBER_KIND
+
+    status_choices = (("enabled", "Enabled"),
+                      ("suspended", "Suspended"),
+                      ("delinquent", "Delinquent"),
+                      ("copyrightviolation", "Copyright Violation"))
+
+    # 'simple_attributes' will be expanded into properties and setters that
+    # store the attribute using self.set_attribute / self.get_attribute.
+
+    simple_attributes = ( ("firewall_enable", False),
+                          ("firewall_rules", "accept all anywhere anywhere"),
+                          ("url_filter_enable", False),
+                          ("url_filter_rules", "allow all"),
+                          ("url_filter_level", "PG"),
+                          ("cdn_enable", False),
+                          ("devices", []),
+                          ("is_demo_user", False),
+
+                          ("uplink_speed", 1000000000),  # 1 gigabit, a reasonable default?
+                          ("downlink_speed", 1000000000),
+                          ("enable_uverse", True) )
+
+    default_attributes = {"status": "enabled"}
+
+    sync_attributes = ("firewall_enable",
+                       "firewall_rules",
+                       "url_filter_enable",
+                       "url_filter_rules",
+                       "cdn_enable",
+                       "uplink_speed",
+                       "downlink_speed",
+                       "enable_uverse",
+                       "status")
+
+    def __init__(self, *args, **kwargs):
+        super(CordSubscriberRoot, self).__init__(*args, **kwargs)
+        self.cached_volt = None
+        self._initial_url_filter_enable = self.url_filter_enable
+
+    @property
+    def volt(self):
+        volt = self.get_newest_subscribed_tenant(VOLTTenant)
+        if not volt:
+            return None
+
+        # always return the same object when possible
+        if (self.cached_volt) and (self.cached_volt.id == volt.id):
+            return self.cached_volt
+
+        #volt.caller = self.creator
+        self.cached_volt = volt
+        return volt
+
+    @property
+    def status(self):
+        return self.get_attribute("status", self.default_attributes["status"])
+
+    @status.setter
+    def status(self, value):
+        if not value in [x[0] for x in self.status_choices]:
+            raise Exception("invalid status %s" % value)
+        self.set_attribute("status", value)
+
+    def find_device(self, mac):
+        for device in self.devices:
+            if device["mac"] == mac:
+                return device
+        return None
+
+    def update_device(self, mac, **kwargs):
+        # kwargs may be "level" or "mac"
+        #    Setting one of these to None will cause None to be stored in the db
+        devices = self.devices
+        for device in devices:
+            if device["mac"] == mac:
+                for arg in kwargs.keys():
+                    device[arg] = kwargs[arg]
+                self.devices = devices
+                return device
+        raise ValueError("Device with mac %s not found" % mac)
+
+    def create_device(self, **kwargs):
+        if "mac" not in kwargs:
+            raise XOSMissingField("The mac field is required")
+
+        if self.find_device(kwargs['mac']):
+                raise XOSDuplicateKey("Device with mac %s already exists" % kwargs["mac"])
+
+        device = kwargs.copy()
+
+        devices = self.devices
+        devices.append(device)
+        self.devices = devices
+
+        return device
+
+    def delete_device(self, mac):
+        devices = self.devices
+        for device in devices:
+            if device["mac"]==mac:
+                devices.remove(device)
+                self.devices = devices
+                return
+
+        raise ValueError("Device with mac %s not found" % mac)
+
+    #--------------------------------------------------------------------------
+    # Deprecated -- devices used to be called users
+
+    def find_user(self, uid):
+        return self.find_device(uid)
+
+    def update_user(self, uid, **kwargs):
+        return self.update_device(uid, **kwargs)
+
+    def create_user(self, **kwargs):
+        return self.create_device(**kwargs)
+
+    def delete_user(self, uid):
+        return self.delete_user(uid)
+
+    # ------------------------------------------------------------------------
+
+    @property
+    def services(self):
+        return {"cdn": self.cdn_enable,
+                "url_filter": self.url_filter_enable,
+                "firewall": self.firewall_enable}
+
+    @services.setter
+    def services(self, value):
+        pass
+
+    def save(self, *args, **kwargs):
+        self.validate_unique_service_specific_id(none_okay=True)
+        if (not hasattr(self, 'caller') or not self.caller.is_admin):
+            if (self.has_field_changed("service_specific_id")):
+                raise XOSPermissionDenied("You do not have permission to change service_specific_id")
+        super(CordSubscriberRoot, self).save(*args, **kwargs)
+        if (self.volt) and (self.volt.vcpe): # and (self._initial_url_filter_enabled != self.url_filter_enable):
+            # 1) trigger manage_bbs_account to run
+            # 2) trigger vcpe observer to wake up
+            self.volt.vcpe.save()
+
+CordSubscriberRoot.setup_simple_attributes()
+
+# -------------------------------------------
+# VOLT
+# -------------------------------------------
+
+class VOLTService(Service):
+    KIND = VOLT_KIND
+
+    class Meta:
+        app_label = "volt"
+        verbose_name = "vOLT Service"
+
+class VOLTTenant(Tenant):
+    KIND = VOLT_KIND
+
+    class Meta:
+        app_label = "volt"
+        verbose_name = "vOLT Tenant"
+
+    s_tag = models.IntegerField(null=True, blank=True, help_text="s-tag")
+    c_tag = models.IntegerField(null=True, blank=True, help_text="c-tag")
+
+    # at some point, this should probably end up part of Tenant.
+    creator = models.ForeignKey(User, related_name='created_volts', blank=True, null=True)
+
+    def __init__(self, *args, **kwargs):
+        volt_services = VOLTService.get_service_objects().all()
+        if volt_services:
+            self._meta.get_field("provider_service").default = volt_services[0].id
+        super(VOLTTenant, self).__init__(*args, **kwargs)
+        self.cached_vcpe = None
+
+    @property
+    def vcpe(self):
+        from services.vsg.models import VSGTenant
+        vcpe = self.get_newest_subscribed_tenant(VSGTenant)
+        if not vcpe:
+            return None
+
+        # always return the same object when possible
+        if (self.cached_vcpe) and (self.cached_vcpe.id == vcpe.id):
+            return self.cached_vcpe
+
+        vcpe.caller = self.creator
+        self.cached_vcpe = vcpe
+        return vcpe
+
+    @vcpe.setter
+    def vcpe(self, value):
+        raise XOSConfigurationError("vOLT.vCPE cannot be set this way -- create a new vCPE object and set its subscriber_tenant instead")
+
+    @property
+    def subscriber(self):
+        if not self.subscriber_root:
+            return None
+        subs = CordSubscriberRoot.objects.filter(id=self.subscriber_root.id)
+        if not subs:
+            return None
+        return subs[0]
+
+    def manage_vcpe(self):
+        # Each VOLT object owns exactly one VCPE object
+
+        if self.deleted:
+            return
+
+        if self.vcpe is None:
+            from services.vsg.models import VSGService, VSGTenant
+            vsgServices = VSGService.get_service_objects().all()
+            if not vsgServices:
+                raise XOSConfigurationError("No VSG Services available")
+
+            vcpe = VSGTenant(provider_service = vsgServices[0],
+                              subscriber_tenant = self)
+            vcpe.caller = self.creator
+            vcpe.save()
+
+    def manage_subscriber(self):
+        if (self.subscriber_root is None):
+            # The vOLT is not connected to a Subscriber, so either find an
+            # existing subscriber with the same SSID, or autogenerate a new
+            # subscriber.
+            #
+            # TODO: This probably goes away when we rethink the ONOS-to-XOS
+            # vOLT API.
+
+            subs = CordSubscriberRoot.get_tenant_objects().filter(service_specific_id = self.service_specific_id)
+            if subs:
+                sub = subs[0]
+            else:
+                sub = CordSubscriberRoot(service_specific_id = self.service_specific_id,
+                                         name = "autogenerated-for-vOLT-%s" % self.id)
+                sub.save()
+            self.subscriber_root = sub
+            self.save()
+
+    def cleanup_vcpe(self):
+        if self.vcpe:
+            # print "XXX cleanup vcpe", self.vcpe
+            self.vcpe.delete()
+
+    def cleanup_orphans(self):
+        from services.vsg.models import VSGTenant
+        # ensure vOLT only has one vCPE
+        cur_vcpe = self.vcpe
+        for vcpe in list(self.get_subscribed_tenants(VSGTenant)):
+            if (not cur_vcpe) or (vcpe.id != cur_vcpe.id):
+                # print "XXX clean up orphaned vcpe", vcpe
+                vcpe.delete()
+
+    def save(self, *args, **kwargs):
+        # VOLTTenant probably doesn't need a SSID anymore; that will be handled
+        # by CORDSubscriberRoot...
+        # self.validate_unique_service_specific_id()
+
+        if (self.subscriber_root is not None):
+            subs = self.subscriber_root.get_subscribed_tenants(VOLTTenant)
+            if (subs) and (self not in subs):
+                raise XOSDuplicateKey("Subscriber should only be linked to one vOLT")
+
+        if not self.creator:
+            if not getattr(self, "caller", None):
+                # caller must be set when creating a vCPE since it creates a slice
+                raise XOSProgrammingError("VOLTTenant's self.caller was not set")
+            self.creator = self.caller
+            if not self.creator:
+                raise XOSProgrammingError("VOLTTenant's self.creator was not set")
+
+        super(VOLTTenant, self).save(*args, **kwargs)
+        model_policy_volt(self.pk)
+
+    def delete(self, *args, **kwargs):
+        self.cleanup_vcpe()
+        super(VOLTTenant, self).delete(*args, **kwargs)
+
+def model_policy_volt(pk):
+    # TODO: this should be made in to a real model_policy
+    with transaction.atomic():
+        volt = VOLTTenant.objects.select_for_update().filter(pk=pk)
+        if not volt:
+            return
+        volt = volt[0]
+        volt.manage_vcpe()
+        volt.manage_subscriber()
+        volt.cleanup_orphans()
+
+class VOLTDevice(PlCoreBase):
+    class Meta:
+        app_label = "volt"
+
+    name = models.CharField(max_length=254, help_text="name of device", null=False, blank=False)
+    volt_service = models.ForeignKey(VOLTService, related_name='volt_devices')
+    openflow_id = models.CharField(max_length=254, help_text="OpenFlow ID", null=True, blank=True)
+    driver = models.CharField(max_length=254, help_text="driver", null=True, blank=True)
+    access_agent = models.ForeignKey("AccessAgent", related_name='volt_devices', blank=True, null=True)
+
+    def __unicode__(self): return u'%s' % (self.name)
+
+class AccessDevice(PlCoreBase):
+    class Meta:
+        app_label = "volt"
+
+    volt_device = models.ForeignKey(VOLTDevice, related_name='access_devices')
+    uplink = models.IntegerField(null=True, blank=True)
+    vlan = models.IntegerField(null=True, blank=True)
+
+    def __unicode__(self): return u'%s-%d:%d' % (self.volt_device.name,self.uplink,self.vlan)
+
+class AccessAgent(PlCoreBase):
+    class Meta:
+        app_label = "volt"
+
+    name = models.CharField(max_length=254, help_text="name of agent", null=False, blank=False)
+    volt_service = models.ForeignKey(VOLTService, related_name='access_agents')
+    mac = models.CharField(max_length=32, help_text="MAC Address or Access Agent", null=True, blank=True)
+
+    def __unicode__(self): return u'%s' % (self.name)
+
+class AgentPortMapping(PlCoreBase):
+    class Meta:
+        app_label = "volt"
+
+    access_agent = models.ForeignKey(AccessAgent, related_name='port_mappings')
+    mac = models.CharField(max_length=32, help_text="MAC Address", null=True, blank=True)
+    port = models.CharField(max_length=32, help_text="Openflow port ID", null=True, blank=True)
+
+    def __unicode__(self): return u'%s-%s-%s' % (self.access_agent.name, self.port, self.mac)
+
+
+
diff --git a/xos/services/cord/templates/voltadmin.html b/xos/onboard/volt/templates/voltadmin.html
similarity index 100%
rename from xos/services/cord/templates/voltadmin.html
rename to xos/onboard/volt/templates/voltadmin.html
diff --git a/xos/tosca/resources/CORDSubscriber.py b/xos/onboard/volt/tosca/resources/CORDSubscriber.py
similarity index 93%
rename from xos/tosca/resources/CORDSubscriber.py
rename to xos/onboard/volt/tosca/resources/CORDSubscriber.py
index f013032..5cdb2ef 100644
--- a/xos/tosca/resources/CORDSubscriber.py
+++ b/xos/onboard/volt/tosca/resources/CORDSubscriber.py
@@ -7,7 +7,7 @@
 import pdb
 
 from core.models import User, TenantRootPrivilege, TenantRootRole
-from services.cord.models import CordSubscriberRoot
+from services.volt.models import CordSubscriberRoot
 
 from xosresource import XOSResource
 
diff --git a/xos/tosca/resources/CORDUser.py b/xos/onboard/volt/tosca/resources/CORDUser.py
similarity index 96%
rename from xos/tosca/resources/CORDUser.py
rename to xos/onboard/volt/tosca/resources/CORDUser.py
index ff2dc8f..d1ae1cc 100644
--- a/xos/tosca/resources/CORDUser.py
+++ b/xos/onboard/volt/tosca/resources/CORDUser.py
@@ -7,7 +7,7 @@
 import pdb
 
 from core.models import User
-from services.cord.models import CordSubscriberRoot
+from services.volt.models import CordSubscriberRoot
 
 from xosresource import XOSResource
 
diff --git a/xos/tosca/resources/VOLTTenant.py b/xos/onboard/volt/tosca/resources/VOLTTenant.py
similarity index 96%
rename from xos/tosca/resources/VOLTTenant.py
rename to xos/onboard/volt/tosca/resources/VOLTTenant.py
index ae1692d..cbc3837 100644
--- a/xos/tosca/resources/VOLTTenant.py
+++ b/xos/onboard/volt/tosca/resources/VOLTTenant.py
@@ -7,7 +7,7 @@
 import pdb
 
 from core.models import User
-from services.cord.models import VOLTTenant, VOLTService, CordSubscriberRoot, VOLT_KIND
+from services.volt.models import VOLTTenant, VOLTService, CordSubscriberRoot, VOLT_KIND
 
 from xosresource import XOSResource
 
diff --git a/xos/tosca/resources/accessagent.py b/xos/onboard/volt/tosca/resources/accessagent.py
similarity index 96%
rename from xos/tosca/resources/accessagent.py
rename to xos/onboard/volt/tosca/resources/accessagent.py
index 368ce55..e40a1cb 100644
--- a/xos/tosca/resources/accessagent.py
+++ b/xos/onboard/volt/tosca/resources/accessagent.py
@@ -5,7 +5,7 @@
 sys.path.append("/opt/tosca")
 from translator.toscalib.tosca_template import ToscaTemplate
 
-from services.cord.models import AccessAgent, VOLTDevice, VOLTService, AgentPortMapping
+from services.volt.models import AccessAgent, VOLTDevice, VOLTService, AgentPortMapping
 from xosresource import XOSResource
 
 class XOSAccessAgent(XOSResource):
diff --git a/xos/tosca/resources/accessdevice.py b/xos/onboard/volt/tosca/resources/accessdevice.py
similarity index 95%
rename from xos/tosca/resources/accessdevice.py
rename to xos/onboard/volt/tosca/resources/accessdevice.py
index 94deb86..f31b37a 100644
--- a/xos/tosca/resources/accessdevice.py
+++ b/xos/onboard/volt/tosca/resources/accessdevice.py
@@ -5,7 +5,7 @@
 sys.path.append("/opt/tosca")
 from translator.toscalib.tosca_template import ToscaTemplate
 
-from services.cord.models import AccessDevice, VOLTDevice
+from services.volt.models import AccessDevice, VOLTDevice
 from xosresource import XOSResource
 
 class XOSAccessDevice(XOSResource):
diff --git a/xos/tosca/resources/voltdevice.py b/xos/onboard/volt/tosca/resources/voltdevice.py
similarity index 96%
rename from xos/tosca/resources/voltdevice.py
rename to xos/onboard/volt/tosca/resources/voltdevice.py
index f1c6830..9665b85 100644
--- a/xos/tosca/resources/voltdevice.py
+++ b/xos/onboard/volt/tosca/resources/voltdevice.py
@@ -5,7 +5,7 @@
 sys.path.append("/opt/tosca")
 from translator.toscalib.tosca_template import ToscaTemplate
 
-from services.cord.models import VOLTDevice, VOLTService, AccessDevice, AccessAgent
+from services.volt.models import VOLTDevice, VOLTService, AccessDevice, AccessAgent
 from xosresource import XOSResource
 
 class XOSVOLTDevice(XOSResource):
diff --git a/xos/tosca/resources/voltservice.py b/xos/onboard/volt/tosca/resources/voltservice.py
similarity index 89%
rename from xos/tosca/resources/voltservice.py
rename to xos/onboard/volt/tosca/resources/voltservice.py
index 57cf846..9df4259 100644
--- a/xos/tosca/resources/voltservice.py
+++ b/xos/onboard/volt/tosca/resources/voltservice.py
@@ -5,7 +5,7 @@
 sys.path.append("/opt/tosca")
 from translator.toscalib.tosca_template import ToscaTemplate
 
-from services.cord.models import VOLTService
+from services.volt.models import VOLTService
 
 from service import XOSService
 
diff --git a/xos/onboard/volt/volt-onboard.yaml b/xos/onboard/volt/volt-onboard.yaml
new file mode 100644
index 0000000..e91ea93
--- /dev/null
+++ b/xos/onboard/volt/volt-onboard.yaml
@@ -0,0 +1,24 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Onboard the exampleservice
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+    servicecontroller#volt:
+      type: tosca.nodes.ServiceController
+      properties:
+          base_url: file:///opt/xos/onboard/volt/
+          # The following will concatenate with base_url automatically, if
+          # base_url is non-null.
+          models: models.py
+          admin: admin.py
+          admin_template: templates/voltadmin.html
+          #synchronizer: synchronizer/manifest
+          tosca_resource: tosca/resources/voltdevice.py, tosca/resources/voltservice.py, tosca/resources/CORDSubscriber.py, tosca/resources/CORDUser.py, tosca/resources/VOLTTenant.py, tosca/resources/accessagent.py, tosca/resources/accessdevice.py
+          rest_tenant: subdirectory:cord api/tenant/cord/volt.py, subdirectory:cord api/tenant/cord/subscriber.py
+          private_key: file:///opt/xos/key_import/volt_rsa
+          public_key: file:///opt/xos/key_import/volt_rsa.pub
+
diff --git a/xos/onboard/vsg/admin.py b/xos/onboard/vsg/admin.py
new file mode 100644
index 0000000..92fa51d
--- /dev/null
+++ b/xos/onboard/vsg/admin.py
@@ -0,0 +1,150 @@
+from django.contrib import admin
+
+from services.vsg.models import *
+from django import forms
+from django.utils.safestring import mark_safe
+from django.contrib.auth.admin import UserAdmin
+from django.contrib.admin.widgets import FilteredSelectMultiple
+from django.contrib.auth.forms import ReadOnlyPasswordHashField
+from django.contrib.auth.signals import user_logged_in
+from django.utils import timezone
+from django.contrib.contenttypes import generic
+from suit.widgets import LinkedSelect
+from core.admin import ServiceAppAdmin,SliceInline,ServiceAttrAsTabInline, ReadOnlyAwareAdmin, XOSTabularInline, ServicePrivilegeInline, TenantRootTenantInline, TenantRootPrivilegeInline
+from core.middleware import get_request
+
+from functools import update_wrapper
+from django.contrib.admin.views.main import ChangeList
+from django.core.urlresolvers import reverse
+from django.contrib.admin.utils import quote
+
+#-----------------------------------------------------------------------------
+# vSG
+#-----------------------------------------------------------------------------
+
+class VSGServiceForm(forms.ModelForm):
+    bbs_api_hostname = forms.CharField(required=False)
+    bbs_api_port = forms.IntegerField(required=False)
+    bbs_server = forms.CharField(required=False)
+    backend_network_label = forms.CharField(required=False)
+    bbs_slice = forms.ModelChoiceField(queryset=Slice.objects.all(), required=False)
+    dns_servers = forms.CharField(required=False)
+    url_filter_kind = forms.ChoiceField(choices=VSGService.URL_FILTER_KIND_CHOICES, required=False)
+    node_label = forms.CharField(required=False)
+
+    def __init__(self,*args,**kwargs):
+        super (VSGServiceForm,self ).__init__(*args,**kwargs)
+        if self.instance:
+            self.fields['bbs_api_hostname'].initial = self.instance.bbs_api_hostname
+            self.fields['bbs_api_port'].initial = self.instance.bbs_api_port
+            self.fields['bbs_server'].initial = self.instance.bbs_server
+            self.fields['backend_network_label'].initial = self.instance.backend_network_label
+            self.fields['bbs_slice'].initial = self.instance.bbs_slice
+            self.fields['dns_servers'].initial = self.instance.dns_servers
+            self.fields['url_filter_kind']. initial = self.instance.url_filter_kind
+            self.fields['node_label'].initial = self.instance.node_label
+
+    def save(self, commit=True):
+        self.instance.bbs_api_hostname = self.cleaned_data.get("bbs_api_hostname")
+        self.instance.bbs_api_port = self.cleaned_data.get("bbs_api_port")
+        self.instance.bbs_server = self.cleaned_data.get("bbs_server")
+        self.instance.backend_network_label = self.cleaned_data.get("backend_network_label")
+        self.instance.bbs_slice = self.cleaned_data.get("bbs_slice")
+        self.instance.dns_servers = self.cleaned_data.get("dns_servers")
+        self.instance.url_filter_kind = self.cleaned_data.get("url_filter_kind")
+        self.instance.node_label = self.cleaned_data.get("node_label")
+        return super(VSGServiceForm, self).save(commit=commit)
+
+    class Meta:
+        model = VSGService
+
+class VSGServiceAdmin(ReadOnlyAwareAdmin):
+    model = VSGService
+    verbose_name = "vSG Service"
+    verbose_name_plural = "vSG Service"
+    list_display = ("backend_status_icon", "name", "enabled")
+    list_display_links = ('backend_status_icon', 'name', )
+    fieldsets = [(None,             {'fields': ['backend_status_text', 'name','enabled','versionNumber', 'description', "view_url", "icon_url", "service_specific_attribute", "node_label"],
+                                     'classes':['suit-tab suit-tab-general']}),
+                 ("backend config", {'fields': [ "backend_network_label", "url_filter_kind", "bbs_api_hostname", "bbs_api_port", "bbs_server", "bbs_slice"],
+                                     'classes':['suit-tab suit-tab-backend']}),
+                 ("vSG config", {'fields': ["dns_servers"],
+                                     'classes':['suit-tab suit-tab-vsg']}) ]
+    readonly_fields = ('backend_status_text', "service_specific_attribute")
+    inlines = [SliceInline,ServiceAttrAsTabInline,ServicePrivilegeInline]
+    form = VSGServiceForm
+
+    extracontext_registered_admins = True
+
+    user_readonly_fields = ["name", "enabled", "versionNumber", "description"]
+
+    suit_form_tabs =(('general', 'Service Details'),
+        ('backend', 'Backend Config'),
+        ('vsg', 'vSG Config'),
+        ('administration', 'Administration'),
+        #('tools', 'Tools'),
+        ('slices','Slices'),
+        ('serviceattrs','Additional Attributes'),
+        ('serviceprivileges','Privileges') ,
+    )
+
+    suit_form_includes = (('vcpeadmin.html', 'top', 'administration'),
+                           ) #('hpctools.html', 'top', 'tools') )
+
+    def queryset(self, request):
+        return VSGService.get_service_objects_by_user(request.user)
+
+class VSGTenantForm(forms.ModelForm):
+    bbs_account = forms.CharField(required=False)
+    creator = forms.ModelChoiceField(queryset=User.objects.all())
+    instance = forms.ModelChoiceField(queryset=Instance.objects.all(),required=False)
+    last_ansible_hash = forms.CharField(required=False)
+    wan_container_ip = forms.CharField(required=False)
+    wan_container_mac = forms.CharField(required=False)
+
+    def __init__(self,*args,**kwargs):
+        super (VSGTenantForm,self ).__init__(*args,**kwargs)
+        self.fields['kind'].widget.attrs['readonly'] = True
+        self.fields['provider_service'].queryset = VSGService.get_service_objects().all()
+        if self.instance:
+            # fields for the attributes
+            self.fields['bbs_account'].initial = self.instance.bbs_account
+            self.fields['creator'].initial = self.instance.creator
+            self.fields['instance'].initial = self.instance.instance
+            self.fields['last_ansible_hash'].initial = self.instance.last_ansible_hash
+            self.fields['wan_container_ip'].initial = self.instance.wan_container_ip
+            self.fields['wan_container_mac'].initial = self.instance.wan_container_mac
+        if (not self.instance) or (not self.instance.pk):
+            # default fields for an 'add' form
+            self.fields['kind'].initial = VCPE_KIND
+            self.fields['creator'].initial = get_request().user
+            if VSGService.get_service_objects().exists():
+               self.fields["provider_service"].initial = VSGService.get_service_objects().all()[0]
+
+    def save(self, commit=True):
+        self.instance.creator = self.cleaned_data.get("creator")
+        self.instance.instance = self.cleaned_data.get("instance")
+        self.instance.last_ansible_hash = self.cleaned_data.get("last_ansible_hash")
+        return super(VSGTenantForm, self).save(commit=commit)
+
+    class Meta:
+        model = VSGTenant
+
+class VSGTenantAdmin(ReadOnlyAwareAdmin):
+    list_display = ('backend_status_icon', 'id', 'subscriber_tenant' )
+    list_display_links = ('backend_status_icon', 'id')
+    fieldsets = [ (None, {'fields': ['backend_status_text', 'kind', 'provider_service', 'subscriber_tenant', 'service_specific_id', # 'service_specific_attribute',
+                                     'wan_container_ip', 'wan_container_mac', 'bbs_account', 'creator', 'instance', 'last_ansible_hash'],
+                          'classes':['suit-tab suit-tab-general']})]
+    readonly_fields = ('backend_status_text', 'service_specific_attribute', 'bbs_account', 'wan_container_ip', 'wan_container_mac')
+    form = VSGTenantForm
+
+    suit_form_tabs = (('general','Details'),)
+
+    def queryset(self, request):
+        return VSGTenant.get_tenant_objects_by_user(request.user)
+
+
+admin.site.register(VSGService, VSGServiceAdmin)
+admin.site.register(VSGTenant, VSGTenantAdmin)
+
diff --git a/xos/api/service/vsg/vsgservice.py b/xos/onboard/vsg/api/service/vsg/vsgservice.py
similarity index 98%
rename from xos/api/service/vsg/vsgservice.py
rename to xos/onboard/vsg/api/service/vsg/vsgservice.py
index 9ab4756..a04fb3e 100644
--- a/xos/api/service/vsg/vsgservice.py
+++ b/xos/onboard/vsg/api/service/vsg/vsgservice.py
@@ -10,7 +10,7 @@
 from core.models import *
 from django.forms import widgets
 from django.conf.urls import patterns, url
-from services.cord.models import VSGService
+from services.vsg.models import VSGService
 from api.xosapi_helpers import PlusModelSerializer, XOSViewSet, ReadOnlyField
 from django.shortcuts import get_object_or_404
 from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
diff --git a/xos/api/tenant/cord/vsg.py b/xos/onboard/vsg/api/tenant/cord/vsg.py
similarity index 95%
rename from xos/api/tenant/cord/vsg.py
rename to xos/onboard/vsg/api/tenant/cord/vsg.py
index 6807e98..c6a4247 100644
--- a/xos/api/tenant/cord/vsg.py
+++ b/xos/onboard/vsg/api/tenant/cord/vsg.py
@@ -6,7 +6,7 @@
 from rest_framework import status
 from core.models import *
 from django.forms import widgets
-from services.cord.models import VSGTenant, VSGService, CordSubscriberRoot
+from services.vsg.models import VSGTenant, VSGService
 from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
 from api.xosapi_helpers import PlusModelSerializer, XOSViewSet, ReadOnlyField
 
diff --git a/xos/onboard/vsg/models.py b/xos/onboard/vsg/models.py
new file mode 100644
index 0000000..ad25c98
--- /dev/null
+++ b/xos/onboard/vsg/models.py
@@ -0,0 +1,448 @@
+from django.db import models
+from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, Subscriber, NetworkParameter, NetworkParameterType, Port, AddressPool, User
+from core.models.plcorebase import StrippedCharField
+import os
+from django.db import models, transaction
+from django.forms.models import model_to_dict
+from django.db.models import Q
+from operator import itemgetter, attrgetter, methodcaller
+from core.models import Tag
+from core.models.service import LeastLoadedNodeScheduler
+from services.vrouter.models import VRouterService, VRouterTenant
+import traceback
+from xos.exceptions import *
+from xos.config import Config
+
+class ConfigurationError(Exception):
+    pass
+
+VCPE_KIND = "vCPE"
+CORD_SUBSCRIBER_KIND = "CordSubscriberRoot"
+
+CORD_USE_VTN = getattr(Config(), "networking_use_vtn", False)
+
+# -------------------------------------------
+# VCPE
+# -------------------------------------------
+
+class VSGService(Service):
+    KIND = VCPE_KIND
+
+    URL_FILTER_KIND_CHOICES = ( (None, "None"), ("safebrowsing", "Safe Browsing"), ("answerx", "AnswerX") )
+
+    simple_attributes = ( ("bbs_api_hostname", None),
+                          ("bbs_api_port", None),
+                          ("bbs_server", None),
+                          ("backend_network_label", "hpc_client"),
+                          ("dns_servers", "8.8.8.8"),
+                          ("url_filter_kind", None),
+                          ("node_label", None) )
+
+    def __init__(self, *args, **kwargs):
+        super(VSGService, self).__init__(*args, **kwargs)
+
+    class Meta:
+        app_label = "vsg"
+        verbose_name = "vSG Service"
+        proxy = True
+
+    def allocate_bbs_account(self):
+        vcpes = VSGTenant.get_tenant_objects().all()
+        bbs_accounts = [vcpe.bbs_account for vcpe in vcpes]
+
+        # There's a bit of a race here; some other user could be trying to
+        # allocate a bbs_account at the same time we are.
+
+        for i in range(2,21):
+             account_name = "bbs%02d@onlab.us" % i
+             if (account_name not in bbs_accounts):
+                 return account_name
+
+        raise XOSConfigurationError("We've run out of available broadbandshield accounts. Delete some vcpe and try again.")
+
+    @property
+    def bbs_slice(self):
+        bbs_slice_id=self.get_attribute("bbs_slice_id")
+        if not bbs_slice_id:
+            return None
+        bbs_slices=Slice.objects.filter(id=bbs_slice_id)
+        if not bbs_slices:
+            return None
+        return bbs_slices[0]
+
+    @bbs_slice.setter
+    def bbs_slice(self, value):
+        if value:
+            value = value.id
+        self.set_attribute("bbs_slice_id", value)
+
+VSGService.setup_simple_attributes()
+
+class VSGTenant(TenantWithContainer):
+    class Meta:
+        proxy = True
+
+    KIND = VCPE_KIND
+
+    sync_attributes = ("wan_container_ip", "wan_container_mac", "wan_container_netbits",
+                       "wan_container_gateway_ip", "wan_container_gateway_mac",
+                       "wan_vm_ip", "wan_vm_mac")
+
+    default_attributes = {"instance_id": None,
+                          "container_id": None,
+                          "users": [],
+                          "bbs_account": None,
+                          "last_ansible_hash": None,
+                          "wan_container_ip": None}
+
+    def __init__(self, *args, **kwargs):
+        super(VSGTenant, self).__init__(*args, **kwargs)
+        self.cached_vrouter=None
+
+    @property
+    def vbng(self):
+        # not supported
+        return None
+
+    @vbng.setter
+    def vbng(self, value):
+        raise XOSConfigurationError("vCPE.vBNG cannot be set this way -- create a new vBNG object and set it's subscriber_tenant instead")
+
+    @property
+    def vrouter(self):
+        vrouter = self.get_newest_subscribed_tenant(VRouterTenant)
+        if not vrouter:
+            return None
+
+        # always return the same object when possible
+        if (self.cached_vrouter) and (self.cached_vrouter.id == vrouter.id):
+            return self.cached_vrouter
+
+        vrouter.caller = self.creator
+        self.cached_vrouter = vrouter
+        return vrouter
+
+    @vrouter.setter
+    def vrouter(self, value):
+        raise XOSConfigurationError("vCPE.vRouter cannot be set this way -- create a new vRuter object and set its subscriber_tenant instead")
+
+    @property
+    def volt(self):
+        from services.volt.models import VOLTTenant
+        if not self.subscriber_tenant:
+            return None
+        volts = VOLTTenant.objects.filter(id=self.subscriber_tenant.id)
+        if not volts:
+            return None
+        return volts[0]
+
+    @property
+    def bbs_account(self):
+        return self.get_attribute("bbs_account", self.default_attributes["bbs_account"])
+
+    @bbs_account.setter
+    def bbs_account(self, value):
+        return self.set_attribute("bbs_account", value)
+
+    @property
+    def last_ansible_hash(self):
+        return self.get_attribute("last_ansible_hash", self.default_attributes["last_ansible_hash"])
+
+    @last_ansible_hash.setter
+    def last_ansible_hash(self, value):
+        return self.set_attribute("last_ansible_hash", value)
+
+    @property
+    def ssh_command(self):
+        if self.instance:
+            return self.instance.get_ssh_command()
+        else:
+            return "no-instance"
+
+    @ssh_command.setter
+    def ssh_command(self, value):
+        pass
+
+    def get_vrouter_field(self, name, default=None):
+        if self.vrouter:
+            return getattr(self.vrouter, name, default)
+        else:
+            return default
+
+    @property
+    def wan_container_ip(self):
+        return self.get_vrouter_field("public_ip", None)
+
+    @property
+    def wan_container_mac(self):
+        return self.get_vrouter_field("public_mac", None)
+
+    @property
+    def wan_container_netbits(self):
+        return self.get_vrouter_field("netbits", None)
+
+    @property
+    def wan_container_gateway_ip(self):
+        return self.get_vrouter_field("gateway_ip", None)
+
+    @property
+    def wan_container_gateway_mac(self):
+        return self.get_vrouter_field("gateway_mac", None)
+
+    @property
+    def wan_vm_ip(self):
+        tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant")
+        if tags:
+            tenant = VRouterTenant.objects.get(id=tags[0].value)
+            return tenant.public_ip
+        else:
+            raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
+
+    @property
+    def wan_vm_mac(self):
+        tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant")
+        if tags:
+            tenant = VRouterTenant.objects.get(id=tags[0].value)
+            return tenant.public_mac
+        else:
+            raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
+
+    @property
+    def is_synced(self):
+        return (self.enacted is not None) and (self.enacted >= self.updated)
+
+    @is_synced.setter
+    def is_synced(self, value):
+        pass
+
+    def get_vrouter_service(self):
+        vrouterServices = VRouterService.get_service_objects().all()
+        if not vrouterServices:
+            raise XOSConfigurationError("No VROUTER Services available")
+        return vrouterServices[0]
+
+    def manage_vrouter(self):
+        # Each vCPE object owns exactly one vRouterTenant object
+
+        if self.deleted:
+            return
+
+        if self.vrouter is None:
+            vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_vsg", subscriber_tenant = self)
+            vrouter.caller = self.creator
+            vrouter.save()
+
+    def cleanup_vrouter(self):
+        if self.vrouter:
+            # print "XXX cleanup vrouter", self.vrouter
+            self.vrouter.delete()
+
+    def cleanup_orphans(self):
+        # ensure vCPE only has one vRouter
+        cur_vrouter = self.vrouter
+        for vrouter in list(self.get_subscribed_tenants(VRouterTenant)):
+            if (not cur_vrouter) or (vrouter.id != cur_vrouter.id):
+                # print "XXX clean up orphaned vrouter", vrouter
+                vrouter.delete()
+
+        if self.orig_instance_id and (self.orig_instance_id != self.get_attribute("instance_id")):
+            instances=Instance.objects.filter(id=self.orig_instance_id)
+            if instances:
+                # print "XXX clean up orphaned instance", instances[0]
+                instances[0].delete()
+
+    def get_slice(self):
+        if not self.provider_service.slices.count():
+            print self, "dio porco"
+            raise XOSConfigurationError("The service has no slices")
+        slice = self.provider_service.slices.all()[0]
+        return slice
+
+    def get_vsg_service(self):
+        return VSGService.get_service_objects().get(id=self.provider_service.id)
+
+    def find_instance_for_s_tag(self, s_tag):
+        #s_tags = STagBlock.objects.find(s_s_tag)
+        #if s_tags:
+        #    return s_tags[0].instance
+
+        tags = Tag.objects.filter(name="s_tag", value=s_tag)
+        if tags:
+            return tags[0].content_object
+
+        return None
+
+    def find_or_make_instance_for_s_tag(self, s_tag):
+        instance = self.find_instance_for_s_tag(self.volt.s_tag)
+        if instance:
+            return instance
+
+        flavors = Flavor.objects.filter(name="m1.small")
+        if not flavors:
+            raise XOSConfigurationError("No m1.small flavor")
+
+        slice = self.provider_service.slices.all()[0]
+
+        if slice.default_isolation == "container_vm":
+            (node, parent) = ContainerVmScheduler(slice).pick()
+        else:
+            (node, parent) = LeastLoadedNodeScheduler(slice, label=self.get_vsg_service().node_label).pick()
+
+        instance = Instance(slice = slice,
+                        node = node,
+                        image = self.image,
+                        creator = self.creator,
+                        deployment = node.site_deployment.deployment,
+                        flavor = flavors[0],
+                        isolation = slice.default_isolation,
+                        parent = parent)
+
+        self.save_instance(instance)
+
+        return instance
+
+    def manage_container(self):
+        from core.models import Instance, Flavor
+
+        if self.deleted:
+            return
+
+        # For container or container_vm isolation, use what TenantWithCotnainer
+        # provides us
+        slice = self.get_slice()
+        if slice.default_isolation in ["container_vm", "container"]:
+            super(VSGTenant,self).manage_container()
+            return
+
+        if not self.volt:
+            raise XOSConfigurationError("This vCPE container has no volt")
+
+        if self.instance:
+            # We're good.
+            return
+
+        instance = self.find_or_make_instance_for_s_tag(self.volt.s_tag)
+        self.instance = instance
+        super(TenantWithContainer, self).save()
+
+    def cleanup_container(self):
+        if self.get_slice().default_isolation in ["container_vm", "container"]:
+            super(VSGTenant,self).cleanup_container()
+
+        # To-do: cleanup unused instances
+        pass
+
+    def manage_bbs_account(self):
+        if self.deleted:
+            return
+
+        if self.volt and self.volt.subscriber and self.volt.subscriber.url_filter_enable:
+            if not self.bbs_account:
+                # make sure we use the proxied VSGService object, not the generic Service object
+                vcpe_service = VSGService.objects.get(id=self.provider_service.id)
+                self.bbs_account = vcpe_service.allocate_bbs_account()
+                super(VSGTenant, self).save()
+        else:
+            if self.bbs_account:
+                self.bbs_account = None
+                super(VSGTenant, self).save()
+
+    def find_or_make_port(self, instance, network, **kwargs):
+        port = Port.objects.filter(instance=instance, network=network)
+        if port:
+            port = port[0]
+        else:
+            port = Port(instance=instance, network=network, **kwargs)
+            port.save()
+        return port
+
+    def get_lan_network(self, instance):
+        slice = self.provider_service.slices.all()[0]
+        if CORD_USE_VTN:
+            # there should only be one network private network, and its template should not be the management template
+            lan_networks = [x for x in slice.networks.all() if x.template.visibility=="private" and (not "management" in x.template.name)]
+            if len(lan_networks)>1:
+                raise XOSProgrammingError("The vSG slice should only have one non-management private network")
+        else:
+            lan_networks = [x for x in slice.networks.all() if "lan" in x.name]
+        if not lan_networks:
+            raise XOSProgrammingError("No lan_network")
+        return lan_networks[0]
+
+    def save_instance(self, instance):
+        with transaction.atomic():
+            instance.volumes = "/etc/dnsmasq.d,/etc/ufw"
+            super(VSGTenant, self).save_instance(instance)
+
+            if instance.isolation in ["container", "container_vm"]:
+                lan_network = self.get_lan_network(instance)
+                port = self.find_or_make_port(instance, lan_network, ip="192.168.0.1", port_id="unmanaged")
+                port.set_parameter("c_tag", self.volt.c_tag)
+                port.set_parameter("s_tag", self.volt.s_tag)
+                port.set_parameter("device", "eth1")
+                port.set_parameter("bridge", "br-lan")
+
+                wan_networks = [x for x in instance.slice.networks.all() if "wan" in x.name]
+                if not wan_networks:
+                    raise XOSProgrammingError("No wan_network")
+                port = self.find_or_make_port(instance, wan_networks[0])
+                port.set_parameter("next_hop", value="10.0.1.253")   # FIX ME
+                port.set_parameter("device", "eth0")
+
+            if instance.isolation in ["vm"]:
+                lan_network = self.get_lan_network(instance)
+                port = self.find_or_make_port(instance, lan_network)
+                port.set_parameter("c_tag", self.volt.c_tag)
+                port.set_parameter("s_tag", self.volt.s_tag)
+                port.set_parameter("neutron_port_name", "stag-%s" % self.volt.s_tag)
+                port.save()
+
+            # tag the instance with the s-tag, so we can easily find the
+            # instance later
+            if self.volt and self.volt.s_tag:
+                tags = Tag.objects.filter(name="s_tag", value=self.volt.s_tag)
+                if not tags:
+                    tag = Tag(service=self.provider_service, content_object=instance, name="s_tag", value=self.volt.s_tag)
+                    tag.save()
+
+            # VTN-CORD needs a WAN address for the VM, so that the VM can
+            # be configured.
+            if CORD_USE_VTN:
+                tags = Tag.select_by_content_object(instance).filter(name="vm_vrouter_tenant")
+                if not tags:
+                    vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_vsg", subscriber_service = self.provider_service)
+                    vrouter.set_attribute("tenant_for_instance_id", instance.id)
+                    vrouter.save()
+                    tag = Tag(service=self.provider_service, content_object=instance, name="vm_vrouter_tenant", value="%d" % vrouter.id)
+                    tag.save()
+
+    def save(self, *args, **kwargs):
+        if not self.creator:
+            if not getattr(self, "caller", None):
+                # caller must be set when creating a vCPE since it creates a slice
+                raise XOSProgrammingError("VSGTenant's self.caller was not set")
+            self.creator = self.caller
+            if not self.creator:
+                raise XOSProgrammingError("VSGTenant's self.creator was not set")
+
+        super(VSGTenant, self).save(*args, **kwargs)
+        model_policy_vcpe(self.pk)
+
+    def delete(self, *args, **kwargs):
+        self.cleanup_vrouter()
+        self.cleanup_container()
+        super(VSGTenant, self).delete(*args, **kwargs)
+
+def model_policy_vcpe(pk):
+    # TODO: this should be made in to a real model_policy
+    with transaction.atomic():
+        vcpe = VSGTenant.objects.select_for_update().filter(pk=pk)
+        if not vcpe:
+            return
+        vcpe = vcpe[0]
+        vcpe.manage_container()
+        vcpe.manage_vrouter()
+        vcpe.manage_bbs_account()
+        vcpe.cleanup_orphans()
+
+
diff --git a/xos/synchronizers/vcpe/broadbandshield.py b/xos/onboard/vsg/synchronizer/broadbandshield.py
similarity index 100%
rename from xos/synchronizers/vcpe/broadbandshield.py
rename to xos/onboard/vsg/synchronizer/broadbandshield.py
diff --git a/xos/synchronizers/vcpe/files/docker.list b/xos/onboard/vsg/synchronizer/files/docker.list
similarity index 100%
rename from xos/synchronizers/vcpe/files/docker.list
rename to xos/onboard/vsg/synchronizer/files/docker.list
diff --git a/xos/synchronizers/vcpe/files/etc/rc.local b/xos/onboard/vsg/synchronizer/files/etc/rc.local
similarity index 100%
rename from xos/synchronizers/vcpe/files/etc/rc.local
rename to xos/onboard/vsg/synchronizer/files/etc/rc.local
diff --git a/xos/synchronizers/vcpe/files/etc/service/message/run b/xos/onboard/vsg/synchronizer/files/etc/service/message/run
similarity index 100%
rename from xos/synchronizers/vcpe/files/etc/service/message/run
rename to xos/onboard/vsg/synchronizer/files/etc/service/message/run
diff --git a/xos/synchronizers/vcpe/files/etc/ufw/after.init b/xos/onboard/vsg/synchronizer/files/etc/ufw/after.init
similarity index 100%
rename from xos/synchronizers/vcpe/files/etc/ufw/after.init
rename to xos/onboard/vsg/synchronizer/files/etc/ufw/after.init
diff --git a/xos/synchronizers/vcpe/files/etc/ufw/after.rules b/xos/onboard/vsg/synchronizer/files/etc/ufw/after.rules
similarity index 100%
rename from xos/synchronizers/vcpe/files/etc/ufw/after.rules
rename to xos/onboard/vsg/synchronizer/files/etc/ufw/after.rules
diff --git a/xos/synchronizers/vcpe/files/etc/ufw/after6.rules b/xos/onboard/vsg/synchronizer/files/etc/ufw/after6.rules
similarity index 100%
rename from xos/synchronizers/vcpe/files/etc/ufw/after6.rules
rename to xos/onboard/vsg/synchronizer/files/etc/ufw/after6.rules
diff --git a/xos/synchronizers/vcpe/files/etc/ufw/applications.d/openssh-server b/xos/onboard/vsg/synchronizer/files/etc/ufw/applications.d/openssh-server
similarity index 100%
rename from xos/synchronizers/vcpe/files/etc/ufw/applications.d/openssh-server
rename to xos/onboard/vsg/synchronizer/files/etc/ufw/applications.d/openssh-server
diff --git a/xos/synchronizers/vcpe/files/etc/ufw/before.init b/xos/onboard/vsg/synchronizer/files/etc/ufw/before.init
similarity index 100%
rename from xos/synchronizers/vcpe/files/etc/ufw/before.init
rename to xos/onboard/vsg/synchronizer/files/etc/ufw/before.init
diff --git a/xos/synchronizers/vcpe/files/etc/ufw/before6.rules b/xos/onboard/vsg/synchronizer/files/etc/ufw/before6.rules
similarity index 100%
rename from xos/synchronizers/vcpe/files/etc/ufw/before6.rules
rename to xos/onboard/vsg/synchronizer/files/etc/ufw/before6.rules
diff --git a/xos/synchronizers/vcpe/files/etc/ufw/sysctl.conf b/xos/onboard/vsg/synchronizer/files/etc/ufw/sysctl.conf
similarity index 100%
rename from xos/synchronizers/vcpe/files/etc/ufw/sysctl.conf
rename to xos/onboard/vsg/synchronizer/files/etc/ufw/sysctl.conf
diff --git a/xos/synchronizers/vcpe/files/etc/ufw/ufw.conf b/xos/onboard/vsg/synchronizer/files/etc/ufw/ufw.conf
similarity index 100%
rename from xos/synchronizers/vcpe/files/etc/ufw/ufw.conf
rename to xos/onboard/vsg/synchronizer/files/etc/ufw/ufw.conf
diff --git a/xos/synchronizers/vcpe/files/vcpe.conf b/xos/onboard/vsg/synchronizer/files/vcpe.conf
similarity index 100%
rename from xos/synchronizers/vcpe/files/vcpe.conf
rename to xos/onboard/vsg/synchronizer/files/vcpe.conf
diff --git a/xos/synchronizers/vcpe/files/vcpe.dnsmasq b/xos/onboard/vsg/synchronizer/files/vcpe.dnsmasq
similarity index 100%
rename from xos/synchronizers/vcpe/files/vcpe.dnsmasq
rename to xos/onboard/vsg/synchronizer/files/vcpe.dnsmasq
diff --git a/xos/synchronizers/vcpe/files/vm-resolv.conf b/xos/onboard/vsg/synchronizer/files/vm-resolv.conf
similarity index 100%
rename from xos/synchronizers/vcpe/files/vm-resolv.conf
rename to xos/onboard/vsg/synchronizer/files/vm-resolv.conf
diff --git a/xos/onboard/vsg/synchronizer/manifest b/xos/onboard/vsg/synchronizer/manifest
new file mode 100644
index 0000000..d13ee05
--- /dev/null
+++ b/xos/onboard/vsg/synchronizer/manifest
@@ -0,0 +1,49 @@
+templates/bwlimit.sh.j2
+templates/vlan_sample.j2
+templates/before.rules.j2
+templates/start-vcpe.sh.j2
+templates/dnsmasq_safe_servers.j2
+templates/firewall_sample.j2
+templates/rc.local.j2
+templates/vcpe.conf.j2
+templates/message.html.j2
+templates/dnsmasq_servers.j2
+templates/start-vcpe-vtn.sh.j2
+manifest
+broadbandshield.py
+observer_ansible_test.py
+vcpe_synchronizer_config
+start-bbs.sh
+steps/sync_vcpetenant.py
+steps/sync_vcpetenant_new.yaml
+steps/sync_vcpetenant_vtn.yaml
+steps/sync_vcpetenant.yaml
+steps/test.yaml
+steps/ansible_test/README
+steps/ansible_test/test.yaml
+steps/ansible_test/xos.py
+steps/ansible_test/test.sh
+steps/ansible_test/inventory.txt
+start.sh
+files/vcpe.conf
+files/etc/service/message/run
+files/etc/rc.local
+files/etc/ufw/after6.rules
+files/etc/ufw/applications.d/openssh-server
+files/etc/ufw/sysctl.conf
+files/etc/ufw/ufw.conf
+files/etc/ufw/before6.rules
+files/etc/ufw/after.init
+files/etc/ufw/before.init
+files/etc/ufw/after.rules
+files/vm-resolv.conf
+files/docker.list
+files/vcpe.dnsmasq
+run-vtn.sh
+stop.sh
+vcpe-synchronizer.py
+model-deps
+supervisor/vcpe-observer.conf
+run.sh
+vtn_vcpe_synchronizer_config
+vcpe_stats_notifier.py
diff --git a/xos/synchronizers/vbng/model-deps b/xos/onboard/vsg/synchronizer/model-deps
similarity index 100%
rename from xos/synchronizers/vbng/model-deps
rename to xos/onboard/vsg/synchronizer/model-deps
diff --git a/xos/synchronizers/vcpe/observer_ansible_test.py b/xos/onboard/vsg/synchronizer/observer_ansible_test.py
similarity index 100%
rename from xos/synchronizers/vcpe/observer_ansible_test.py
rename to xos/onboard/vsg/synchronizer/observer_ansible_test.py
diff --git a/xos/synchronizers/vcpe/run-vtn.sh b/xos/onboard/vsg/synchronizer/run-vtn.sh
similarity index 100%
rename from xos/synchronizers/vcpe/run-vtn.sh
rename to xos/onboard/vsg/synchronizer/run-vtn.sh
diff --git a/xos/synchronizers/vcpe/run.sh b/xos/onboard/vsg/synchronizer/run.sh
similarity index 100%
rename from xos/synchronizers/vcpe/run.sh
rename to xos/onboard/vsg/synchronizer/run.sh
diff --git a/xos/synchronizers/vcpe/start-bbs.sh b/xos/onboard/vsg/synchronizer/start-bbs.sh
similarity index 100%
rename from xos/synchronizers/vcpe/start-bbs.sh
rename to xos/onboard/vsg/synchronizer/start-bbs.sh
diff --git a/xos/synchronizers/vcpe/start.sh b/xos/onboard/vsg/synchronizer/start.sh
similarity index 100%
rename from xos/synchronizers/vcpe/start.sh
rename to xos/onboard/vsg/synchronizer/start.sh
diff --git a/xos/synchronizers/vcpe/steps/ansible_test/README b/xos/onboard/vsg/synchronizer/steps/ansible_test/README
similarity index 100%
rename from xos/synchronizers/vcpe/steps/ansible_test/README
rename to xos/onboard/vsg/synchronizer/steps/ansible_test/README
diff --git a/xos/synchronizers/vcpe/steps/ansible_test/inventory.txt b/xos/onboard/vsg/synchronizer/steps/ansible_test/inventory.txt
similarity index 100%
rename from xos/synchronizers/vcpe/steps/ansible_test/inventory.txt
rename to xos/onboard/vsg/synchronizer/steps/ansible_test/inventory.txt
diff --git a/xos/synchronizers/vcpe/steps/ansible_test/test.sh b/xos/onboard/vsg/synchronizer/steps/ansible_test/test.sh
similarity index 100%
rename from xos/synchronizers/vcpe/steps/ansible_test/test.sh
rename to xos/onboard/vsg/synchronizer/steps/ansible_test/test.sh
diff --git a/xos/synchronizers/vcpe/steps/ansible_test/test.yaml b/xos/onboard/vsg/synchronizer/steps/ansible_test/test.yaml
similarity index 100%
rename from xos/synchronizers/vcpe/steps/ansible_test/test.yaml
rename to xos/onboard/vsg/synchronizer/steps/ansible_test/test.yaml
diff --git a/xos/synchronizers/vcpe/steps/ansible_test/xos.py b/xos/onboard/vsg/synchronizer/steps/ansible_test/xos.py
similarity index 100%
rename from xos/synchronizers/vcpe/steps/ansible_test/xos.py
rename to xos/onboard/vsg/synchronizer/steps/ansible_test/xos.py
diff --git a/xos/synchronizers/vcpe/steps/sync_vcpetenant.py b/xos/onboard/vsg/synchronizer/steps/sync_vcpetenant.py
similarity index 97%
rename from xos/synchronizers/vcpe/steps/sync_vcpetenant.py
rename to xos/onboard/vsg/synchronizer/steps/sync_vcpetenant.py
index d8bc525..0b777c7 100644
--- a/xos/synchronizers/vcpe/steps/sync_vcpetenant.py
+++ b/xos/onboard/vsg/synchronizer/steps/sync_vcpetenant.py
@@ -10,7 +10,7 @@
 from synchronizers.base.ansible import run_template_ssh
 from synchronizers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
 from core.models import Service, Slice, Tag
-from services.cord.models import VSGService, VSGTenant, VOLTTenant
+from services.vsg.models import VSGService, VSGTenant
 from services.hpc.models import HpcService, CDNPrefix
 from xos.logger import Logger, logging
 
@@ -31,7 +31,6 @@
     observes=VSGTenant
     requested_interval=0
     template_name = "sync_vcpetenant.yaml"
-    service_key_name = "/opt/xos/synchronizers/vcpe/vcpe_private_key"
 
     def __init__(self, *args, **kwargs):
         super(SyncVSGTenant, self).__init__(*args, **kwargs)
@@ -67,7 +66,7 @@
         dnsdemux_ip = None
         cdn_prefixes = []
 
-        cdn_config_fn = "/opt/xos/synchronizers/vcpe/cdn_config"
+        cdn_config_fn = "/opt/xos/synchronizers/vsg/cdn_config"
         if os.path.exists(cdn_config_fn):
             # manual CDN configuration
             #   the first line is the address of dnsredir
diff --git a/xos/synchronizers/vcpe/steps/sync_vcpetenant.yaml b/xos/onboard/vsg/synchronizer/steps/sync_vcpetenant.yaml
similarity index 83%
rename from xos/synchronizers/vcpe/steps/sync_vcpetenant.yaml
rename to xos/onboard/vsg/synchronizer/steps/sync_vcpetenant.yaml
index 9be0f98..880895e 100644
--- a/xos/synchronizers/vcpe/steps/sync_vcpetenant.yaml
+++ b/xos/onboard/vsg/synchronizer/steps/sync_vcpetenant.yaml
@@ -63,7 +63,7 @@
   tasks:
 {% if full_setup %}
   - name: Docker repository
-    copy: src=/opt/xos/synchronizers/vcpe/files/docker.list
+    copy: src=/opt/xos/synchronizers/vsg/files/docker.list
       dest=/etc/apt/sources.list.d/docker.list
 
   - name: Import the repository key
@@ -95,7 +95,7 @@
     shell: rm -f /etc/resolv.conf
 
   - name: Install resolv.conf
-    copy: src=/opt/xos/synchronizers/vcpe/files/vm-resolv.conf
+    copy: src=/opt/xos/synchronizers/vsg/files/vm-resolv.conf
       dest=/etc/resolv.conf
 
   - name: Verify if vcpe_stats_notifier ([] is to avoid capturing the shell process) cron job is already running
@@ -110,7 +110,7 @@
 #    when: cron_job_pids_count.stdout == "0"
 
   - name: Copy cron job to destination
-    copy: src=/opt/xos/synchronizers/vcpe/vcpe_stats_notifier.py
+    copy: src=/opt/xos/synchronizers/vsg/vcpe_stats_notifier.py
       dest=/usr/local/sbin/vcpe_stats_notifier.py
     when: cron_job_pids_count.stdout == "0"
 
@@ -126,10 +126,10 @@
 {% endif %}
 
   - name: vCPE upstart
-    template: src=/opt/xos/synchronizers/vcpe/templates/vcpe.conf.j2 dest=/etc/init/vcpe-{{ s_tags[0] }}-{{ c_tags[0] }}.conf
+    template: src=/opt/xos/synchronizers/vsg/templates/vcpe.conf.j2 dest=/etc/init/vcpe-{{ s_tags[0] }}-{{ c_tags[0] }}.conf
 
   - name: vCPE startup script
-    template: src=/opt/xos/synchronizers/vcpe/templates/start-vcpe.sh.j2 dest=/usr/local/sbin/start-vcpe-{{ s_tags[0] }}-{{ c_tags[0] }}.sh mode=0755
+    template: src=/opt/xos/synchronizers/vsg/templates/start-vcpe.sh.j2 dest=/usr/local/sbin/start-vcpe-{{ s_tags[0] }}-{{ c_tags[0] }}.sh mode=0755
     notify:
 #    - restart vcpe
      - stop vcpe
@@ -140,22 +140,22 @@
     file: path=/etc/vcpe-{{ s_tags[0] }}-{{ c_tags[0] }}/dnsmasq.d state=directory owner=root group=root
 
   - name: vCPE basic dnsmasq config
-    copy: src=/opt/xos/synchronizers/vcpe/files/vcpe.dnsmasq dest=/etc/vcpe-{{ s_tags[0] }}-{{ c_tags[0] }}/dnsmasq.d/vcpe.conf owner=root group=root
+    copy: src=/opt/xos/synchronizers/vsg/files/vcpe.dnsmasq dest=/etc/vcpe-{{ s_tags[0] }}-{{ c_tags[0] }}/dnsmasq.d/vcpe.conf owner=root group=root
     notify:
     - restart dnsmasq
 
   - name: dnsmasq config
-    template: src=/opt/xos/synchronizers/vcpe/templates/dnsmasq_servers.j2 dest=/etc/vcpe-{{ s_tags[0] }}-{{ c_tags[0] }}/dnsmasq.d/servers.conf owner=root group=root
+    template: src=/opt/xos/synchronizers/vsg/templates/dnsmasq_servers.j2 dest=/etc/vcpe-{{ s_tags[0] }}-{{ c_tags[0] }}/dnsmasq.d/servers.conf owner=root group=root
     notify:
     - restart dnsmasq
 
 # These are samples, not necessary for correct function of demo
 
 #  - name: networking info
-#    template: src=/opt/xos/synchronizers/vcpe/templates/vlan_sample.j2 dest=/etc/vlan_sample owner=root group=root
+#    template: src=/opt/xos/synchronizers/vsg/templates/vlan_sample.j2 dest=/etc/vlan_sample owner=root group=root
 
 #  - name: firewall info
-#    template: src=/opt/xos/synchronizers/vcpe/templates/firewall_sample.j2 dest=/etc/firewall_sample owner=root group=root
+#    template: src=/opt/xos/synchronizers/vsg/templates/firewall_sample.j2 dest=/etc/firewall_sample owner=root group=root
 
   - name: Make sure vCPE service is running
     service: name=vcpe-{{ s_tags[0] }}-{{ c_tags[0] }} state=started
diff --git a/xos/synchronizers/vcpe/steps/sync_vcpetenant_new.yaml b/xos/onboard/vsg/synchronizer/steps/sync_vcpetenant_new.yaml
similarity index 80%
rename from xos/synchronizers/vcpe/steps/sync_vcpetenant_new.yaml
rename to xos/onboard/vsg/synchronizer/steps/sync_vcpetenant_new.yaml
index 435b721..9c59280 100644
--- a/xos/synchronizers/vcpe/steps/sync_vcpetenant_new.yaml
+++ b/xos/onboard/vsg/synchronizer/steps/sync_vcpetenant_new.yaml
@@ -74,7 +74,7 @@
     when: cron_job_pids_count.stdout == "0"
 
   - name: Copy cron job to destination
-    copy: src=/opt/xos/synchronizers/vcpe/vcpe_stats_notifier.py
+    copy: src=/opt/xos/synchronizers/vsg/vcpe_stats_notifier.py
       dest=~/bin/vcpe_stats_notifier.py
     when: cron_job_pids_count.stdout == "0"
 
@@ -89,12 +89,12 @@
     when: cron_job_pids_count.stdout == "0"
 
   - name: vCPE basic dnsmasq config
-    copy: src=/opt/xos/synchronizers/vcpe/files/vcpe.dnsmasq dest=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/vcpe.conf owner=root group=root
+    copy: src=/opt/xos/synchronizers/vsg/files/vcpe.dnsmasq dest=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/vcpe.conf owner=root group=root
     notify:
     - restart dnsmasq
 
   - name: dnsmasq config
-    template: src=/opt/xos/synchronizers/vcpe/templates/dnsmasq_servers.j2 dest=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/servers.conf owner=root group=root
+    template: src=/opt/xos/synchronizers/vsg/templates/dnsmasq_servers.j2 dest=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/servers.conf owner=root group=root
     notify:
     - restart dnsmasq
 
@@ -102,22 +102,22 @@
     file: path=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/safe state=directory
 
   - name: dnsmasq "safe" config
-    template: src=/opt/xos/synchronizers/vcpe/templates/dnsmasq_safe_servers.j2 dest=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/safe/servers.conf owner=root group=root
+    template: src=/opt/xos/synchronizers/vsg/templates/dnsmasq_safe_servers.j2 dest=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/safe/servers.conf owner=root group=root
     notify:
     - restart dnsmasq
 
   - name: copy base ufw files
-    synchronize: src=/opt/xos/synchronizers/vcpe/files/etc/ufw/ dest=/var/container_volumes/{{ container_name }}/etc/ufw/
+    synchronize: src=/opt/xos/synchronizers/vsg/files/etc/ufw/ dest=/var/container_volumes/{{ container_name }}/etc/ufw/
     notify:
     - reload ufw
 
   - name: redirection rules for safe DNS
-    template: src=/opt/xos/synchronizers/vcpe/templates/before.rules.j2 dest=/var/container_volumes/{{ container_name }}/etc/ufw/before.rules owner=root group=root
+    template: src=/opt/xos/synchronizers/vsg/templates/before.rules.j2 dest=/var/container_volumes/{{ container_name }}/etc/ufw/before.rules owner=root group=root
     notify:
     - reload ufw
 
   - name: base ufw setup uses /etc/rc.local
-    copy: src=/opt/xos/synchronizers/vcpe/files/etc/rc.local dest=/var/container_volumes/{{ container_name }}/etc/ owner=root group=root
+    copy: src=/opt/xos/synchronizers/vsg/files/etc/rc.local dest=/var/container_volumes/{{ container_name }}/etc/ owner=root group=root
     notify:
     - copy in /etc/rc.local
 
diff --git a/xos/synchronizers/vcpe/steps/sync_vcpetenant_vtn.yaml b/xos/onboard/vsg/synchronizer/steps/sync_vcpetenant_vtn.yaml
similarity index 81%
rename from xos/synchronizers/vcpe/steps/sync_vcpetenant_vtn.yaml
rename to xos/onboard/vsg/synchronizer/steps/sync_vcpetenant_vtn.yaml
index b24d15a..0226354 100644
--- a/xos/synchronizers/vcpe/steps/sync_vcpetenant_vtn.yaml
+++ b/xos/onboard/vsg/synchronizer/steps/sync_vcpetenant_vtn.yaml
@@ -128,7 +128,7 @@
 #    when: cron_job_pids_count.stdout == "0"
 
 #  - name: Copy cron job to destination
-#    copy: src=/opt/xos/synchronizers/vcpe/vcpe_stats_notifier.py
+#    copy: src=/opt/xos/synchronizers/vsg/vcpe_stats_notifier.py
 #      dest=/usr/local/sbin/vcpe_stats_notifier.py
 #    when: cron_job_pids_count.stdout == "0"
 
@@ -144,10 +144,10 @@
 {% endif %}
 
   - name: vCPE upstart
-    template: src=/opt/xos/synchronizers/vcpe/templates/vcpe.conf.j2 dest=/etc/init/{{ container_name }}.conf
+    template: src=/opt/xos/synchronizers/vsg/templates/vcpe.conf.j2 dest=/etc/init/{{ container_name }}.conf
 
   - name: vCPE startup script
-    template: src=/opt/xos/synchronizers/vcpe/templates/start-vcpe-vtn.sh.j2 dest=/usr/local/sbin/start-{{ container_name }}.sh mode=0755
+    template: src=/opt/xos/synchronizers/vsg/templates/start-vcpe-vtn.sh.j2 dest=/usr/local/sbin/start-{{ container_name }}.sh mode=0755
     notify:
 #    - restart vcpe
      - stop vcpe
@@ -158,17 +158,17 @@
     file: path=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/safe state=directory owner=root group=root
 
   - name: vCPE basic dnsmasq config
-    copy: src=/opt/xos/synchronizers/vcpe/files/vcpe.dnsmasq dest=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/vcpe.conf owner=root group=root
+    copy: src=/opt/xos/synchronizers/vsg/files/vcpe.dnsmasq dest=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/vcpe.conf owner=root group=root
     notify:
     - restart dnsmasq
 
   - name: dnsmasq config
-    template: src=/opt/xos/synchronizers/vcpe/templates/dnsmasq_servers.j2 dest=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/servers.conf owner=root group=root
+    template: src=/opt/xos/synchronizers/vsg/templates/dnsmasq_servers.j2 dest=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/servers.conf owner=root group=root
     notify:
     - restart dnsmasq
 
   - name: dnsmasq "safe" config
-    template: src=/opt/xos/synchronizers/vcpe/templates/dnsmasq_safe_servers.j2 dest=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/safe/servers.conf owner=root group=root
+    template: src=/opt/xos/synchronizers/vsg/templates/dnsmasq_safe_servers.j2 dest=/var/container_volumes/{{ container_name }}/etc/dnsmasq.d/safe/servers.conf owner=root group=root
     notify:
     - restart dnsmasq
 
@@ -176,12 +176,12 @@
     file: path=/var/container_volumes/{{ container_name }}/mount state=directory owner=root group=root
 
   - name: redirection rules for safe DNS
-    template: src=/opt/xos/synchronizers/vcpe/templates/before.rules.j2 dest=/var/container_volumes/{{ container_name }}/mount/before.rules owner=root group=root mode=0644
+    template: src=/opt/xos/synchronizers/vsg/templates/before.rules.j2 dest=/var/container_volumes/{{ container_name }}/mount/before.rules owner=root group=root mode=0644
     notify:
     - reload ufw
 
   - name: base ufw setup uses /etc/rc.local
-    template: src=/opt/xos/synchronizers/vcpe/templates/rc.local.j2 dest=/var/container_volumes/{{ container_name }}/mount/rc.local owner=root group=root mode=0755
+    template: src=/opt/xos/synchronizers/vsg/templates/rc.local.j2 dest=/var/container_volumes/{{ container_name }}/mount/rc.local owner=root group=root mode=0755
     notify:
     - rerun /etc/rc.local
 
@@ -189,7 +189,7 @@
     file: path=/var/container_volumes/{{ container_name }}/usr/local/sbin state=directory
 
   - name: bandwidth limit script
-    template: src=/opt/xos/synchronizers/vcpe/templates/bwlimit.sh.j2 dest=/var/container_volumes/{{ container_name }}/usr/local/sbin/bwlimit.sh owner=root group=root mode=0755
+    template: src=/opt/xos/synchronizers/vsg/templates/bwlimit.sh.j2 dest=/var/container_volumes/{{ container_name }}/usr/local/sbin/bwlimit.sh owner=root group=root mode=0755
     notify:
     - reset bwlimits
 
@@ -197,7 +197,7 @@
     file: path=/var/container_volumes/{{ container_name }}/etc/service/message state=directory
 
   - name: copy simple webserver
-    copy: src=/opt/xos/synchronizers/vcpe/files/etc/service/ dest=/var/container_volumes/{{ container_name }}/etc/service/ owner=root group=root
+    copy: src=/opt/xos/synchronizers/vsg/files/etc/service/ dest=/var/container_volumes/{{ container_name }}/etc/service/ owner=root group=root
     when: status != "enabled"
 
   - name: make webserver script executable
@@ -205,7 +205,7 @@
     when: status != "enabled"
 
   - name: generate the message page
-    template: src=/opt/xos/synchronizers/vcpe/templates/message.html.j2 dest=/var/container_volumes/{{ container_name }}/etc/service/message/message.html owner=root group=root mode=0644
+    template: src=/opt/xos/synchronizers/vsg/templates/message.html.j2 dest=/var/container_volumes/{{ container_name }}/etc/service/message/message.html owner=root group=root mode=0644
     when: status != "enabled"
     #notify: restart vcpe
 
diff --git a/xos/synchronizers/vcpe/steps/test.yaml b/xos/onboard/vsg/synchronizer/steps/test.yaml
similarity index 100%
rename from xos/synchronizers/vcpe/steps/test.yaml
rename to xos/onboard/vsg/synchronizer/steps/test.yaml
diff --git a/xos/synchronizers/vcpe/stop.sh b/xos/onboard/vsg/synchronizer/stop.sh
similarity index 100%
rename from xos/synchronizers/vcpe/stop.sh
rename to xos/onboard/vsg/synchronizer/stop.sh
diff --git a/xos/onboard/vsg/synchronizer/supervisor/vcpe-observer.conf b/xos/onboard/vsg/synchronizer/supervisor/vcpe-observer.conf
new file mode 100644
index 0000000..2d90293
--- /dev/null
+++ b/xos/onboard/vsg/synchronizer/supervisor/vcpe-observer.conf
@@ -0,0 +1,2 @@
+[program:vcpe-observer]
+command=python /opt/xos/synchronizers/vsg/vcpe-synchronizer.py -C /opt/xos/synchronizers/vsg/vcpe_synchronizer_config
diff --git a/xos/synchronizers/vcpe/templates/before.rules.j2 b/xos/onboard/vsg/synchronizer/templates/before.rules.j2
similarity index 100%
rename from xos/synchronizers/vcpe/templates/before.rules.j2
rename to xos/onboard/vsg/synchronizer/templates/before.rules.j2
diff --git a/xos/synchronizers/vcpe/templates/bwlimit.sh.j2 b/xos/onboard/vsg/synchronizer/templates/bwlimit.sh.j2
similarity index 100%
rename from xos/synchronizers/vcpe/templates/bwlimit.sh.j2
rename to xos/onboard/vsg/synchronizer/templates/bwlimit.sh.j2
diff --git a/xos/synchronizers/vcpe/templates/dnsmasq_safe_servers.j2 b/xos/onboard/vsg/synchronizer/templates/dnsmasq_safe_servers.j2
similarity index 100%
rename from xos/synchronizers/vcpe/templates/dnsmasq_safe_servers.j2
rename to xos/onboard/vsg/synchronizer/templates/dnsmasq_safe_servers.j2
diff --git a/xos/synchronizers/vcpe/templates/dnsmasq_servers.j2 b/xos/onboard/vsg/synchronizer/templates/dnsmasq_servers.j2
similarity index 100%
rename from xos/synchronizers/vcpe/templates/dnsmasq_servers.j2
rename to xos/onboard/vsg/synchronizer/templates/dnsmasq_servers.j2
diff --git a/xos/synchronizers/vcpe/templates/firewall_sample.j2 b/xos/onboard/vsg/synchronizer/templates/firewall_sample.j2
similarity index 100%
rename from xos/synchronizers/vcpe/templates/firewall_sample.j2
rename to xos/onboard/vsg/synchronizer/templates/firewall_sample.j2
diff --git a/xos/synchronizers/vcpe/templates/message.html.j2 b/xos/onboard/vsg/synchronizer/templates/message.html.j2
similarity index 100%
rename from xos/synchronizers/vcpe/templates/message.html.j2
rename to xos/onboard/vsg/synchronizer/templates/message.html.j2
diff --git a/xos/synchronizers/vcpe/templates/rc.local.j2 b/xos/onboard/vsg/synchronizer/templates/rc.local.j2
similarity index 100%
rename from xos/synchronizers/vcpe/templates/rc.local.j2
rename to xos/onboard/vsg/synchronizer/templates/rc.local.j2
diff --git a/xos/synchronizers/vcpe/templates/start-vcpe-vtn.sh.j2 b/xos/onboard/vsg/synchronizer/templates/start-vcpe-vtn.sh.j2
similarity index 100%
rename from xos/synchronizers/vcpe/templates/start-vcpe-vtn.sh.j2
rename to xos/onboard/vsg/synchronizer/templates/start-vcpe-vtn.sh.j2
diff --git a/xos/synchronizers/vcpe/templates/start-vcpe.sh.j2 b/xos/onboard/vsg/synchronizer/templates/start-vcpe.sh.j2
similarity index 100%
rename from xos/synchronizers/vcpe/templates/start-vcpe.sh.j2
rename to xos/onboard/vsg/synchronizer/templates/start-vcpe.sh.j2
diff --git a/xos/synchronizers/vcpe/templates/vcpe.conf.j2 b/xos/onboard/vsg/synchronizer/templates/vcpe.conf.j2
similarity index 100%
rename from xos/synchronizers/vcpe/templates/vcpe.conf.j2
rename to xos/onboard/vsg/synchronizer/templates/vcpe.conf.j2
diff --git a/xos/synchronizers/vcpe/templates/vlan_sample.j2 b/xos/onboard/vsg/synchronizer/templates/vlan_sample.j2
similarity index 100%
rename from xos/synchronizers/vcpe/templates/vlan_sample.j2
rename to xos/onboard/vsg/synchronizer/templates/vlan_sample.j2
diff --git a/xos/synchronizers/vcpe/vcpe-synchronizer.py b/xos/onboard/vsg/synchronizer/vcpe-synchronizer.py
similarity index 100%
rename from xos/synchronizers/vcpe/vcpe-synchronizer.py
rename to xos/onboard/vsg/synchronizer/vcpe-synchronizer.py
diff --git a/xos/synchronizers/vcpe/vcpe_stats_notifier.py b/xos/onboard/vsg/synchronizer/vcpe_stats_notifier.py
similarity index 100%
rename from xos/synchronizers/vcpe/vcpe_stats_notifier.py
rename to xos/onboard/vsg/synchronizer/vcpe_stats_notifier.py
diff --git a/xos/synchronizers/vcpe/vcpe_synchronizer_config b/xos/onboard/vsg/synchronizer/vcpe_synchronizer_config
similarity index 73%
rename from xos/synchronizers/vcpe/vcpe_synchronizer_config
rename to xos/onboard/vsg/synchronizer/vcpe_synchronizer_config
index 110b8e2..e41dc9a 100644
--- a/xos/synchronizers/vcpe/vcpe_synchronizer_config
+++ b/xos/onboard/vsg/synchronizer/vcpe_synchronizer_config
@@ -23,10 +23,10 @@
 
 [observer]
 name=vcpe
-dependency_graph=/opt/xos/synchronizers/vcpe/model-deps
-steps_dir=/opt/xos/synchronizers/vcpe/steps
-sys_dir=/opt/xos/synchronizers/vcpe/sys
-deleters_dir=/opt/xos/synchronizers/vcpe/deleters
+dependency_graph=/opt/xos/synchronizers/vsg/model-deps
+steps_dir=/opt/xos/synchronizers/vsg/steps
+sys_dir=/opt/xos/synchronizers/vsg/sys
+deleters_dir=/opt/xos/synchronizers/vsg/deleters
 log_file=console
 #/var/log/hpc.log
 driver=None
diff --git a/xos/synchronizers/vcpe/vtn_vcpe_synchronizer_config b/xos/onboard/vsg/synchronizer/vtn_vcpe_synchronizer_config
similarity index 70%
rename from xos/synchronizers/vcpe/vtn_vcpe_synchronizer_config
rename to xos/onboard/vsg/synchronizer/vtn_vcpe_synchronizer_config
index e92786b..b43d831 100644
--- a/xos/synchronizers/vcpe/vtn_vcpe_synchronizer_config
+++ b/xos/onboard/vsg/synchronizer/vtn_vcpe_synchronizer_config
@@ -23,10 +23,10 @@
 
 [observer]
 name=vcpe
-dependency_graph=/opt/xos/synchronizers/vcpe/model-deps
-steps_dir=/opt/xos/synchronizers/vcpe/steps
-sys_dir=/opt/xos/synchronizers/vcpe/sys
-deleters_dir=/opt/xos/synchronizers/vcpe/deleters
+dependency_graph=/opt/xos/synchronizers/vsg/model-deps
+steps_dir=/opt/xos/synchronizers/vsg/steps
+sys_dir=/opt/xos/synchronizers/vsg/sys
+deleters_dir=/opt/xos/synchronizers/vsg/deleters
 log_file=console
 #/var/log/hpc.log
 driver=None
@@ -36,7 +36,7 @@
 # set proxy_ssh to false on cloudlab
 full_setup=True
 proxy_ssh=True
-proxy_ssh_key=/opt/xos/synchronizers/vcpe/node_key
+proxy_ssh_key=/opt/xos/synchronizers/vsg/node_key
 proxy_ssh_user=root
 
 [networking]
diff --git a/xos/services/cord/templates/vcpeadmin.html b/xos/onboard/vsg/templates/vcpeadmin.html
similarity index 100%
rename from xos/services/cord/templates/vcpeadmin.html
rename to xos/onboard/vsg/templates/vcpeadmin.html
diff --git a/xos/tosca/resources/vcpeservice.py b/xos/onboard/vsg/tosca/resources/vcpeservice.py
similarity index 91%
rename from xos/tosca/resources/vcpeservice.py
rename to xos/onboard/vsg/tosca/resources/vcpeservice.py
index 972c13c..956d888 100644
--- a/xos/tosca/resources/vcpeservice.py
+++ b/xos/onboard/vsg/tosca/resources/vcpeservice.py
@@ -5,7 +5,7 @@
 sys.path.append("/opt/tosca")
 from translator.toscalib.tosca_template import ToscaTemplate
 
-from services.cord.models import VSGService
+from services.vsg.models import VSGService
 
 from service import XOSService
 
diff --git a/xos/onboard/vsg/vsg-onboard.yaml b/xos/onboard/vsg/vsg-onboard.yaml
new file mode 100644
index 0000000..48f6ad4
--- /dev/null
+++ b/xos/onboard/vsg/vsg-onboard.yaml
@@ -0,0 +1,27 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Onboard the exampleservice
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+    servicecontroller#vsg:
+      type: tosca.nodes.ServiceController
+      properties:
+          base_url: file:///opt/xos/onboard/vsg/
+          # The following will concatenate with base_url automatically, if
+          # base_url is non-null.
+          models: models.py
+          admin: admin.py
+          admin_template: templates/vcpeadmin.html
+          synchronizer: synchronizer/manifest
+          synchronizer_run: vcpe-synchronizer.py
+          #tosca_custom_types: exampleservice.yaml
+          tosca_resource: tosca/resources/vcpeservice.py
+          rest_service: subdirectory:vsg api/service/vsg/vsgservice.py
+          rest_tenant: subdirectory:cord api/tenant/cord/vsg.py
+          private_key: file:///opt/xos/key_import/vsg_rsa
+          public_key: file:///opt/xos/key_import/vsg_rsa.pub
+
diff --git a/xos/services/vtn/admin.py b/xos/onboard/vtn/admin.py
similarity index 97%
rename from xos/services/vtn/admin.py
rename to xos/onboard/vtn/admin.py
index 03ff5cd..464f197 100644
--- a/xos/services/vtn/admin.py
+++ b/xos/onboard/vtn/admin.py
@@ -1,6 +1,5 @@
 from django.contrib import admin
 
-from services.cord.models import *
 from django import forms
 from django.utils.safestring import mark_safe
 from django.contrib.auth.admin import UserAdmin
@@ -14,7 +13,6 @@
 from core.middleware import get_request
 
 from services.vtn.models import *
-from services.cord.models import CordSubscriberRoot
 
 from functools import update_wrapper
 from django.contrib.admin.views.main import ChangeList
diff --git a/xos/api/service/vtn.py b/xos/onboard/vtn/api/service/vtn.py
similarity index 100%
rename from xos/api/service/vtn.py
rename to xos/onboard/vtn/api/service/vtn.py
diff --git a/xos/services/vtn/models.py b/xos/onboard/vtn/models.py
similarity index 96%
rename from xos/services/vtn/models.py
rename to xos/onboard/vtn/models.py
index 52b1633..c805f24 100644
--- a/xos/services/vtn/models.py
+++ b/xos/onboard/vtn/models.py
@@ -8,7 +8,6 @@
 from operator import itemgetter, attrgetter, methodcaller
 from core.models import Tag
 from core.models.service import LeastLoadedNodeScheduler
-from services.cord.models import CordSubscriberRoot
 import traceback
 from xos.exceptions import *
 from xos.config import Config
diff --git a/xos/onboard/vtn/synchronizer/manifest b/xos/onboard/vtn/synchronizer/manifest
new file mode 100644
index 0000000..dccfcdc
--- /dev/null
+++ b/xos/onboard/vtn/synchronizer/manifest
@@ -0,0 +1,10 @@
+manifest
+vtn-synchronizer.py
+steps/sync_tenant.py
+steps/sync_port_addresses.py
+start.sh
+stop.sh
+model-deps
+supervisor/vtn-observer.conf
+run.sh
+vtn_synchronizer_config
diff --git a/xos/synchronizers/vbng/model-deps b/xos/onboard/vtn/synchronizer/model-deps
similarity index 100%
copy from xos/synchronizers/vbng/model-deps
copy to xos/onboard/vtn/synchronizer/model-deps
diff --git a/xos/synchronizers/vtn/run.sh b/xos/onboard/vtn/synchronizer/run.sh
similarity index 100%
rename from xos/synchronizers/vtn/run.sh
rename to xos/onboard/vtn/synchronizer/run.sh
diff --git a/xos/synchronizers/vtn/start.sh b/xos/onboard/vtn/synchronizer/start.sh
similarity index 100%
rename from xos/synchronizers/vtn/start.sh
rename to xos/onboard/vtn/synchronizer/start.sh
diff --git a/xos/synchronizers/vtn/steps/sync_port_addresses.py b/xos/onboard/vtn/synchronizer/steps/sync_port_addresses.py
similarity index 96%
rename from xos/synchronizers/vtn/steps/sync_port_addresses.py
rename to xos/onboard/vtn/synchronizer/steps/sync_port_addresses.py
index bbc6c99..553df6f 100644
--- a/xos/synchronizers/vtn/steps/sync_port_addresses.py
+++ b/xos/onboard/vtn/synchronizer/steps/sync_port_addresses.py
@@ -6,10 +6,9 @@
 from django.db.models import F, Q
 from xos.config import Config
 from synchronizers.base.syncstep import SyncStep
-from core.models import Service, Port, Controller, Tag
+from core.models import Service, Port, Controller, Tag, Tenant
 from core.models.service import COARSE_KIND
-from services.cord.models import VSGTenant
-from services.cord.models import Tenant
+from services.vsg.models import VSGTenant
 from xos.logger import Logger, logging
 from requests.auth import HTTPBasicAuth
 
diff --git a/xos/synchronizers/vtn/steps/sync_tenant.py b/xos/onboard/vtn/synchronizer/steps/sync_tenant.py
similarity index 97%
rename from xos/synchronizers/vtn/steps/sync_tenant.py
rename to xos/onboard/vtn/synchronizer/steps/sync_tenant.py
index cc374be..a0e6cdb 100644
--- a/xos/synchronizers/vtn/steps/sync_tenant.py
+++ b/xos/onboard/vtn/synchronizer/steps/sync_tenant.py
@@ -6,9 +6,8 @@
 from django.db.models import F, Q
 from xos.config import Config
 from synchronizers.base.syncstep import SyncStep
-from core.models import Service
+from core.models import Service, Tenant
 from core.models.service import COARSE_KIND
-from services.cord.models import Tenant
 from xos.logger import Logger, logging
 from requests.auth import HTTPBasicAuth
 
diff --git a/xos/synchronizers/vtn/stop.sh b/xos/onboard/vtn/synchronizer/stop.sh
similarity index 100%
rename from xos/synchronizers/vtn/stop.sh
rename to xos/onboard/vtn/synchronizer/stop.sh
diff --git a/xos/synchronizers/vtn/supervisor/vtn-observer.conf b/xos/onboard/vtn/synchronizer/supervisor/vtn-observer.conf
similarity index 100%
rename from xos/synchronizers/vtn/supervisor/vtn-observer.conf
rename to xos/onboard/vtn/synchronizer/supervisor/vtn-observer.conf
diff --git a/xos/synchronizers/vtn/vtn-synchronizer.py b/xos/onboard/vtn/synchronizer/vtn-synchronizer.py
similarity index 100%
rename from xos/synchronizers/vtn/vtn-synchronizer.py
rename to xos/onboard/vtn/synchronizer/vtn-synchronizer.py
diff --git a/xos/synchronizers/vtn/vtn_synchronizer_config b/xos/onboard/vtn/synchronizer/vtn_synchronizer_config
similarity index 100%
rename from xos/synchronizers/vtn/vtn_synchronizer_config
rename to xos/onboard/vtn/synchronizer/vtn_synchronizer_config
diff --git a/xos/services/vtn/templates/vtnadmin.html b/xos/onboard/vtn/templates/vtnadmin.html
similarity index 100%
rename from xos/services/vtn/templates/vtnadmin.html
rename to xos/onboard/vtn/templates/vtnadmin.html
diff --git a/xos/tosca/resources/vtnservice.py b/xos/onboard/vtn/tosca/resources/vtnservice.py
similarity index 100%
rename from xos/tosca/resources/vtnservice.py
rename to xos/onboard/vtn/tosca/resources/vtnservice.py
diff --git a/xos/onboard/vtn/vtn-onboard.yaml b/xos/onboard/vtn/vtn-onboard.yaml
new file mode 100644
index 0000000..460af5a
--- /dev/null
+++ b/xos/onboard/vtn/vtn-onboard.yaml
@@ -0,0 +1,25 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Onboard the exampleservice
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+    servicecontroller#vtn:
+      type: tosca.nodes.ServiceController
+      properties:
+          base_url: file:///opt/xos/onboard/vtn/
+          # The following will concatenate with base_url automatically, if
+          # base_url is non-null.
+          models: models.py
+          admin: admin.py
+          admin_template: templates/vtnadmin.html
+          synchronizer: synchronizer/manifest
+          synchronizer_run: vtn-synchronizer.py
+          tosca_resource: tosca/resources/vtnservice.py
+          rest_service: api/service/vtn.py
+          #private_key: file:///opt/xos/key_import/vsg_rsa
+          #public_key: file:///opt/xos/key_import/vsg_rsa.pub
+
diff --git a/xos/services/vtr/admin.py b/xos/onboard/vtr/admin.py
similarity index 98%
rename from xos/services/vtr/admin.py
rename to xos/onboard/vtr/admin.py
index 5015fc8..0120e66 100644
--- a/xos/services/vtr/admin.py
+++ b/xos/onboard/vtr/admin.py
@@ -1,6 +1,5 @@
 from django.contrib import admin
 
-from services.cord.models import *
 from django import forms
 from django.utils.safestring import mark_safe
 from django.contrib.auth.admin import UserAdmin
@@ -14,7 +13,7 @@
 from core.middleware import get_request
 
 from services.vtr.models import *
-from services.cord.models import CordSubscriberRoot
+from services.volt.models import CordSubscriberRoot
 
 from functools import update_wrapper
 from django.contrib.admin.views.main import ChangeList
diff --git a/xos/api/tenant/truckroll.py b/xos/onboard/vtr/api/tenant/truckroll.py
similarity index 97%
rename from xos/api/tenant/truckroll.py
rename to xos/onboard/vtr/api/tenant/truckroll.py
index b5e9e3f..cc8d62b 100644
--- a/xos/api/tenant/truckroll.py
+++ b/xos/onboard/vtr/api/tenant/truckroll.py
@@ -6,7 +6,6 @@
 from rest_framework import status
 from core.models import *
 from django.forms import widgets
-from services.cord.models import CordSubscriberRoot
 from services.vtr.models import VTRTenant, VTRService
 from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
 from api.xosapi_helpers import PlusModelSerializer, XOSViewSet, ReadOnlyField
diff --git a/xos/services/vtr/models.py b/xos/onboard/vtr/models.py
similarity index 97%
rename from xos/services/vtr/models.py
rename to xos/onboard/vtr/models.py
index 31c26c4..ce2e345 100644
--- a/xos/services/vtr/models.py
+++ b/xos/onboard/vtr/models.py
@@ -8,7 +8,7 @@
 from operator import itemgetter, attrgetter, methodcaller
 from core.models import Tag
 from core.models.service import LeastLoadedNodeScheduler
-from services.cord.models import CordSubscriberRoot
+from services.volt.models import CordSubscriberRoot
 import traceback
 from xos.exceptions import *
 from xos.config import Config
diff --git a/xos/synchronizers/vtr/files/run_tcpdump.sh b/xos/onboard/vtr/synchronizer/files/run_tcpdump.sh
similarity index 100%
rename from xos/synchronizers/vtr/files/run_tcpdump.sh
rename to xos/onboard/vtr/synchronizer/files/run_tcpdump.sh
diff --git a/xos/onboard/vtr/synchronizer/manifest b/xos/onboard/vtr/synchronizer/manifest
new file mode 100644
index 0000000..61ffb39
--- /dev/null
+++ b/xos/onboard/vtr/synchronizer/manifest
@@ -0,0 +1,10 @@
+manifest
+vtr-synchronizer.py
+vtn_vtr_synchronizer_config
+steps/sync_vtrtenant.py
+steps/sync_vtrtenant.yaml
+vtr_synchronizer_config
+files/run_tcpdump.sh
+run-vtn.sh
+model-deps
+run.sh
diff --git a/xos/synchronizers/vbng/model-deps b/xos/onboard/vtr/synchronizer/model-deps
similarity index 100%
copy from xos/synchronizers/vbng/model-deps
copy to xos/onboard/vtr/synchronizer/model-deps
diff --git a/xos/synchronizers/vtr/run-vtn.sh b/xos/onboard/vtr/synchronizer/run-vtn.sh
similarity index 100%
rename from xos/synchronizers/vtr/run-vtn.sh
rename to xos/onboard/vtr/synchronizer/run-vtn.sh
diff --git a/xos/synchronizers/vtr/run.sh b/xos/onboard/vtr/synchronizer/run.sh
similarity index 100%
rename from xos/synchronizers/vtr/run.sh
rename to xos/onboard/vtr/synchronizer/run.sh
diff --git a/xos/synchronizers/vtr/steps/sync_vtrtenant.py b/xos/onboard/vtr/synchronizer/steps/sync_vtrtenant.py
similarity index 97%
rename from xos/synchronizers/vtr/steps/sync_vtrtenant.py
rename to xos/onboard/vtr/synchronizer/steps/sync_vtrtenant.py
index c66f19c..1932d70 100644
--- a/xos/synchronizers/vtr/steps/sync_vtrtenant.py
+++ b/xos/onboard/vtr/synchronizer/steps/sync_vtrtenant.py
@@ -9,7 +9,7 @@
 from synchronizers.base.ansible import run_template_ssh
 from synchronizers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
 from core.models import Service, Slice, Tag
-from services.cord.models import VSGService, VSGTenant, VOLTTenant, CordSubscriberRoot
+from services.vsg.models import VSGService
 from services.vtr.models import VTRService, VTRTenant
 from services.hpc.models import HpcService, CDNPrefix
 from xos.logger import Logger, logging
diff --git a/xos/synchronizers/vtr/steps/sync_vtrtenant.yaml b/xos/onboard/vtr/synchronizer/steps/sync_vtrtenant.yaml
similarity index 100%
rename from xos/synchronizers/vtr/steps/sync_vtrtenant.yaml
rename to xos/onboard/vtr/synchronizer/steps/sync_vtrtenant.yaml
diff --git a/xos/synchronizers/vtr/vtn_vtr_synchronizer_config b/xos/onboard/vtr/synchronizer/vtn_vtr_synchronizer_config
similarity index 100%
rename from xos/synchronizers/vtr/vtn_vtr_synchronizer_config
rename to xos/onboard/vtr/synchronizer/vtn_vtr_synchronizer_config
diff --git a/xos/synchronizers/vtr/vtr-synchronizer.py b/xos/onboard/vtr/synchronizer/vtr-synchronizer.py
similarity index 100%
rename from xos/synchronizers/vtr/vtr-synchronizer.py
rename to xos/onboard/vtr/synchronizer/vtr-synchronizer.py
diff --git a/xos/synchronizers/vtr/vtr_synchronizer_config b/xos/onboard/vtr/synchronizer/vtr_synchronizer_config
similarity index 100%
rename from xos/synchronizers/vtr/vtr_synchronizer_config
rename to xos/onboard/vtr/synchronizer/vtr_synchronizer_config
diff --git a/xos/services/vtr/templates/vtradmin.html b/xos/onboard/vtr/templates/vtradmin.html
similarity index 100%
rename from xos/services/vtr/templates/vtradmin.html
rename to xos/onboard/vtr/templates/vtradmin.html
diff --git a/xos/onboard/vtr/vtr-onboard.yaml b/xos/onboard/vtr/vtr-onboard.yaml
new file mode 100644
index 0000000..1644f02
--- /dev/null
+++ b/xos/onboard/vtr/vtr-onboard.yaml
@@ -0,0 +1,23 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Onboard the exampleservice
+
+imports:
+   - custom_types/xos.yaml
+
+topology_template:
+  node_templates:
+    servicecontroller#vtr:
+      type: tosca.nodes.ServiceController
+      properties:
+          base_url: file:///opt/xos/onboard/vtr/
+          # The following will concatenate with base_url automatically, if
+          # base_url is non-null.
+          models: models.py
+          admin: admin.py
+          admin_template: templates/vtradmin.html
+          synchronizer: synchronizer/manifest
+          rest_tenant: api/tenant/truckroll.py
+          private_key: file:///opt/xos/key_import/vsg_rsa
+          public_key: file:///opt/xos/key_import/vsg_rsa.pub
+
diff --git a/xos/services/cord/__init__.py b/xos/services/cord_old/__init__.py
similarity index 100%
rename from xos/services/cord/__init__.py
rename to xos/services/cord_old/__init__.py
diff --git a/xos/services/cord/admin.py b/xos/services/cord_old/admin.py
similarity index 100%
rename from xos/services/cord/admin.py
rename to xos/services/cord_old/admin.py
diff --git a/xos/services/cord/migrations/0001_initial.py b/xos/services/cord_old/migrations/0001_initial.py
similarity index 100%
rename from xos/services/cord/migrations/0001_initial.py
rename to xos/services/cord_old/migrations/0001_initial.py
diff --git a/xos/services/cord/migrations/__init__.py b/xos/services/cord_old/migrations/__init__.py
similarity index 100%
rename from xos/services/cord/migrations/__init__.py
rename to xos/services/cord_old/migrations/__init__.py
diff --git a/xos/services/cord/models.py b/xos/services/cord_old/models.py
similarity index 100%
rename from xos/services/cord/models.py
rename to xos/services/cord_old/models.py
diff --git a/xos/services/cord/rest_examples/add_truckroll.sh b/xos/services/cord_old/rest_examples/add_truckroll.sh
similarity index 100%
rename from xos/services/cord/rest_examples/add_truckroll.sh
rename to xos/services/cord_old/rest_examples/add_truckroll.sh
diff --git a/xos/services/cord/rest_examples/add_volt_tenant.sh b/xos/services/cord_old/rest_examples/add_volt_tenant.sh
similarity index 100%
rename from xos/services/cord/rest_examples/add_volt_tenant.sh
rename to xos/services/cord_old/rest_examples/add_volt_tenant.sh
diff --git a/xos/services/cord/rest_examples/config.sh b/xos/services/cord_old/rest_examples/config.sh
similarity index 100%
rename from xos/services/cord/rest_examples/config.sh
rename to xos/services/cord_old/rest_examples/config.sh
diff --git a/xos/services/cord/rest_examples/delete_volt_tenant.sh b/xos/services/cord_old/rest_examples/delete_volt_tenant.sh
similarity index 100%
rename from xos/services/cord/rest_examples/delete_volt_tenant.sh
rename to xos/services/cord_old/rest_examples/delete_volt_tenant.sh
diff --git a/xos/services/cord/rest_examples/list_cord_subscribers.sh b/xos/services/cord_old/rest_examples/list_cord_subscribers.sh
similarity index 100%
rename from xos/services/cord/rest_examples/list_cord_subscribers.sh
rename to xos/services/cord_old/rest_examples/list_cord_subscribers.sh
diff --git a/xos/services/cord/rest_examples/list_truckrolls.sh b/xos/services/cord_old/rest_examples/list_truckrolls.sh
similarity index 100%
rename from xos/services/cord/rest_examples/list_truckrolls.sh
rename to xos/services/cord_old/rest_examples/list_truckrolls.sh
diff --git a/xos/services/cord/rest_examples/list_volt_tenants.sh b/xos/services/cord_old/rest_examples/list_volt_tenants.sh
similarity index 100%
rename from xos/services/cord/rest_examples/list_volt_tenants.sh
rename to xos/services/cord_old/rest_examples/list_volt_tenants.sh
diff --git a/xos/services/cord/templates/vbngadmin.html b/xos/services/cord_old/templates/vbngadmin.html
similarity index 100%
rename from xos/services/cord/templates/vbngadmin.html
rename to xos/services/cord_old/templates/vbngadmin.html
diff --git a/xos/services/vtr/__init__.py b/xos/services/vtr_old/__init__.py
similarity index 100%
rename from xos/services/vtr/__init__.py
rename to xos/services/vtr_old/__init__.py
diff --git a/xos/services/vtr/migrations/0001_initial.py b/xos/services/vtr_old/migrations/0001_initial.py
similarity index 100%
rename from xos/services/vtr/migrations/0001_initial.py
rename to xos/services/vtr_old/migrations/0001_initial.py
diff --git a/xos/services/vtr/migrations/__init__.py b/xos/services/vtr_old/migrations/__init__.py
similarity index 100%
rename from xos/services/vtr/migrations/__init__.py
rename to xos/services/vtr_old/migrations/__init__.py
diff --git a/xos/synchronizers/onboarding/xosbuilder.py b/xos/synchronizers/onboarding/xosbuilder.py
index ffb66ee..e7a3e1c 100644
--- a/xos/synchronizers/onboarding/xosbuilder.py
+++ b/xos/synchronizers/onboarding/xosbuilder.py
@@ -14,7 +14,7 @@
 logger = Logger(level=logging.INFO)
 
 class XOSBuilder(object):
-    UI_KINDS=["models", "admin", "django_library", "rest_service", "rest_tenant", "tosca_custom_types", "tosca_resource","public_key"]
+    UI_KINDS=["models", "admin", "admin_template", "django_library", "rest_service", "rest_tenant", "tosca_custom_types", "tosca_resource","public_key"]
     SYNC_CONTROLLER_KINDS=["synchronizer", "private_key", "public_key"]
     SYNC_ALLCONTROLLER_KINDS=["models", "django_library"]
 
@@ -30,15 +30,21 @@
         service_name = scr.service_controller.name
         base_dirs = {"models": "%s/services/%s/" % (xos_base, service_name),
                      "admin": "%s/services/%s/" % (xos_base, service_name),
+                     "admin_template": "%s/services/%s/templates/" % (xos_base, service_name),
                      "django_library": "%s/services/%s/" % (xos_base, service_name),
                      "synchronizer": "%s/synchronizers/%s/" % (xos_base, service_name),
                      "tosca_custom_types": "%s/tosca/custom_types/" % (xos_base),
                      "tosca_resource": "%s/tosca/resources/" % (xos_base),
                      "rest_service": "%s/api/service/" % (xos_base),
                      "rest_tenant": "%s/api/tenant/" % (xos_base),
-                     "private_key": "%s/services/%s/keys" % (xos_base, service_name),
+                     "private_key": "%s/services/%s/keys/" % (xos_base, service_name),
                      "public_key": "%s/services/%s/keys/" % (xos_base, service_name)}
-        return base_dirs[scr.kind]
+        dest_dir = base_dirs[scr.kind]
+
+        if scr.subdirectory:
+            dest_dir = os.path.join(dest_dir, scr.subdirectory)
+
+        return dest_dir
 
     def get_build_fn(self, scr):
         dest_dir = self.get_dest_dir(scr)
@@ -86,33 +92,69 @@
         else:
             self.download_file(scr.full_url, self.get_download_fn(scr))
 
-    def get_docker_lines(self, scr):
+# XXX docker creates a new container and commits it for every single COPY
+# line in the dockerfile. This causes services with many files (for example,
+# vsg) to take ~ 10-15 minutes to build the docker file. So instead we'll copy
+# the whole build directory, and then run a script that copies the files
+# we want.
+
+#    def get_docker_lines(self, scr):
+#        if scr.format == "manifest":
+#            manifest_fn = self.get_download_fn(scr)
+#            manifest = self.read_manifest(scr, manifest_fn)
+#            lines = []
+#            for (url, download_fn, build_fn) in manifest:
+#               script.append("mkdir -p
+#               #lines.append("COPY %s /%s" % (build_fn, build_fn))
+#            return lines
+#        else:
+#            build_fn = self.get_build_fn(scr)
+#            #return ["COPY %s /%s" % (build_fn, build_fn)]
+
+#    def get_controller_docker_lines(self, controller, kinds):
+#        need_service_init_py = False
+#        dockerfile=[]
+#        for scr in controller.service_controller_resources.all():
+#            if scr.kind in kinds:
+#                lines = self.get_docker_lines(scr)
+#                dockerfile = dockerfile + lines
+#            if scr.kind in ["admin", "models"]:
+#                need_service_init_py = True
+#
+#        if need_service_init_py:
+#            file(os.path.join(self.build_dir, "opt/xos/empty__init__.py"),"w").write("")
+#            dockerfile.append("COPY opt/xos/empty__init__.py /opt/xos/services/%s/__init__.py" % controller.name)
+#
+#        return dockerfile
+
+    def get_script_lines(self, scr):
         if scr.format == "manifest":
             manifest_fn = self.get_download_fn(scr)
             manifest = self.read_manifest(scr, manifest_fn)
             lines = []
             for (url, download_fn, build_fn) in manifest:
-               lines.append("ADD %s /%s" % (build_fn, build_fn))
+               lines.append("mkdir -p /%s" % os.path.dirname(build_fn))
+               lines.append("cp /build/%s /%s" % (build_fn, build_fn))
             return lines
         else:
             build_fn = self.get_build_fn(scr)
-            return ["ADD %s /%s" % (build_fn, build_fn)]
+            return ["mkdir -p /%s" % os.path.dirname(build_fn),
+                    "cp /build/%s /%s" % (build_fn, build_fn)]
 
-    def get_controller_docker_lines(self, controller, kinds):
+    def get_controller_script_lines(self, controller, kinds):
         need_service_init_py = False
-        dockerfile=[]
+        script=[]
         for scr in controller.service_controller_resources.all():
             if scr.kind in kinds:
-                lines = self.get_docker_lines(scr)
-                dockerfile = dockerfile + lines
+                lines = self.get_script_lines(scr)
+                script = script + lines
             if scr.kind in ["admin", "models"]:
                 need_service_init_py = True
 
         if need_service_init_py:
-            file(os.path.join(self.build_dir, "opt/xos/empty__init__.py"),"w").write("")
-            dockerfile.append("ADD opt/xos/empty__init__.py /opt/xos/services/%s/__init__.py" % controller.name)
+            script.append("echo > /opt/xos/services/%s/__init__.py" % controller.name)
 
-        return dockerfile
+        return script
 
     def check_controller_unready(self, controller):
         unready_resources=[]
@@ -124,16 +166,20 @@
 
     # stuff that has to do with building
 
-    def create_xos_app_data(self, name, dockerfile, app_list, migration_list):
+    def create_xos_app_data(self, name, script, app_list, migration_list):
         if not os.path.exists(os.path.join(self.build_dir,"opt/xos/xos")):
             os.makedirs(os.path.join(self.build_dir,"opt/xos/xos"))
 
         if app_list:
-            dockerfile.append("COPY opt/xos/xos/%s_xosbuilder_app_list /opt/xos/xos/xosbuilder_app_list" % name)
+            script.append("mkdir -p /opt/xos/xos")
+            script.append("cp /build/opt/xos/xos/%s_xosbuilder_app_list /opt/xos/xos/xosbuilder_app_list" % name)
+            #dockerfile.append("COPY opt/xos/xos/%s_xosbuilder_app_list /opt/xos/xos/xosbuilder_app_list" % name)
             file(os.path.join(self.build_dir, "opt/xos/xos/%s_xosbuilder_app_list") % name, "w").write("\n".join(app_list)+"\n")
 
         if migration_list:
-            dockerfile.append("COPY opt/xos/xos/%s_xosbuilder_migration_list /opt/xos/xos/xosbuilder_migration_list" % name)
+            script.append("mkdir -p /opt/xos/xos")
+            script.append("cp /build/opt/xos/xos/%s_xosbuilder_migration_list /opt/xos/xos/xosbuilder_migration_list" % name)
+            #dockerfile.append("COPY opt/xos/xos/%s_xosbuilder_migration_list /opt/xos/xos/xosbuilder_migration_list" % name)
             file(os.path.join(self.build_dir, "opt/xos/xos/%s_xosbuilder_migration_list") % name, "w").write("\n".join(migration_list)+"\n")
 
     def create_ui_dockerfile(self):
@@ -143,17 +189,23 @@
         migration_list = []
 
         dockerfile = ["FROM %s" % self.source_ui_image]
+        script = []
         for controller in ServiceController.objects.all():
             if self.check_controller_unready(controller):
                  logger.warning("Controller %s has unready resources" % str(controller))
                  continue
 
-            dockerfile = dockerfile + self.get_controller_docker_lines(controller, self.UI_KINDS)
+            #dockerfile = dockerfile + self.get_controller_docker_lines(controller, self.UI_KINDS)
+            script = script + self.get_controller_script_lines(controller, self.UI_KINDS)
             if controller.service_controller_resources.filter(kind="models").exists():
                 app_list.append("services." + controller.name)
                 migration_list.append(controller.name)
 
-        self.create_xos_app_data("ui", dockerfile, app_list, migration_list)
+        self.create_xos_app_data("ui", script, app_list, migration_list)
+
+        file(os.path.join(self.build_dir, "install-xos.sh"), "w").write("\n".join(script)+"\n")
+        dockerfile.append("COPY . /build/")
+        dockerfile.append("RUN bash /build/install-xos.sh")
 
         file(os.path.join(self.build_dir, dockerfile_fn), "w").write("\n".join(dockerfile)+"\n")
 
@@ -162,25 +214,32 @@
 
     def create_synchronizer_dockerfile(self, controller):
         # bake in the synchronizer from this controller
-        sync_lines = self.get_controller_docker_lines(controller, self.SYNC_CONTROLLER_KINDS)
+        sync_lines = self.get_controller_script_lines(controller, self.SYNC_CONTROLLER_KINDS)
         if not sync_lines:
             return []
 
         dockerfile_fn = "Dockerfile.%s" % controller.name
         dockerfile = ["FROM %s" % self.source_sync_image]
+        script = []
 
         # Now bake in models from this controller as well as the others
         # It's important to bake all services in, because some services'
         # synchronizers may depend on models from another service.
         app_list = []
         for c in ServiceController.objects.all():
-            dockerfile = dockerfile + self.get_controller_docker_lines(c, self.SYNC_ALLCONTROLLER_KINDS)
+            #dockerfile = dockerfile + self.get_controller_docker_lines(c, self.SYNC_ALLCONTROLLER_KINDS)
+            script = script + self.get_controller_script_lines(c, self.SYNC_ALLCONTROLLER_KINDS)
             if controller.service_controller_resources.filter(kind="models").exists():
-                app_list.append("services." + controller.name)
+                app_list.append("services." + c.name)
 
-        self.create_xos_app_data(controller.name, dockerfile, app_list, None)
+        self.create_xos_app_data(controller.name, script, app_list, None)
 
-        dockerfile = dockerfile + sync_lines
+        script = script + sync_lines
+
+        file(os.path.join(self.build_dir, "install-%s.sh" % controller.name), "w").write("\n".join(script)+"\n")
+        dockerfile.append("COPY . /build/")
+        dockerfile.append("RUN bash /build/install-%s.sh" % controller.name)
+
         file(os.path.join(self.build_dir, dockerfile_fn), "w").write("\n".join(dockerfile)+"\n")
 
         return {"dockerfile_fn": dockerfile_fn,
@@ -218,17 +277,24 @@
 #                             "links": ["xos_db"],
 #                             "volumes": volume_list}
 
-         for c in ServiceController.objects.all():
-             if self.check_controller_unready(c):
-                 logger.warning("Controller %s has unready resources" % str(c))
-                 continue
+         if not xos.frontend_only:
+             for c in ServiceController.objects.all():
+                 if self.check_controller_unready(c):
+                     logger.warning("Controller %s has unready resources" % str(c))
+                     continue
 
-             containers["xos_synchronizer_%s" % c.name] = \
-                            {"image": "xosproject/xos-synchronizer-%s" % c.name,
-                             "command": 'bash -c "sleep 120; cd /opt/xos/synchronizers/%s; bash ./run.sh"' % c.name,
-                             #"external_links": [db_container_name],
-                             "links": ["xos_db"],
-                             "volumes": volume_list}
+                 if c.service_controller_resources.filter(kind="synchronizer").exists():
+                     if c.synchronizer_run and c.synchronizer_config:
+                         command = 'bash -c "sleep 120; cd /opt/xos/synchronizers/%s; python ./%s -C %s"' % (c.name, c.synchronizer_run, c.synchronizer_config)
+                     else:
+                         command = 'bash -c "sleep 120; cd /opt/xos/synchronizers/%s; bash ./run.sh"' % c.name
+
+                     containers["xos_synchronizer_%s" % c.name] = \
+                                    {"image": "xosproject/xos-synchronizer-%s" % c.name,
+                                     "command": command,
+                                     #"external_links": [db_container_name],
+                                     "links": ["xos_db"],
+                                     "volumes": volume_list}
 
          vars = { "containers": containers }
 
diff --git a/xos/synchronizers/openstack/steps/sync_container.py b/xos/synchronizers/openstack/steps/sync_container.py
index 84a2c61..41e1305 100644
--- a/xos/synchronizers/openstack/steps/sync_container.py
+++ b/xos/synchronizers/openstack/steps/sync_container.py
@@ -10,7 +10,6 @@
 from synchronizers.base.syncstep import SyncStep, DeferredException
 from synchronizers.base.ansible import run_template_ssh
 from core.models import Service, Slice, Instance
-from services.onos.models import ONOSService, ONOSApp
 from xos.logger import Logger, logging
 
 # hpclibrary will be in steps/..
diff --git a/xos/synchronizers/vbng/run.sh b/xos/synchronizers/vbng/run.sh
deleted file mode 100755
index de3ed7c..0000000
--- a/xos/synchronizers/vbng/run.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#if [[ ! -e ./vbng-observer.py ]]; then
-#    ln -s ../../xos-observer.py vbng-observer.py
-#fi
-
-export XOS_DIR=/opt/xos
-python vbng-synchronizer.py  -C $XOS_DIR/synchronizers/vbng/vbng_synchronizer_config
diff --git a/xos/synchronizers/vbng/start.sh b/xos/synchronizers/vbng/start.sh
deleted file mode 100755
index 9553610..0000000
--- a/xos/synchronizers/vbng/start.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#if [[ ! -e ./vbng-observer.py ]]; then
-#    ln -s ../../xos-observer.py vbng-observer.py
-#fi
-
-export XOS_DIR=/opt/xos
-nohup python vbng-synchronizer.py  -C $XOS_DIR/synchronizers/vbng/vbng_synchronizer_config > /dev/null 2>&1 &
diff --git a/xos/synchronizers/vbng/steps/sync_vbngtenant.py b/xos/synchronizers/vbng/steps/sync_vbngtenant.py
deleted file mode 100644
index 89e7bc0..0000000
--- a/xos/synchronizers/vbng/steps/sync_vbngtenant.py
+++ /dev/null
@@ -1,142 +0,0 @@
-import os
-import requests
-import socket
-import sys
-import base64
-from django.db.models import F, Q
-from xos.config import Config
-from synchronizers.base.syncstep import SyncStep
-from synchronizers.base.ansible import run_template_ssh
-from core.models import Service
-from services.cord.models import VSGService, VSGTenant, VBNGTenant, VBNGService
-from services.hpc.models import HpcService, CDNPrefix
-from xos.logger import Logger, logging
-
-# VBNG_API = "http://10.0.3.136:8181/onos/virtualbng/privateip/"
-
-# hpclibrary will be in steps/..
-parentdir = os.path.join(os.path.dirname(__file__),"..")
-sys.path.insert(0,parentdir)
-
-logger = Logger(level=logging.INFO)
-
-class SyncVBNGTenant(SyncStep):
-    provides=[VSGTenant]
-    observes=VSGTenant
-    requested_interval=0
-
-    def __init__(self, **args):
-        SyncStep.__init__(self, **args)
-
-    def fetch_pending(self, deleted):
-        if (not deleted):
-            objs = VBNGTenant.get_tenant_objects().filter(Q(enacted__lt=F('updated')) | Q(enacted=None),Q(lazy_blocked=False))
-        else:
-            objs = VBNGTenant.get_deleted_tenant_objects()
-
-        return objs
-
-    def defer_sync(self, o, reason):
-        logger.info("defer object %s due to %s" % (str(o), reason),extra=o.tologdict())
-        raise Exception("defer object %s due to %s" % (str(o), reason))
-
-    def get_vbng_service(self, o):
-        if not o.provider_service:
-             raise Exception("vBNG tenant %s has no provider_service" % str(o.id))
-        services = VBNGService.get_service_objects().filter(id = o.provider_service.id)
-        if not services:
-             raise Exception("vBNG tenant %s is associated with the wrong kind of provider_service" % str(o.id))
-        return services[0]
-
-    def get_vbng_url(self, o):
-        service = self.get_vbng_service(o)
-
-        # if the service object specifies a vbng_url, then use it
-        if service.vbng_url:
-            return service.vbng_url
-
-        # otherwise, see if the service has tenancy in ONOS
-        for tenant in service.subscribed_tenants.all():
-            if tenant.provider_service and tenant.provider_service.kind == "onos":
-                onos_service = tenant.provider_service
-                if not onos_service.slices.exists():
-                    raise Exception("vBNG service is linked to an ONOSApp, but the App's Service has no slices")
-                onos_slice = onos_service.slices.all()[0]
-                if not onos_slice.instances.exists():
-                    raise Exception("vBNG service is linked to an ONOSApp, but the App's Service's Slice has no instances")
-                instance = onos_slice.instances.all()[0]
-
-                #onos_app = ONOSApp.objects.filter(id = tenant.id)
-                #instance = onos_app.instance
-                #if not instance:
-                #    raise Exception("ONOSApp has no instance")
-
-                if not instance.instance_name:
-                    raise Exception("vBNG service is linked to an ONOSApp, but the App's Service's Slice's first instance is not instantiated")
-                ip = instance.get_network_ip("nat")
-                if not ip:
-                    raise Exception("vBNG service is linked to an ONOSApp, but the App's Service's Slice's first instance does not have an ip")
-
-                logger.info("Using ip %s from ONOS Instance %s" % (ip, instance),extra=o.tologdict())
-
-                return "http://%s:8181/onos/virtualbng/" % ip
-
-        raise Exception("vBNG service does not have vbng_url set, and is not linked to an ONOSApp")
-
-    def get_private_interface(self, o):
-        vcpes = VSGTenant.get_tenant_objects().all()
-        vcpes = [x for x in vcpes if (x.vbng is not None) and (x.vbng.id == o.id)]
-        if not vcpes:
-            raise Exception("No vCPE tenant is associated with vBNG %s" % str(o.id))
-        if len(vcpes)>1:
-            raise Exception("More than one vCPE tenant is associated with vBNG %s" % str(o.id))
-
-        vcpe = vcpes[0]
-        instance = vcpe.instance
-
-        if not instance:
-            raise Exception("No instance associated with vBNG %s" % str(o.id))
-
-        if not vcpe.wan_ip:
-            self.defer_sync(o, "does not have a WAN IP yet")
-
-        if not vcpe.wan_container_mac:
-            # this should never happen; container MAC is computed from WAN IP
-            self.defer_sync(o, "does not have a WAN container MAC yet")
-
-        return (vcpe.wan_ip, vcpe.wan_container_mac, vcpe.instance.node.name)
-
-    def sync_record(self, o):
-        logger.info("sync'ing VBNGTenant %s" % str(o),extra=o.tologdict())
-
-        if not o.routeable_subnet:
-            (private_ip, private_mac, private_hostname) = self.get_private_interface(o)
-            logger.info("contacting vBNG service to request mapping for private ip %s mac %s host %s" % (private_ip, private_mac, private_hostname) ,extra=o.tologdict())
-
-            url = self.get_vbng_url(o) + "privateip/%s/%s/%s" % (private_ip, private_mac, private_hostname)
-            logger.info( "vbng url: %s" % url ,extra=o.tologdict())
-            r = requests.post(url )
-            if (r.status_code != 200):
-                raise Exception("Received error from bng service (%d)" % r.status_code)
-            logger.info("received public IP %s from private IP %s" % (r.text, private_ip),extra=o.tologdict())
-
-            if r.text == "0":
-                raise Exception("VBNG service failed to return a routeable_subnet (probably ran out)")
-
-            o.routeable_subnet = r.text
-            o.mapped_ip = private_ip
-            o.mapped_mac = private_mac
-            o.mapped_hostname = private_hostname
-
-        o.save()
-
-    def delete_record(self, o):
-        logger.info("deleting VBNGTenant %s" % str(o),extra=o.tologdict())
-
-        if o.mapped_ip:
-            private_ip = o.mapped_ip
-            logger.info("contacting vBNG service to delete private ip %s" % private_ip,extra=o.tologdict())
-            r = requests.delete(self.get_vbng_url(o) + "privateip/%s" % private_ip, )
-            if (r.status_code != 200):
-                raise Exception("Received error from bng service (%d)" % r.status_code)
-
diff --git a/xos/synchronizers/vbng/stop.sh b/xos/synchronizers/vbng/stop.sh
deleted file mode 100755
index d49591e..0000000
--- a/xos/synchronizers/vbng/stop.sh
+++ /dev/null
@@ -1 +0,0 @@
-pkill -9 -f vbng-observer.py
diff --git a/xos/synchronizers/vbng/supervisor/vbng-observer.conf b/xos/synchronizers/vbng/supervisor/vbng-observer.conf
deleted file mode 100644
index a999318..0000000
--- a/xos/synchronizers/vbng/supervisor/vbng-observer.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-[program:vbng-observer]
-command=python /opt/xos/synchronizers/vbng/vbng-synchronizer.py -C /opt/xos/synchronizers/vbng/vbng_synchronizer_config
diff --git a/xos/synchronizers/vbng/vbng-synchronizer.py b/xos/synchronizers/vbng/vbng-synchronizer.py
deleted file mode 100755
index 84bec4f..0000000
--- a/xos/synchronizers/vbng/vbng-synchronizer.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env python
-
-# This imports and runs ../../xos-observer.py
-
-import importlib
-import os
-import sys
-observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../synchronizers/base")
-sys.path.append(observer_path)
-mod = importlib.import_module("xos-synchronizer")
-mod.main()
diff --git a/xos/synchronizers/vbng/vbng_synchronizer_config b/xos/synchronizers/vbng/vbng_synchronizer_config
deleted file mode 100644
index d613ce3..0000000
--- a/xos/synchronizers/vbng/vbng_synchronizer_config
+++ /dev/null
@@ -1,38 +0,0 @@
-
-[plc]
-name=plc
-deployment=VICCI
-
-[db]
-name=xos
-user=postgres
-password=password
-host=localhost
-port=5432
-
-[api]
-host=128.112.171.237
-port=8000
-ssl_key=None
-ssl_cert=None
-ca_ssl_cert=None
-ratelimit_enabled=0
-omf_enabled=0
-mail_support_address=support@localhost
-nova_enabled=True
-
-[observer]
-name=vbng
-dependency_graph=/opt/xos/synchronizers/vbng/model-deps
-steps_dir=/opt/xos/synchronizers/vbng/steps
-sys_dir=/opt/xos/synchronizers/vbng/sys
-deleters_dir=/opt/xos/synchronizers/vbng/deleters
-log_file=console
-#/var/log/hpc.log
-driver=None
-pretend=False
-backoff_disabled=True
-
-[feefie]
-client_id='vicci_dev_central'
-user_id='pl'
diff --git a/xos/synchronizers/vcpe/model-deps b/xos/synchronizers/vcpe/model-deps
deleted file mode 100644
index 0967ef4..0000000
--- a/xos/synchronizers/vcpe/model-deps
+++ /dev/null
@@ -1 +0,0 @@
-{}
diff --git a/xos/synchronizers/vcpe/supervisor/vcpe-observer.conf b/xos/synchronizers/vcpe/supervisor/vcpe-observer.conf
deleted file mode 100644
index 13d797a..0000000
--- a/xos/synchronizers/vcpe/supervisor/vcpe-observer.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-[program:vcpe-observer]
-command=python /opt/xos/synchronizers/vcpe/vcpe-synchronizer.py -C /opt/xos/synchronizers/vcpe/vcpe_synchronizer_config
diff --git a/xos/synchronizers/vtn/model-deps b/xos/synchronizers/vtn/model-deps
deleted file mode 100644
index 0967ef4..0000000
--- a/xos/synchronizers/vtn/model-deps
+++ /dev/null
@@ -1 +0,0 @@
-{}
diff --git a/xos/synchronizers/vtr/model-deps b/xos/synchronizers/vtr/model-deps
deleted file mode 100644
index 0967ef4..0000000
--- a/xos/synchronizers/vtr/model-deps
+++ /dev/null
@@ -1 +0,0 @@
-{}
diff --git a/xos/tests/api/helpers/before_test.py b/xos/tests/api/helpers/before_test.py
index d45f4e5..a977564 100644
--- a/xos/tests/api/helpers/before_test.py
+++ b/xos/tests/api/helpers/before_test.py
@@ -9,7 +9,8 @@
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
 import django
 from core.models import *
-from services.cord.models import *
+from services.volt.models import *
+from services.vsg.models import *
 from services.vtr.models import *
 import urllib2
 import json
diff --git a/xos/tests/api/helpers/flavors.py b/xos/tests/api/helpers/flavors.py
index e16d41f..dca4d77 100644
--- a/xos/tests/api/helpers/flavors.py
+++ b/xos/tests/api/helpers/flavors.py
@@ -9,8 +9,6 @@
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
 import django
 from core.models import *
-from services.cord.models import *
-from services.vtr.models import *
 import urllib2
 import json
 django.setup()
diff --git a/xos/tests/api/helpers/subscriber.py b/xos/tests/api/helpers/subscriber.py
index 4ede030..320c73c 100644
--- a/xos/tests/api/helpers/subscriber.py
+++ b/xos/tests/api/helpers/subscriber.py
@@ -9,7 +9,8 @@
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
 import django
 from core.models import *
-from services.cord.models import *
+from services.volt.models import *
+from services.vsg.models import *
 from services.vtr.models import *
 from django.contrib.auth import authenticate, login
 from django.core.exceptions import PermissionDenied
diff --git a/xos/tests/api/hooks.py b/xos/tests/api/hooks.py
index 43756c9..9fbf83f 100644
--- a/xos/tests/api/hooks.py
+++ b/xos/tests/api/hooks.py
@@ -9,7 +9,8 @@
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
 import django
 from core.models import *
-from services.cord.models import *
+from services.volt.models import *
+from services.vsg.models import *
 from services.vtr.models import *
 import urllib2
 import json
diff --git a/xos/tools/cleanup_unique.py b/xos/tools/cleanup_unique.py
index 4df82f4..97710ec 100644
--- a/xos/tools/cleanup_unique.py
+++ b/xos/tools/cleanup_unique.py
@@ -4,8 +4,6 @@
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
 import django
 from core.models import *
-from services.hpc.models import *
-from services.cord.models import *
 django.setup()
 
 for obj in ControllerNetwork.deleted_objects.all():
diff --git a/xos/tools/dmdot b/xos/tools/dmdot
index a57c0b1..9cde0ed 100755
--- a/xos/tools/dmdot
+++ b/xos/tools/dmdot
@@ -20,7 +20,7 @@
       sys.exit(-1)
 
 # defaults
-apps = ["core", "services.hpc", "services.cord", "services.requestrouter", "services.onos"]
+apps = ["core", "services.hpc", "services.requestrouter", "services.onos"]
 output = "-json"
 
 # syntax: dmdot [-json | -dot] [app_name]
diff --git a/xos/tools/purge.py b/xos/tools/purge.py
index 023c2fe..8c081e6 100644
--- a/xos/tools/purge.py
+++ b/xos/tools/purge.py
@@ -4,8 +4,6 @@
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")
 import django
 from core.models import *
-from services.hpc.models import *
-from services.cord.models import *
 django.setup()
 
 def purge(cls):
diff --git a/xos/tools/wait_for_object_creation.py b/xos/tools/wait_for_object_creation.py
index 354a213..b2af38f 100755
--- a/xos/tools/wait_for_object_creation.py
+++ b/xos/tools/wait_for_object_creation.py
@@ -5,7 +5,8 @@
 import django
 from core.models import *
 from services.hpc.models import *
-from services.cord.models import *
+from services.volt.models import *
+from services.vsg.models import *
 import time
 django.setup()
 
diff --git a/xos/tools/xos-manage b/xos/tools/xos-manage
index fcd14e1..8871c12 100755
--- a/xos/tools/xos-manage
+++ b/xos/tools/xos-manage
@@ -142,14 +142,13 @@
     python ./manage.py makemigrations hpc
     python ./manage.py makemigrations requestrouter
     python ./manage.py makemigrations syndicate_storage
-    python ./manage.py makemigrations cord
     python ./manage.py makemigrations mcord
     python ./manage.py makemigrations ceilometer
-    python ./manage.py makemigrations onos
+#    python ./manage.py makemigrations onos
     python ./manage.py makemigrations openvpn
-    python ./manage.py makemigrations vtr
+#    python ./manage.py makemigrations vtr
     python ./manage.py makemigrations vrouter
-    python ./manage.py makemigrations vtn
+#    python ./manage.py makemigrations vtn
     python ./manage.py makemigrations fabric
     #python ./manage.py makemigrations servcomp
 
diff --git a/xos/tosca/custom_types/xos.m4 b/xos/tosca/custom_types/xos.m4
index 9e6cb41..ef852af 100644
--- a/xos/tosca/custom_types/xos.m4
+++ b/xos/tosca/custom_types/xos.m4
@@ -27,6 +27,10 @@
                 type: boolean
                 required: false
                 description: True if XOS build should be enabled
+            frontend_only:
+                type: boolean
+                required: false
+                description: True if XOS should not start synchronizer containers
 
 
     tosca.nodes.XOSVolume:
@@ -72,10 +76,22 @@
                 type: string
                 required: false
                 description: url of admin.py
+            admin_template:
+                type: string
+                required: false
+                description: url of admin html template
             synchronizer:
                 type: string
                 required: false
                 description: url of synchronizer manifest
+            synchronizer_run:
+                type: string
+                required: false
+                description: synchronizer run command
+            synchronizer_config:
+                type: string
+                required: false
+                description: synchronizer config filename
             tosca_custom_types:
                 type: string
                 required: false
diff --git a/xos/tosca/custom_types/xos.yaml b/xos/tosca/custom_types/xos.yaml
index 0888c53..93dad18 100644
--- a/xos/tosca/custom_types/xos.yaml
+++ b/xos/tosca/custom_types/xos.yaml
@@ -57,6 +57,10 @@
                 type: boolean
                 required: false
                 description: True if XOS build should be enabled
+            frontend_only:
+                type: boolean
+                required: false
+                description: True if XOS should not start synchronizer containers
 
 
     tosca.nodes.XOSVolume:
@@ -180,10 +184,22 @@
                 type: string
                 required: false
                 description: url of admin.py
+            admin_template:
+                type: string
+                required: false
+                description: url of admin html template
             synchronizer:
                 type: string
                 required: false
                 description: url of synchronizer manifest
+            synchronizer_run:
+                type: string
+                required: false
+                description: synchronizer run command
+            synchronizer_config:
+                type: string
+                required: false
+                description: synchronizer config filename
             tosca_custom_types:
                 type: string
                 required: false
diff --git a/xos/tosca/resources/servicecontroller.py b/xos/tosca/resources/servicecontroller.py
index d821b56..d7e894a 100644
--- a/xos/tosca/resources/servicecontroller.py
+++ b/xos/tosca/resources/servicecontroller.py
@@ -12,34 +12,51 @@
 class XOSServiceController(XOSResource):
     provides = "tosca.nodes.ServiceController"
     xos_model = ServiceController
-    copyin_props = ["base_url"]
+    copyin_props = ["base_url", "synchronizer_run", "synchronizer_config"]
 
     def postprocess_resource_prop(self, obj, kind, format):
         values = self.get_property(kind)
         if values:
             for i,value in enumerate(values.split(",")):
                 value = value.strip()
+                subdirectory = None
 
                 name=kind
                 if i>0:
                     name = "%s_%d" %( name, i)
 
+                if (" " in value):
+                    parts=value.split()
+                    for part in parts[:-1]:
+                       if ":" in part:
+                           (lhs, rhs) = part.split(":", 1)
+                           if lhs=="subdirectory":
+                               subdirectory=rhs
+                           else:
+                               raise Exception("Malformed value %s" % value)
+                       else:
+                           raise Exception("Malformed value %s" % value)
+                    value = parts[-1]
+
+
                 scr = ServiceControllerResource.objects.filter(service_controller=obj, name=name, kind=kind, format=format)
                 if scr:
                     scr=scr[0]
-                    if scr.url != value:
+                    if (scr.url != value) or (scr.subdirectory!=subdirectory):
                         self.info("updating resource %s" % kind)
                         scr.url = value
+                        scr.subdirectory = subdirectory
                         scr.save()
                 else:
                     self.info("adding resource %s" % kind)
-                    scr = ServiceControllerResource(service_controller=obj, name=name, kind=kind, format=format, url=value)
+                    scr = ServiceControllerResource(service_controller=obj, name=name, kind=kind, format=format, url=value, subdirectory=subdirectory)
                     scr.save()
 
     def postprocess(self, obj):
         # allow these common resource to be specified directly by the ServiceController tosca object
         self.postprocess_resource_prop(obj, "models", "python")
         self.postprocess_resource_prop(obj, "admin", "python")
+        self.postprocess_resource_prop(obj, "admin_template", "raw")
         self.postprocess_resource_prop(obj, "tosca_custom_types", "yaml")
         self.postprocess_resource_prop(obj, "tosca_resource", "python")
         self.postprocess_resource_prop(obj, "synchronizer", "manifest")
diff --git a/xos/tosca/resources/vbngservice.py b/xos/tosca/resources/vbngservice.py
deleted file mode 100644
index 28d4a1d..0000000
--- a/xos/tosca/resources/vbngservice.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import os
-import pdb
-import sys
-import tempfile
-sys.path.append("/opt/tosca")
-from translator.toscalib.tosca_template import ToscaTemplate
-
-from services.cord.models import VBNGService
-
-from service import XOSService
-
-class XOSVBGNService(XOSService):
-    provides = "tosca.nodes.VBNGService"
-    xos_model = VBNGService
-    copyin_props = ["view_url", "icon_url", "enabled", "published", "public_key", "versionNumber", "vbng_url"]
-
diff --git a/xos/tosca/resources/xosmodel.py b/xos/tosca/resources/xosmodel.py
index 188bb4f..b397686 100644
--- a/xos/tosca/resources/xosmodel.py
+++ b/xos/tosca/resources/xosmodel.py
@@ -12,7 +12,7 @@
 class XOSXOS(XOSResource):
     provides = "tosca.nodes.XOS"
     xos_model = XOS
-    copyin_props = ["ui_port", "bootstrap_ui_port", "docker_project_name", "enable_build"]
+    copyin_props = ["ui_port", "bootstrap_ui_port", "docker_project_name", "enable_build", "frontend_only"]
 
 class XOSVolume(XOSResource):
     provides = "tosca.nodes.XOSVolume"
diff --git a/xos/xos/settings.py b/xos/xos/settings.py
index 9f20937..417caa0 100644
--- a/xos/xos/settings.py
+++ b/xos/xos/settings.py
@@ -182,16 +182,15 @@
     'django_extensions',
     'core',
     'services.hpc',
-    'services.cord',
     'services.mcord',
-    'services.onos',
+#    'services.onos',
     'services.ceilometer',
     'services.requestrouter',
     'services.syndicate_storage',
     'services.openvpn',
-    'services.vtr',
+#    'services.vtr',
     'services.vrouter',
-    'services.vtn',
+#    'services.vtn',
     'services.fabric',
     'geoposition',
     'rest_framework_swagger',