plumb through container-in-VM to synchronizer
diff --git a/xos/openstack_observer/steps/sync_container.py b/xos/openstack_observer/steps/sync_container.py
index 3a8375d..915ef3d 100644
--- a/xos/openstack_observer/steps/sync_container.py
+++ b/xos/openstack_observer/steps/sync_container.py
@@ -29,7 +29,7 @@
 
     def fetch_pending(self, deletion=False):
         objs = super(SyncContainer, self).fetch_pending(deletion)
-        objs = [x for x in objs if x.isolation=="container"]
+        objs = [x for x in objs if x.isolation in ["container", "container_vm"]]
         return objs
 
     def get_node(self,o):
@@ -56,12 +56,20 @@
             pd["mac"] = port.mac
             pd["ip"] = port.ip
 
-            instance_port = self.get_instance_port(port)
-            if not instance_port:
-                raise Exception("No instance on slice for port on network %s" % port.network.name)
+            if o.isolation == "container":
+                # container on bare metal
+                instance_port = self.get_instance_port(port)
+                if not instance_port:
+                    raise Exception("No instance on slice for port on network %s" % port.network.name)
 
-            pd["snoop_instance_mac"] = instance_port.mac
-            pd["snoop_instance_id"] = instance_port.instance.instance_id
+                pd["snoop_instance_mac"] = instance_port.mac
+                pd["snoop_instance_id"] = instance_port.instance.instance_id
+                pd["src_device"] = ""
+            else:
+                # container in VM
+                pd["snoop_instance_mac"] = ""
+                pd["snoop_instance_id"] = ""
+                pd["src_device"] = "eth%d" % i
 
             ports.append(pd)
 
@@ -72,13 +80,13 @@
     def get_extra_attributes(self, o):
         fields={}
         fields["ansible_tag"] = "container-%s" % str(o.id)
-        fields["baremetal_ssh"] = True
-        fields["instance_name"] = "rootcontext"
         fields["container_name"] = "%s-%s" % (o.slice.name, str(o.id))
         fields["docker_image"] = o.image.name
-        fields["username"] = "root"
         fields["ports"] = self.get_ports(o)
-        fields["volumes"] = [x.strip() for x in o.volumes.split(",")]
+        if o.volumes:
+            fields["volumes"] = [x.strip() for x in o.volumes.split(",")]
+        else:
+            fields["volumes"] = ""
         return fields
 
     def sync_fields(self, o, fields):
@@ -87,17 +95,39 @@
     def sync_record(self, o):
         logger.info("sync'ing object %s" % str(o))
 
-        node = self.get_node(o)
-        node_key_name = self.get_node_key(node)
+        if o.isolation=="container":
+            # container on bare metal
+            node = self.get_node(o)
+            key_name = self.get_node_key(node)
+            hostname = node.name
+            fields = { "hostname": hostname,
+                       "baremetal_ssh": True,
+                       "instance_name": "rootcontext",
+                       "username": "root",
+                     }
+        else:
+            # container in a VM
+            if not o.parent:
+                raise Exception("Container-in-VM has no parent")
+            if not o.parent.instance_id:
+                raise Exception("Container-in-VM parent is not yet instantiated")
+            if not o.parent.slice.service:
+                raise Exception("Container-in-VM parent has no service")
+            if not o.parent.slice.service.private_key_fn:
+                raise Exception("Container-in-VM parent service has no private_key_fn")
+            key_name = o.parent.slice.service.private_key_fn
+            fields = { "hostname": o.parent.node.name,
+                       "instance_name": o.parent.name,
+                       "instance_id": o.parent.instance_id,
+                       "username": "ubuntu",
+                       "nat_ip": o.parent.get_ssh_ip() }
 
-        if not os.path.exists(node_key_name):
+        if not os.path.exists(key_name):
             raise Exception("Node key %s does not exist" % node_key_name)
 
-        node_key = file(node_key_name).read()
+        key = file(key_name).read()
 
-        fields = { "hostname": node.name,
-                   "private_key": node_key,
-                 }
+        fields["private_key"] = key
 
         # If 'o' defines a 'sync_attributes' list, then we'll copy those
         # attributes into the Ansible recipe's field list automatically.
diff --git a/xos/openstack_observer/steps/sync_container.yaml b/xos/openstack_observer/steps/sync_container.yaml
index e005e58..4eac2a1 100644
--- a/xos/openstack_observer/steps/sync_container.yaml
+++ b/xos/openstack_observer/steps/sync_container.yaml
@@ -15,6 +15,7 @@
          ip: {{ port.ip }}
          snoop_instance_mac: {{ port.snoop_instance_mac }}
          snoop_instance_id: {{ port.snoop_instance_id }}
+         src_device: {{ port.src_device }}
     {% endfor %}
     volumes:
     {% for volume in volumes %}
@@ -78,6 +79,10 @@
 #      state: running
 #      image: {{ docker_image }}
 
+  - name: check if systemd is installed
+    stat: path=/usr/bin/systemctl
+    register: systemctl
+
   - name: container upstart
     template: src=/opt/xos/openstack_observer/templates/container.conf.j2 dest=/etc/init/container-{{ container_name }}.conf
 
@@ -89,6 +94,7 @@
 
   - name: restart systemd
     shell: systemctl daemon-reload
+    when: systemctl.stat.exists == True
 
   - name: Make sure container is running
     service: name=container-{{ container_name }} state=started
diff --git a/xos/openstack_observer/templates/start-container.sh.j2 b/xos/openstack_observer/templates/start-container.sh.j2
index 86491eb..967578d 100644
--- a/xos/openstack_observer/templates/start-container.sh.j2
+++ b/xos/openstack_observer/templates/start-container.sh.j2
@@ -25,6 +25,11 @@
 
 {% if ports %}
 {% for port in ports %}
+{% if port.src_device %}
+# container-in-VM
+docker exec $CONTAINER ifconfig {{ port.src_device }} >> /dev/null || pipework {{ port.src_device }} -i {{ port.device }} $CONTAINER {{ port.ip }}/24 {{ port.mac }}
+{% else %}
+# container-on-metal
 IP="{{ port.ip }}"
 MAC="{{ port.mac }}"
 DEVICE="{{ port.device }}"

@@ -33,7 +38,7 @@
 INSTANCE_TAP=`virsh domiflist $INSTANCE_ID | grep -i $INSTANCE_MAC | awk '{print $1}'`
 INSTANCE_TAP=${INSTANCE_TAP:3}
 VLAN_ID=`ovs-vsctl show | grep -i -A 1 port.*$INSTANCE_TAP | grep -i tag | awk '{print $2}'`
-TAP="con`echo $CONTAINER_$DEVICE|md5sum|awk '{print $1}'`"
+TAP="con`echo ${CONTAINER}_$DEVICE|md5sum|awk '{print $1}'`"
 TAP=${TAP:0:12}
 echo im=$INSTANCE_MAC ii=$INSTANCE_ID it=$INSTANCE_TAP vlan=$VLAN_ID tap=$TAP con=$CONTAINER dev=$DEVICE mac=$MAC
 ovs-vsctl show | grep -i $TAP
@@ -45,6 +50,7 @@
 fi
 
 docker exec $CONTAINER ifconfig $DEVICE >> /dev/null || pipework $TAP -i $DEVICE $CONTAINER $IP/24 $MAC
+{% endif %}
 {% endfor %}
 {% endif %}