Merge branch 'master' of github.com:open-cloud/xos
diff --git a/xos/configurations/cord-pod/cdn/cmi.yaml b/xos/configurations/cord-pod/cdn/cmi.yaml
index 3876de4..a2edd9e 100644
--- a/xos/configurations/cord-pod/cdn/cmi.yaml
+++ b/xos/configurations/cord-pod/cdn/cmi.yaml
@@ -4,19 +4,23 @@
   user: root
   vars:
     eth_device: eth0
+    eth_mac: 02:42:CF:8D:C0:82
     cmi_password: XOScdn123$
     cmi_hostname: xos-cloudlab-cmi-vtn.opencloud.us
     cmi_dns: 8.8.8.8
     cdn_site: CoBlitz Test
     cdn_short_name: cobtest
     cdn_name: CoBlitz
-    gateway_ip: 10.124.0.1
-    gateway_mac: 00:8c:fa:5b:09:d8
+#    gateway_ip: 10.124.0.1
+#    gateway_mac: 00:8c:fa:5b:09:d8
+    gateway_ip: 207.141.192.129
+    gateway_mac: a4:23:05:45:56:79
     node_hostname: xos-cloudlab-node1-vtn.opencloud.us
   tasks:
   - name: fix the networking
     shell: "{{ item }}"
     with_items:
+      - ifconfig {{ eth_device }} hw ether {{ eth_mac }}
       - ip route del default || true
       - ip route add default via {{ gateway_ip }}
       - arp -s {{ gateway_ip }} {{ gateway_mac }}
diff --git a/xos/core/xoslib/methods/truckroll.py b/xos/core/xoslib/methods/truckroll.py
index b3143d9..917a676 100644
--- a/xos/core/xoslib/methods/truckroll.py
+++ b/xos/core/xoslib/methods/truckroll.py
@@ -32,6 +32,7 @@
         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")
@@ -39,7 +40,7 @@
 
         class Meta:
             model = VTRTenant
-            fields = ('humanReadableName', 'id', 'provider_service', 'target_id', 'scope', 'test', 'argument', 'result', 'is_synced', 'backend_status' )
+            fields = ('humanReadableName', 'id', 'provider_service', 'target_id', 'scope', 'test', 'argument', 'result', 'result_code', 'is_synced', 'backend_status' )
 
         def getHumanReadableName(self, obj):
             return obj.__unicode__()
diff --git a/xos/core/xoslib/methods/volttenant.py b/xos/core/xoslib/methods/volttenant.py
index 3adb995..05cd7e8 100644
--- a/xos/core/xoslib/methods/volttenant.py
+++ b/xos/core/xoslib/methods/volttenant.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
+from services.cord.models import VOLTTenant, VOLTService, CordSubscriberRoot
 from plus import PlusSerializerMixin
 from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
 
@@ -26,10 +26,10 @@
 class VOLTTenantIdSerializer(serializers.ModelSerializer, PlusSerializerMixin):
         id = ReadOnlyField()
         service_specific_id = serializers.CharField()
-        #vlan_id = serializers.CharField()
         s_tag = serializers.CharField()
         c_tag = serializers.CharField()
         provider_service = serializers.PrimaryKeyRelatedField(queryset=VOLTService.get_service_objects().all(), default=get_default_volt_service)
+        subscriber_root = serializers.PrimaryKeyRelatedField(queryset=CordSubscriberRoot.get_tenant_objects().all(), required=False)
 
         humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
 
@@ -37,7 +37,7 @@
 
         class Meta:
             model = VOLTTenant
-            fields = ('humanReadableName', 'id', 'provider_service', 'service_specific_id', 's_tag', 'c_tag', 'computeNodeName' )
+            fields = ('humanReadableName', 'id', 'provider_service', 'service_specific_id', 's_tag', 'c_tag', 'computeNodeName', 'subscriber_root' )
 
         def getHumanReadableName(self, obj):
             return obj.__unicode__()
diff --git a/xos/services/vtr/admin.py b/xos/services/vtr/admin.py
index 0bdd475..5015fc8 100644
--- a/xos/services/vtr/admin.py
+++ b/xos/services/vtr/admin.py
@@ -52,6 +52,7 @@
     test = forms.ChoiceField(choices=VTRTenant.TEST_CHOICES, required=True)
     scope = forms.ChoiceField(choices=VTRTenant.SCOPE_CHOICES, required=True)
     argument = forms.CharField(required=False)
+    result_code = forms.CharField(required=False)
     result = forms.CharField(required=False, widget=forms.Textarea(attrs={'rows': 10, 'cols': 80, 'class': 'input-xxlarge'}))
     target = forms.ModelChoiceField(queryset=CordSubscriberRoot.objects.all())
 
