OFAgent now has suicidal tendencies.

If OFAgent cannot find voltha-grpc it kills itself only to be restarted
by docker, this will continue until it is happy. Similarly, if voltha
goes away ofagent will kill itself until voltha comes back

Change-Id: Ib2a2cbf5ed438f8bd40f80a4543bd80f065461f1
diff --git a/compose/docker-compose-system-test.yml b/compose/docker-compose-system-test.yml
index 27bf8be..344f6f9 100644
--- a/compose/docker-compose-system-test.yml
+++ b/compose/docker-compose-system-test.yml
@@ -199,6 +199,7 @@
     - fluentd
     volumes:
     - "/var/run/docker.sock:/tmp/docker.sock"
+    restart: unless-stopped
 
   #
   # Netconf server instance(s)
diff --git a/docker/Dockerfile.ofagent b/docker/Dockerfile.ofagent
index e9a4b84..b5d49f0 100644
--- a/docker/Dockerfile.ofagent
+++ b/docker/Dockerfile.ofagent
@@ -30,6 +30,7 @@
     wget http://ftp.us.debian.org/debian/pool/main/p/protobuf/libprotobuf-dev_3.0.0-9_amd64.deb && \
     wget http://ftp.us.debian.org/debian/pool/main/p/protobuf/libprotobuf10_3.0.0-9_amd64.deb && \
     wget http://ftp.us.debian.org/debian/pool/main/p/protobuf/protobuf-compiler_3.0.0-9_amd64.deb && \
+    wget https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
     dpkg -i *.deb && \
     protoc --version && \
     rm -f *.deb
@@ -40,5 +41,7 @@
 COPY common /ofagent/common
 COPY ofagent /ofagent/ofagent
 
+ENTRYPOINT ["/usr/bin/dumb-init", "--"]
+
 # Exposing process and default entry point
-CMD ["python", "ofagent/ofagent/main.py"]
+CMD ["dumb-init", "python", "ofagent/ofagent/main.py"]
diff --git a/docker/Dockerfile.onos b/docker/Dockerfile.onos
index 4974e1e..eafa892 100644
--- a/docker/Dockerfile.onos
+++ b/docker/Dockerfile.onos
@@ -8,7 +8,7 @@
 ENV AUX=$APPS/aux
 
 RUN apt-get update && apt-get install -y git maven unzip 
-RUN git config --global http.sslverify false &&\
+RUN git config --global http.sslverify false && \
     git clone https://alshabibi@bitbucket.org/alshabibi/onos-apps.git
     
 RUN cd $ONOS/onos-apps/apps && mvn clean install
diff --git a/ofagent/connection_mgr.py b/ofagent/connection_mgr.py
index 71318af..6182b90 100644
--- a/ofagent/connection_mgr.py
+++ b/ofagent/connection_mgr.py
@@ -13,6 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+import os
 
 import sys
 
@@ -99,7 +100,9 @@
             except Exception as e:
                 log.error('Failure to locate {} service from '
                                'consul {}:'.format(endpoint, repr(e)))
-                return
+                log.error('Committing suicide...')
+                # Committing suicide in order to let docker restart ofagent
+                os.system("kill -15 {}".format(os.getpid()))
         if ip_port_endpoint:
             host, port = ip_port_endpoint.split(':', 2)
             return host, int(port)
diff --git a/ofagent/grpc_client.py b/ofagent/grpc_client.py
index d1b78bd..ccdb98b 100644
--- a/ofagent/grpc_client.py
+++ b/ofagent/grpc_client.py
@@ -18,6 +18,7 @@
 The gRPC client layer for the OpenFlow agent
 """
 from Queue import Queue, Empty
+import os
 
 from grpc import StatusCode
 from grpc._channel import _Rendezvous
@@ -77,7 +78,11 @@
 
         def stream_packets_out():
             generator = packet_generator()
-            self.local_stub.StreamPacketsOut(generator)
+            try:
+                self.local_stub.StreamPacketsOut(generator)
+            except _Rendezvous, e:
+                if e.code() == StatusCode.UNAVAILABLE:
+                    os.system("kill -15 {}".format(os.getpid()))
 
         reactor.callInThread(stream_packets_out)
 
@@ -86,12 +91,16 @@
         def receive_packet_in_stream():
             streaming_rpc_method = self.local_stub.ReceivePacketsIn
             iterator = streaming_rpc_method(empty_pb2.Empty())
-            for packet_in in iterator:
-                reactor.callFromThread(self.packet_in_queue.put,
-                                       packet_in)
-                log.debug('enqued-packet-in',
-                          packet_in=packet_in,
-                          queue_len=len(self.packet_in_queue.pending))
+            try:
+                for packet_in in iterator:
+                    reactor.callFromThread(self.packet_in_queue.put,
+                                           packet_in)
+                    log.debug('enqued-packet-in',
+                              packet_in=packet_in,
+                              queue_len=len(self.packet_in_queue.pending))
+            except _Rendezvous, e:
+                if e.code() == StatusCode.UNAVAILABLE:
+                    os.system("kill -15 {}".format(os.getpid()))
 
         reactor.callInThread(receive_packet_in_stream)
 
@@ -100,11 +109,15 @@
         def receive_change_events():
             streaming_rpc_method = self.local_stub.ReceiveChangeEvents
             iterator = streaming_rpc_method(empty_pb2.Empty())
-            for event in iterator:
-                reactor.callFromThread(self.change_event_queue.put, event)
-                log.debug('enqued-change-event',
-                          change_event=event,
-                          queue_len=len(self.change_event_queue.pending))
+            try:
+                for event in iterator:
+                    reactor.callFromThread(self.change_event_queue.put, event)
+                    log.debug('enqued-change-event',
+                              change_event=event,
+                              queue_len=len(self.change_event_queue.pending))
+            except _Rendezvous, e:
+                if e.code() == StatusCode.UNAVAILABLE:
+                    os.system("kill -15 {}".format(os.getpid()))
 
         reactor.callInThread(receive_change_events)