--- /dev/null
+"""
+This example:
+
+1. Creates a model on the current controller
+2. Deploys a charm to it.
+3. Attempts to ssh into the charm
+
+"""
+from juju import loop
+from juju import utils
+from juju.controller import Controller
+import asyncio
+from logging import getLogger
+
+LOG = getLogger(__name__)
+
+
+async def main():
+ controller = Controller()
+ print("Connecting to controller")
+ await controller.connect_current()
+
+ try:
+ model = await controller.add_model("quux")
+
+ print('Deploying ubuntu')
+ application = await model.deploy(
+ 'ubuntu-10',
+ application_name='ubuntu',
+ series='trusty',
+ channel='stable',
+ )
+
+ print('Waiting for active')
+ await asyncio.sleep(10)
+ await model.block_until(
+ lambda: all(unit.workload_status == 'active'
+ for unit in application.units))
+
+ print("Verifying that we can ssh into the created model")
+ ret = utils.execute_process('juju', 'ssh', 'ls /', log=LOG)
+ assert ret
+
+ print('Removing ubuntu')
+ await application.remove()
+
+ print("Destroying model")
+ await controller.destroy_model(model.info.uuid)
+
+ finally:
+ print('Disconnecting from controller')
+ await model.disconnect()
+ await controller.disconnect()
+
+
+loop.run(main())
import logging
from . import tag
+from . import utils
from .client import client
from .client import connection
from .client import watcher
region,
)
+ # Add our ssh key to the model, to work around
+ # https://bugs.launchpad.net/juju/+bug/1643076
+ try:
+ ssh_key = utils.read_ssh_key()
+ await utils.execute_process(
+ 'juju', 'add-ssh-key', '-m', model_name, ssh_key, log=log)
+ except Exception as e:
+ log.warning(
+ "Could not add ssh key to model. You will not be able "
+ "to ssh into machines in this model. "
+ "Manually running `juju add-ssh-key <key>` in the cli "
+ "may fix this problem.")
+
model = Model()
await model.connect(
self.connection.endpoint,
--- /dev/null
+import asyncio
+import os
+from pathlib import Path
+
+
+async def execute_process(*cmd, log=None):
+ '''
+ Wrapper around asyncio.create_subprocess_exec.
+
+ '''
+ p = await asyncio.create_subprocess_exec(
+ *cmd,
+ stdin=asyncio.subprocess.PIPE,
+ stdout=asyncio.subprocess.PIPE,
+ stderr=asyncio.subprocess.PIPE,
+ )
+ stdout, stderr = await p.communicate()
+ if log:
+ log.debug("Exec %s -> %d", cmd, p.returncode)
+ if stdout:
+ log.debug(stdout.decode('utf-8'))
+ if stderr:
+ log.debug(stderr.decode('utf-8'))
+ return p.returncode == 0
+
+
+def read_ssh_key():
+ '''
+ Attempt to read the local juju admin's public ssh key, so that it
+ can be passed on to a model.
+
+ '''
+ default_data_dir = Path(Path.home(), ".local", "share", "juju")
+ juju_data = os.environ.get("JUJU_DATA", default_data_dir)
+ ssh_key_path = Path(juju_data, 'ssh', 'juju_id_rsa.pub')
+ with ssh_key_path.open('r') as ssh_key_file:
+ ssh_key = ssh_key_file.readlines()[0].strip()
+ return ssh_key
+