@@ -66,8 +67,10 @@
             self.fields['scope'].initial = self.instance.scope
             if (self.instance.enacted is not None) and (self.instance.enacted >= self.instance.updated):
                 self.fields['result'].initial = self.instance.result
+                self.fields['result_code'].initial = self.instance.result_code
             else:
                 self.fields['result'].initial = ""
+                self.fields['result_code'].initial= ""
         if (not self.instance) or (not self.instance.pk):
             # default fields for an 'add' form
             self.fields['kind'].initial = VTR_KIND
@@ -80,6 +83,7 @@
         self.instance.argument = self.cleaned_data.get("argument")
         self.instance.target = self.cleaned_data.get("target")
         self.instance.result = self.cleaned_data.get("result")
+        self.instance.result_code = self.cleaned_data.get("result_code")
         self.instance.scope = self.cleaned_data.get("scope")
         return super(VTRTenantForm, self).save(commit=commit)
 
@@ -90,7 +94,7 @@
     list_display = ('backend_status_icon', 'id', 'target', 'test', 'argument' )
     list_display_links = ('backend_status_icon', 'id')
     fieldsets = [ (None, {'fields': ['backend_status_text', 'kind', 'provider_service', # 'subscriber_root', 'service_specific_id', 'service_specific_attribute',
-                                     'target', 'scope', 'test', 'argument', 'is_synced', 'result'],
+                                     'target', 'scope', 'test', 'argument', 'is_synced', 'result_code', 'result'],
                           'classes':['suit-tab suit-tab-general']})]
     readonly_fields = ('backend_status_text', 'service_specific_attribute', 'is_synced')
     form = VTRTenantForm
diff --git a/xos/services/vtr/models.py b/xos/services/vtr/models.py
index d3e6010..31c26c4 100644
--- a/xos/services/vtr/models.py
+++ b/xos/services/vtr/models.py
@@ -44,6 +44,7 @@
     simple_attributes = ( ("test", None),
                           ("argument", None),
                           ("result", None),
+                          ("result_code", None),
                           ("target_id", None),
                           ("scope", "container") )
 
diff --git a/xos/synchronizers/vcpe/steps/sync_vcpetenant_vtn.yaml b/xos/synchronizers/vcpe/steps/sync_vcpetenant_vtn.yaml
index 66deed5..f575664 100644
--- a/xos/synchronizers/vcpe/steps/sync_vcpetenant_vtn.yaml
+++ b/xos/synchronizers/vcpe/steps/sync_vcpetenant_vtn.yaml
@@ -245,6 +245,10 @@
     copy: src=/opt/xos/synchronizers/vcpe/files/etc/service/ dest=/var/container_volumes/{{ container_name }}/etc/service/ owner=root group=root
     when: status != "enabled"
 
+  - name: make webserver script executable
+    file: path=/var/container_volumes/{{ container_name }}/etc/service/message/run mode=0755
+    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
     when: status != "enabled"
diff --git a/xos/synchronizers/vtr/steps/sync_vtrtenant.py b/xos/synchronizers/vtr/steps/sync_vtrtenant.py
index d58b867..d2ec209 100644
--- a/xos/synchronizers/vtr/steps/sync_vtrtenant.py
+++ b/xos/synchronizers/vtr/steps/sync_vtrtenant.py
@@ -108,7 +108,8 @@
                 "container_name": "vcpe-%s-%s" % (s_tags[0], c_tags[0]),
                 "dns_servers": [x.strip() for x in vcpe_service.dns_servers.split(",")],
 
-                "result_fn": "%s-vcpe-%s-%s" % (o.test, s_tags[0], c_tags[0]) }
+                "result_fn": "%s-vcpe-%s-%s" % (o.test, s_tags[0], c_tags[0]),
+                "resultcode_fn": "code-%s-vcpe-%s-%s" % (o.test, s_tags[0], c_tags[0]) }
 
         # add in the sync_attributes that come from the SubscriberRoot object
 
@@ -133,11 +134,18 @@
         if os.path.exists(result_fn):
             os.remove(result_fn)
 
+        resultcode_fn = os.path.join("/opt/xos/synchronizers/vtr/result", fields["resultcode_fn"])
+        if os.path.exists(resultcode_fn):
+            os.remove(resultcode_fn)
+
         super(SyncVTRTenant, self).run_playbook(o, fields)
 
         if os.path.exists(result_fn):
             o.result = open(result_fn).read()
 
+        if os.path.exists(resultcode_fn):
+            o.result_code = open(resultcode_fn).read()
+
 
     def delete_record(self, m):
         pass
