From 660a58aa232d250480dce53b64880482837d3160 Mon Sep 17 00:00:00 2001 From: Tim Van Steenburgh Date: Fri, 7 Oct 2016 12:52:53 -0400 Subject: [PATCH] Minor cleanups. Added todo list of next work. --- README.md | 7 +++++- TODO | 28 ++++++++++++++++++++++++ examples/allwatcher.py | 18 +++++++++++----- examples/future.py | 48 ++++++++++++++++++++++++++++++++++++++++++ examples/relate.py | 7 +++++- 5 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 TODO create mode 100644 examples/future.py diff --git a/README.md b/README.md index 56508fb..37ec461 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,11 @@ See the `examples/` directory for some simple working examples. ## Simple bootstrap/deploy ```python +""" +This doesn't work yet! It's an example of what usage might +look like in the future. + +""" from juju import Juju juju = Juju() @@ -51,7 +56,7 @@ model = controller.get_model('default') # We might want an async and blocking version of deploy()? model.deploy('mediawiki-single') -mediawiki = model.get_service('mediawiki') +mediawiki = model.get_application('mediawiki') mediawiki.expose() ``` diff --git a/TODO b/TODO new file mode 100644 index 0000000..394b228 --- /dev/null +++ b/TODO @@ -0,0 +1,28 @@ +TODO +==== + +Model as state history of immutable objects +------------------------------------------- + +1. Model gets delta from AllWatcher +2. Entity type+id in the delta uniquely identifies an entity in the model +3. The model keeps a history deque for each of these entities +4. The new delta is appended to the deque for this entity +5. When a new python object is created for this entitiy, it: + a. Registers an observer with the model so it'll get change callbacks + b. Gets its state from a pointer back to the last item in the model's + history deque for this entity + c. Has a previous() method that returns a copy of the object at its previous + frame of history (or None if no previous history exists). This object + would be disconnected (would not receive live updates from the model). + + +Make model-changing methods (like deploy()) return the appropriate object +------------------------------------------------------------------------- +For objects being added (newly created), this will require that the method +doesn't return until the AllWatcher returns a delta containing an id for +the newly created thing. + + +Add a LogWatcher coroutine that yields from debug-log api +--------------------------------------------------------- diff --git a/examples/allwatcher.py b/examples/allwatcher.py index 3f5ea06..ecd6e82 100644 --- a/examples/allwatcher.py +++ b/examples/allwatcher.py @@ -1,15 +1,19 @@ +""" +This example: + +1. Connects to the current model +2. Starts an AllWatcher +3. Prints all changes received from the AllWatcher +4. Runs forever (kill with Ctrl-C) + +""" import asyncio import logging -logging.basicConfig(level=logging.DEBUG) from juju.client.connection import Connection from juju.client import watcher -loop = asyncio.get_event_loop() -conn = loop.run_until_complete(Connection.connect_current()) - - async def watch(): allwatcher = watcher.AllWatcher() allwatcher.connect(conn) @@ -18,4 +22,8 @@ async def watch(): for delta in change.deltas: print(delta.deltas) + +logging.basicConfig(level=logging.DEBUG) +loop = asyncio.get_event_loop() +conn = loop.run_until_complete(Connection.connect_current()) loop.run_until_complete(watch()) diff --git a/examples/future.py b/examples/future.py new file mode 100644 index 0000000..dd3d04b --- /dev/null +++ b/examples/future.py @@ -0,0 +1,48 @@ +""" +This example doesn't work - it demonstrates features that don't exist yet. + +""" +import asyncio +import logging + +from juju.model import Model + + +async def run(): + model = Model() + await model.connect_current() + await model.reset(force=True) + + goal_state = Model.from_yaml('bundle-like-thing') + ubuntu_app = await model.deploy( + 'ubuntu-0', + service_name='ubuntu', + series='trusty', + channel='stable', + ) + ubuntu_app.on_unit_added(callback=lambda unit: True) + + await model.deploy( + 'nrpe-11', + service_name='nrpe', + series='trusty', + channel='stable', + num_units=0, + ) + await model.add_relation( + 'ubuntu', + 'nrpe', + ) + + result, ok = await model.block_until( + lambda: model.matches(goal_state), + timeout=600 + ) + + +logging.basicConfig(level=logging.DEBUG) +ws_logger = logging.getLogger('websockets.protocol') +ws_logger.setLevel(logging.INFO) +loop = asyncio.get_event_loop() +loop.create_task(run()) +loop.run_forever() diff --git a/examples/relate.py b/examples/relate.py index a8e39a0..288d58f 100644 --- a/examples/relate.py +++ b/examples/relate.py @@ -1,5 +1,10 @@ """ -Deploy two charms and relate them. +This example: + +1. Connects to the current model +2. Resets it +3. Deploys two charms and relates them +4. Waits for units to be idle, then exits """ import asyncio -- 2.25.1