Merge branch 'master' of https://github.com/open-cloud/xos
diff --git a/xos/configurations/common/Dockerfile.common b/xos/configurations/common/Dockerfile.common
index 5329142..03b479a 100644
--- a/xos/configurations/common/Dockerfile.common
+++ b/xos/configurations/common/Dockerfile.common
@@ -48,7 +48,7 @@
 RUN pip install django-ipware
 RUN pip install django-encrypted-fields
 RUN pip install python-keyczar
-RUN pip install pygraphviz
+RUN pip install pygraphviz --install-option="--include-path=/usr/include/graphviz" --install-option="--library-path=/usr/lib/graphviz/"
 RUN pip install dnslib
 
 RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python-keystoneclient
diff --git a/xos/configurations/cord/Makefile.inside b/xos/configurations/cord/Makefile.inside
index a4494dc..a4bb5f1 100644
--- a/xos/configurations/cord/Makefile.inside
+++ b/xos/configurations/cord/Makefile.inside
@@ -6,8 +6,5 @@
 	python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/common/cloudlab-nodes.yaml
 	python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/cord/cord.yaml
 
-setup_subscriber:
-	python /opt/xos/tosca/run.py padmin@vicci.org /opt/xos/configurations/cord/subscriber.yaml
-
 run_develserver:
 	cd /opt/xos; python manage.py runserver 0.0.0.0:8000 --insecure
diff --git a/xos/configurations/cord/README.md b/xos/configurations/cord/README.md
index 423f4d6..efabcb2 100644
--- a/xos/configurations/cord/README.md
+++ b/xos/configurations/cord/README.md
@@ -60,17 +60,10 @@
 1. *Slice mysite_vbng*: for running OvS with the `virtualbng` app as controller
 1. *Slice mysite_volt*: for running OvS with the `olt` app as controller
 1. *Slice mysite_clients*: a subscriber client for end-to-end testing
+1. *Slice mysite_vcpe*: runs the vCPE Docker container
 
 Once all the VMs are up and the ONOS apps are configured, XOS should be able to get an address mapping from the `virtualbng`
-ONOS app when creating a vCPE.  To test this, enter the XOS Docker container and run:
-
-```
-$ cd /opt/xos/configurations/cord/
-$ make -f Makefile.inside setup_subscriber
-```
-
-This will run the TOSCA engine with `subscriber.yaml`.  After a bit, a new VM should be created in slice *mysite_vcpe* running
-the vCPE Docker container.  To verify that it has received an IP address mapping, look at the **Routeable subnet:** field in 
+ONOS app for the vCPE. To verify that it has received an IP address mapping, look at the **Routeable subnet:** field in 
 the appropriate *Vbng tenant* object in XOS.  It should contain an IP address in the 10.254.0.0/24 subnet.
 
 ## How to log into ONOS
diff --git a/xos/configurations/cord/cord.yaml b/xos/configurations/cord/cord.yaml
index 5b48398..9d850b2 100644
--- a/xos/configurations/cord/cord.yaml
+++ b/xos/configurations/cord/cord.yaml
@@ -339,3 +339,65 @@
                 node: mysite_clients
                 relationship: tosca.relationships.MemberOfSlice
 