diff --git a/xos/synchronizers/vtr/steps/sync_vtrtenant.yaml b/xos/synchronizers/vtr/steps/sync_vtrtenant.yaml
index 2a257f3..35d9032 100644
--- a/xos/synchronizers/vtr/steps/sync_vtrtenant.yaml
+++ b/xos/synchronizers/vtr/steps/sync_vtrtenant.yaml
@@ -16,7 +16,8 @@
       scope: {{ scope }}
       test: {{ test }}
       argument: {{ argument }}
-      result_file: {{ result_fn }}
+      result_fn: {{ result_fn }}
+      resultcode_fn: {{ resultcode_fn }}
 
 
   tasks:
@@ -35,6 +36,11 @@
   - name: Send the pings from VM
     shell: ping -c 10 {{ argument }} 2>&1 > /tmp/{{ result_fn }}
     ignore_errors: yes
+    register: vm_ping_result
+    when: (scope=="vm") and (test=="ping")
+
+  - name: Store VM ping resultcode to file
+    shell: echo "{{ '{{' }} vm_ping_result.rc {{ '}}' }}" > /tmp/{{ resultcode_fn }}
     when: (scope=="vm") and (test=="ping")
 
   - name: Install traceroute
@@ -44,11 +50,21 @@
   - name: Send traceroute from VM
     shell: traceroute {{ argument }} 2>&1 > /tmp/{{ result_fn }}
     ignore_errors: yes
+    register: vm_traceroute_result
+    when: (scope=="vm") and (test=="traceroute")
+
+  - name: Store VM traceroute resultcode to file
+    shell: echo "{{ '{{' }} vm_traceroute_result.rc {{ '}}' }}" > /tmp/{{ resultcode_fn }}
     when: (scope=="vm") and (test=="traceroute")
 
   - name: Run tcpdump for 30 seconds on VM
     shell: /root/run_tcpdump.sh {{ argument }} 2>&1 > /tmp/{{ result_fn }}
     ignore_errors: yes
+    register: vm_tcpdump_result
+    when: (scope=="vm") and (test=="tcpdump")
+
+  - name: Store VM tcpdump resultcode to file
+    shell: echo "{{ '{{' }} vm_tcpdump_result.rc {{ '}}' }}" > /tmp/{{ resultcode_fn }}
     when: (scope=="vm") and (test=="tcpdump")
 
 # ------------------
@@ -58,6 +74,11 @@
   - name: Send the pings from Container
     shell: docker exec {{ container_name }} ping -c 10 {{ argument }} 2>&1 > /tmp/{{ result_fn }}
     ignore_errors: yes
+    register: ctr_ping_result
+    when: (scope=="container") and (test=="ping")
+
+  - name: Store ctr ping resultcode to file
+    shell: echo "{{ '{{' }} ctr_ping_result.rc {{ '}}' }}" > /tmp/{{ resultcode_fn }}
     when: (scope=="container") and (test=="ping")
 
   - name: Install traceroute into Container
@@ -67,6 +88,11 @@
   - name: Send traceroute from Container
     shell: docker exec {{ container_name }} traceroute {{ argument }} 2>&1 > /tmp/{{ result_fn }}
     ignore_errors: yes
+    register: ctr_traceroute_result
+    when: (scope=="container") and (test=="traceroute")
+
+  - name: Store ctr traceroute resultcode to file
+    shell: echo "{{ '{{' }} ctr_traceroute_result.rc {{ '}}' }}" > /tmp/{{ resultcode_fn }}
     when: (scope=="container") and (test=="traceroute")
 
   - name: Copy run_tcpdump.sh to container
@@ -76,15 +102,22 @@
   - name: Run tcpdump for 30 seconds from Container
     shell: docker exec {{ container_name }} /root/run_tcpdump.sh {{ argument }} 2>&1 > /tmp/{{ result_fn }}
     ignore_errors: yes
+    register: diagresult
+    when: (scope=="container") and (test=="tcpdump")
+
+  - name: Store ctr tcpdump resultcode to file
+    shell: echo "{{ '{{' }} ctr_tcpdump_result.rc {{ '}}' }}" > /tmp/{{ resultcode_fn }}
     when: (scope=="container") and (test=="tcpdump")
 
 # ------------------
 # scope == *
 # ------------------
-
   - name: Fetch the result
     fetch: src=/tmp/{{ result_fn }} dest=/opt/xos/synchronizers/vtr/result/{{ result_fn }} flat=yes
 
+  - name: Fetch the resultcode
+    fetch: src=/tmp/{{ resultcode_fn }} dest=/opt/xos/synchronizers/vtr/result/{{ resultcode_fn }} flat=yes
+