New N2VC interface + updated libjuju

This commit introduces the Python3 N2VC module, which acts as a standard
interface to the VCA.

The goal of this is to provide a common way for modules to interface
with the VCA.

- Updated libjuju from 0.6.1 to 0.7.3

Signed-off-by: Adam Israel <adam.israel@canonical.com>
Change-Id: Ide70fb5ae5797eb6486de24653dc09a23f9c009e
diff --git a/modules/libjuju/juju/utils.py b/modules/libjuju/juju/utils.py
index 1d9bc1c..3565fd6 100644
--- a/modules/libjuju/juju/utils.py
+++ b/modules/libjuju/juju/utils.py
@@ -46,6 +46,7 @@
     can be passed on to a model.
 
     '''
+    loop = loop or asyncio.get_event_loop()
     return await loop.run_in_executor(None, _read_ssh_key)
 
 
@@ -71,6 +72,16 @@
             await queue.put(value)
 
 
+async def block_until(*conditions, timeout=None, wait_period=0.5, loop=None):
+    """Return only after all conditions are true.
+
+    """
+    async def _block():
+        while not all(c() for c in conditions):
+            await asyncio.sleep(wait_period, loop=loop)
+    await asyncio.wait_for(_block(), timeout, loop=loop)
+
+
 async def run_with_interrupt(task, event, loop=None):
     """
     Awaits a task while allowing it to be interrupted by an `asyncio.Event`.
@@ -91,6 +102,10 @@
                                        return_when=asyncio.FIRST_COMPLETED)
     for f in pending:
         f.cancel()
+    exception = [f.exception() for f in done
+                 if f is not event_task and f.exception()]
+    if exception:
+        raise exception[0]
     result = [f.result() for f in done if f is not event_task]
     if result:
         return result[0]