+    # A subscriber
+    My House:
+       type: tosca.nodes.CORDSubscriber
+       properties:
+           service_specific_id: 123
+           firewall_enable: false
+           cdn_enable: false
+           url_filter_enable: false
+           url_filter_level: R
+
+    Mom's PC:
+       type: tosca.nodes.CORDUser
+       properties:
+           mac: 010203040506
+           level: PG_13
+       requirements:
+           - household:
+               node: My House
+               relationship: tosca.relationships.SubscriberDevice
+
+    Dad's PC:
+       type: tosca.nodes.CORDUser
+       properties:
+           mac: 90E2Ba82F975
+           level: PG_13
+       requirements:
+           - household:
+               node: My House
+               relationship: tosca.relationships.SubscriberDevice
+
+    Jack's Laptop:
+       type: tosca.nodes.CORDUser
+       properties:
+           mac: 685B359D91D5
+           level: PG_13
+       requirements:
+           - household:
+               node: My House
+               relationship: tosca.relationships.SubscriberDevice
+
+    Jill's Laptop:
+       type: tosca.nodes.CORDUser
+       properties:
+           mac: 34363BC9B6A6
+           level: PG_13
+       requirements:
+           - household:
+               node: My House
+               relationship: tosca.relationships.SubscriberDevice
+
+    My Volt:
+        type: tosca.nodes.VOLTTenant
+        properties:
+            service_specific_id: 123
+            vlan_id: 432
+        requirements:
+            - provider_service:
+                node: service_volt
+                relationship: tosca.relationships.MemberOfService
+            - subscriber:
+                node: My House
+                relationship: tosca.relationships.BelongsToSubscriber
diff --git a/xos/configurations/cord/subscriber.yaml b/xos/configurations/cord/subscriber.yaml
deleted file mode 100644
index f77f4d5..0000000
--- a/xos/configurations/cord/subscriber.yaml
+++ /dev/null
@@ -1,82 +0,0 @@
-tosca_definitions_version: tosca_simple_yaml_1_0
-
-description: Set up a subscriber for CORD
-
-imports:
-   - custom_types/xos.yaml
-
-topology_template:
-  node_templates:
-
-    # These services defined in cord.yaml
-    service_volt:
-      type: tosca.nodes.Service
-
-    service_vcpe:
-      type: tosca.nodes.VCPEService
-
-    service_vbng:
-      type: tosca.nodes.VBNGService
-
-    # A subscriber
-    My House:
-       type: tosca.nodes.CORDSubscriber
-       properties:
-           service_specific_id: 123
-           firewall_enable: false
-           cdn_enable: false
-           url_filter_enable: false
-           url_filter_level: R
-
-    Mom's PC:
-       type: tosca.nodes.CORDUser
-       properties:
-           mac: 010203040506
-           level: PG_13
-       requirements:
-           - household:
-               node: My House
-               relationship: tosca.relationships.SubscriberDevice
-
-    Dad's PC:
-       type: tosca.nodes.CORDUser
-       properties:
-           mac: 90E2Ba82F975
-           level: PG_13
-       requirements:
-           - household:
-               node: My House
-               relationship: tosca.relationships.SubscriberDevice
-
-    Jack's Laptop:
-       type: tosca.nodes.CORDUser
-       properties:
-           mac: 685B359D91D5
-           level: PG_13
-       requirements:
-           - household:
-               node: My House
-               relationship: tosca.relationships.SubscriberDevice
-
-    Jill's Laptop:
-       type: tosca.nodes.CORDUser
-       properties:
-           mac: 34363BC9B6A6
-           level: PG_13
-       requirements:
-           - household:
-               node: My House
-               relationship: tosca.relationships.SubscriberDevice
-
-    My Volt:
-        type: tosca.nodes.VOLTTenant
-        properties:
-            service_specific_id: 123
-            vlan_id: 432
-        requirements:
-            - provider_service:
-                node: service_volt
-                relationship: tosca.relationships.MemberOfService
-            - subscriber:
-                node: My House
-                relationship: tosca.relationships.BelongsToSubscriber
diff --git a/xos/core/views/services.py b/xos/core/views/services.py
index 6d18c26..e11988b 100644
--- a/xos/core/views/services.py
+++ b/xos/core/views/services.py
@@ -121,14 +121,14 @@
         g.graph_attr.update(graphdir="TB")
 
         for service in Service.objects.all():
-            provided_tenants = CoarseTenant.get_tenant_objects().filter(provider_service=service)
-            subscribed_tenants = CoarseTenant.get_tenant_objects().filter(subscriber_service=service)
+            provided_tenants = Tenant.objects.filter(provider_service=service, subscriber_service__isnull=False)
+            subscribed_tenants = Tenant.objects.filter(subscriber_service=service, provider_service__isnull=False)
             if not (provided_tenants or subscribed_tenants):
                # nodes with no edges aren't interesting
                continue
             g.add_node(service.id, label=service.name)
 
-        for tenant in CoarseTenant.get_tenant_objects().all():
+        for tenant in Tenant.objects.all():
             if (not tenant.provider_service) or (not tenant.subscriber_service):
                 continue
             g.add_edge(tenant.subscriber_service.id, tenant.provider_service.id)
diff --git a/xos/observers/monitoring_channel/templates/ceilometer_proxy_server.py b/xos/observers/monitoring_channel/templates/ceilometer_proxy_server.py
index 711e996..c6be286 100644
--- a/xos/observers/monitoring_channel/templates/ceilometer_proxy_server.py
+++ b/xos/observers/monitoring_channel/templates/ceilometer_proxy_server.py
@@ -209,7 +209,7 @@
               query = make_query(tenant_id=k)
               final_query.extend(query)
               logger.debug('final query=%s',final_query)
-              results = client.samples.list(q=query)
+              results = client.samples.list(q=final_query)
               samples.extend(results)
         return json.dumps([ob._info for ob in samples])
 
@@ -235,7 +235,7 @@
               query = make_query(tenant_id=k)
               final_query.extend(query)
               logger.debug('final query=%s',final_query)
-              results = client.resources.list(q=query)
+              results = client.resources.list(q=final_query, links=1)
               resources.extend(results)
         return json.dumps([ob._info for ob in resources])
 
diff --git a/xos/observers/vcpe/steps/sync_vcpetenant.yaml b/xos/observers/vcpe/steps/sync_vcpetenant.yaml
index fac78d5..b485c0f 100644
--- a/xos/observers/vcpe/steps/sync_vcpetenant.yaml
+++ b/xos/observers/vcpe/steps/sync_vcpetenant.yaml
@@ -79,24 +79,31 @@
     copy: src=/opt/xos/observers/vcpe/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
+    shell: pgrep -f [v]cpe_stats_notifier | wc -l
+    register: cron_job_pids_count
+
+#  - name: DEBUG
+#    debug: var=cron_job_pids_count.stdout
+
   - name: make sure ~/bin exists
     file: path=~/bin state=directory owner=root group=root
+    when: cron_job_pids_count.stdout == "0"
 
   - name: Copy cron job to destination
     copy: src=/opt/xos/observers/vcpe/vcpe_stats_notifier.py
       dest=~/bin/vcpe_stats_notifier.py
+    when: cron_job_pids_count.stdout == "0"
 
   - name: install python-kombu
     apt: name=python-kombu state=present
-
-  - name: Clean any running vcpe_stats_notifier cron jobs
-    command: pkill vcpe_stats_notifier.py
-    ignore_errors: yes
+    when: cron_job_pids_count.stdout == "0"
 
   - name: Initiate vcpe_stats_notifier cron job
     command: python ~/bin/vcpe_stats_notifier.py --keystone_tenant_id={{ keystone_tenant_id }} --keystone_user_id={{ keystone_user_id }} --rabbit_user={{ rabbit_user }} --rabbit_password={{ rabbit_password }} --rabbit_host={{ rabbit_host }} --vcpeservice_rabbit_exchange='vcpeservice'
-    async: 999999999999999999
+    async: 9999999999999999
     poll: 0
+    when: cron_job_pids_count.stdout == "0"
 {% endif %}
 
   - name: vCPE upstart
diff --git a/xos/tosca/custom_types/xos.m4 b/xos/tosca/custom_types/xos.m4
index 7a94d8b..055817d 100644
--- a/xos/tosca/custom_types/xos.m4
+++ b/xos/tosca/custom_types/xos.m4
@@ -111,7 +111,7 @@
     tosca.nodes.ONOSvBNGApp:
         derived_from: tosca.nodes.Root
         description: >
-            An ONOS Application.
+            An ONOS vBNG Application.
         properties:
             xos_base_tenant_props
             dependencies:
@@ -124,6 +124,16 @@
                 type: string
                 required: false
 
+    tosca.nodes.ONOSvOLTApp:
+        derived_from: tosca.nodes.Root
+        description: >
+            An ONOS vOLT Application.
+        properties:
+            xos_base_tenant_props
+            dependencies:
+                type: string
+                required: false
+
     tosca.nodes.VCPEService:
         description: >
             CORD: The vCPE Service.
diff --git a/xos/tosca/custom_types/xos.yaml b/xos/tosca/custom_types/xos.yaml
index 9b307d6..409e86b 100644
--- a/xos/tosca/custom_types/xos.yaml
+++ b/xos/tosca/custom_types/xos.yaml
@@ -115,7 +115,7 @@
     tosca.nodes.ONOSvBNGApp:
         derived_from: tosca.nodes.Root
         description: >
-            An ONOS Application.
+            An ONOS vBNG Application.
         properties:
             kind:
                 type: string
@@ -135,6 +135,23 @@
                 type: string
                 required: false
 
+    tosca.nodes.ONOSvOLTApp:
+        derived_from: tosca.nodes.Root
+        description: >
+            An ONOS vOLT Application.
+        properties:
+            kind:
+                type: string
+                default: generic
+                description: Kind of tenant
+            service_specific_id:
+                type: string
+                required: false
+                description: Service specific ID opaque to XOS but meaningful to service
+            dependencies:
+                type: string
+                required: false
+
     tosca.nodes.VCPEService:
         description: >
             CORD: The vCPE Service.
diff --git a/xos/tosca/resources/onosapp.py b/xos/tosca/resources/onosapp.py
index 03c4eb5..111cf9a 100644
--- a/xos/tosca/resources/onosapp.py
+++ b/xos/tosca/resources/onosapp.py
@@ -12,7 +12,7 @@
 from xosresource import XOSResource
 
 class XOSONOSApp(XOSResource):
-    provides = ["tosca.nodes.ONOSApp", "tosca.nodes.ONOSvBNGApp"]
+    provides = ["tosca.nodes.ONOSApp", "tosca.nodes.ONOSvBNGApp", "tosca.nodes.ONOSvOLTApp"]
     xos_model = ONOSApp
     copyin_props = ["service_specific_id", "dependencies"]
 
diff --git a/xos/tosca/samples/onos.yaml b/xos/tosca/samples/onos.yaml
index fc6a3d5..a549515 100644
--- a/xos/tosca/samples/onos.yaml
+++ b/xos/tosca/samples/onos.yaml
@@ -56,6 +56,15 @@
                 "xosRestPort" : "9999"

             }
 
+    vOLT:
+      type: tosca.nodes.ONOSvOLTApp
+      requirements:
+          - onos_tenant:
+              node: ONOS
+              relationship: tosca.relationships.TenantOfService
+      properties:
+          dependencies: org.onosproject.olt
+
     mysite:
       type: tosca.nodes.Site