Refactor repo to not use builds/ directory for compiled charms due to licensing confl...
authorAdam Israel <adam.israel@canonical.com>
Tue, 4 Oct 2016 15:26:03 +0000 (08:26 -0700)
committerAdam Israel <adam.israel@canonical.com>
Tue, 4 Oct 2016 16:19:13 +0000 (09:19 -0700)
Signed-off-by: Adam Israel <adam.israel@canonical.com>
61 files changed:
.gitignore
builds/VyOS-proxy/Makefile [deleted file]
builds/VyOS-proxy/README.ex [deleted file]
builds/VyOS-proxy/README.md [deleted file]
builds/VyOS-proxy/actions.yaml [deleted file]
builds/VyOS-proxy/actions/ping [deleted file]
builds/VyOS-proxy/bin/layer_option [deleted file]
builds/VyOS-proxy/config.yaml [deleted file]
builds/VyOS-proxy/copyright [deleted file]
builds/VyOS-proxy/hooks/config-changed [deleted file]
builds/VyOS-proxy/hooks/hook.template [deleted file]
builds/VyOS-proxy/hooks/install [deleted file]
builds/VyOS-proxy/hooks/leader-elected [deleted file]
builds/VyOS-proxy/hooks/leader-settings-changed [deleted file]
builds/VyOS-proxy/hooks/start [deleted file]
builds/VyOS-proxy/hooks/stop [deleted file]
builds/VyOS-proxy/hooks/update-status [deleted file]
builds/VyOS-proxy/hooks/upgrade-charm [deleted file]
builds/VyOS-proxy/icon.svg [deleted file]
builds/VyOS-proxy/layer.yaml [deleted file]
builds/VyOS-proxy/lib/charms/layer/__init__.py [deleted file]
builds/VyOS-proxy/lib/charms/layer/basic.py [deleted file]
builds/VyOS-proxy/lib/charms/layer/execd.py [deleted file]
builds/VyOS-proxy/metadata.yaml [deleted file]
builds/VyOS-proxy/reactive/__init__.py [deleted file]
builds/VyOS-proxy/reactive/vyos_proxy.py [deleted file]
builds/VyOS-proxy/requirements.txt [deleted file]
builds/VyOS-proxy/revision [deleted file]
builds/VyOS-proxy/tox.ini [deleted file]
builds/VyOS-proxy/wheelhouse/Jinja2-2.8.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/MarkupSafe-0.23.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/PyYAML-3.11.zip [deleted file]
builds/VyOS-proxy/wheelhouse/Tempita-0.5.2.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/cffi-1.7.0.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/charmhelpers-0.7.0.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/charms.reactive-0.4.4.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/cryptography-1.4.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/idna-2.1.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/netaddr-0.7.18.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/paramiko-2.0.1.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/pip-8.1.2.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/pyaml-15.8.2.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/pyasn1-0.1.9.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/pycparser-2.14.tar.gz [deleted file]
builds/VyOS-proxy/wheelhouse/setuptools-23.1.0.zip [deleted file]
builds/VyOS-proxy/wheelhouse/six-1.10.0.tar.gz [deleted file]
layers/vyos-proxy/Makefile [new file with mode: 0644]
layers/vyos-proxy/README.md [new file with mode: 0644]
layers/vyos-proxy/actions.yaml [new file with mode: 0644]
layers/vyos-proxy/actions/ping [new file with mode: 0755]
layers/vyos-proxy/config.yaml [new file with mode: 0644]
layers/vyos-proxy/copyright [new file with mode: 0644]
layers/vyos-proxy/icon.svg [new file with mode: 0644]
layers/vyos-proxy/layer.yaml [new file with mode: 0644]
layers/vyos-proxy/metadata.yaml [new file with mode: 0644]
layers/vyos-proxy/reactive/__init__.py [new file with mode: 0644]
layers/vyos-proxy/reactive/vyos_proxy.py [new file with mode: 0644]
layers/vyos-proxy/requirements.txt [new file with mode: 0644]
layers/vyos-proxy/revision [new file with mode: 0644]
layers/vyos-proxy/tox.ini [new file with mode: 0644]
layers/vyos-proxy/wheelhouse.txt [new file with mode: 0644]

index 6912fef..9421a45 100644 (file)
@@ -1 +1,2 @@
+builds/
 deps/
diff --git a/builds/VyOS-proxy/Makefile b/builds/VyOS-proxy/Makefile
deleted file mode 100644 (file)
index a1ad3a5..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/make
-
-all: lint unit_test
-
-
-.PHONY: clean
-clean:
-       @rm -rf .tox
-
-.PHONY: apt_prereqs
-apt_prereqs:
-       @# Need tox, but don't install the apt version unless we have to (don't want to conflict with pip)
-       @which tox >/dev/null || (sudo apt-get install -y python-pip && sudo pip install tox)
-
-.PHONY: lint
-lint: apt_prereqs
-       @tox --notest
-       @PATH=.tox/py34/bin:.tox/py35/bin flake8 $(wildcard hooks reactive lib unit_tests tests)
-       @charm proof
-
-.PHONY: unit_test
-unit_test: apt_prereqs
-       @echo Starting tests...
-       tox
diff --git a/builds/VyOS-proxy/README.ex b/builds/VyOS-proxy/README.ex
deleted file mode 100644 (file)
index b6816b2..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-# Overview
-
-Describe the intended usage of this charm and anything unique about how this
-charm relates to others here.
-
-This README will be displayed in the Charm Store, it should be either Markdown
-or RST. Ideal READMEs include instructions on how to use the charm, expected
-usage, and charm features that your audience might be interested in. For an
-example of a well written README check out Hadoop:
-http://jujucharms.com/charms/precise/hadoop
-
-Use this as a Markdown reference if you need help with the formatting of this
-README: http://askubuntu.com/editing-help
-
-This charm provides [service][]. Add a description here of what the service
-itself actually does.
-
-Also remember to check the [icon guidelines][] so that your charm looks good
-in the Juju GUI.
-
-# Usage
-
-Step by step instructions on using the charm:
-
-juju deploy servicename
-
-and so on. If you're providing a web service or something that the end user
-needs to go to, tell them here, especially if you're deploying a service that
-might listen to a non-default port.
-
-You can then browse to http://ip-address to configure the service.
-
-## Scale out Usage
-
-If the charm has any recommendations for running at scale, outline them in
-examples here. For example if you have a memcached relation that improves
-performance, mention it here.
-
-## Known Limitations and Issues
-
-This not only helps users but gives people a place to start if they want to help
-you add features to your charm.
-
-# Configuration
-
-The configuration options will be listed on the charm store, however If you're
-making assumptions or opinionated decisions in the charm (like setting a default
-administrator password), you should detail that here so the user knows how to
-change it immediately, etc.
-
-# Contact Information
-
-Though this will be listed in the charm store itself don't assume a user will
-know that, so include that information here:
-
-## Upstream Project Name
-
-  - Upstream website
-  - Upstream bug tracker
-  - Upstream mailing list or contact information
-  - Feel free to add things if it's useful for users
-
-
-[service]: http://example.com
-[icon guidelines]: https://jujucharms.com/docs/stable/authors-charm-icon
diff --git a/builds/VyOS-proxy/README.md b/builds/VyOS-proxy/README.md
deleted file mode 100644 (file)
index 0337c83..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-# Overview
-
-This is the base layer for all charms [built using layers][building].  It
-provides all of the standard Juju hooks and runs the
-[charms.reactive.main][charms.reactive] loop for them.  It also bootstraps the
-[charm-helpers][] and [charms.reactive][] libraries and all of their
-dependencies for use by the charm.
-
-# Usage
-
-To create a charm layer using this base layer, you need only include it in
-a `layer.yaml` file:
-
-```yaml
-includes: ['layer:basic']
-```
-
-This will fetch this layer from [interfaces.juju.solutions][] and incorporate
-it into your charm layer.  You can then add handlers under the `reactive/`
-directory.  Note that **any** file under `reactive/` will be expected to
-contain handlers, whether as Python decorated functions or [executables][non-python]
-using the [external handler protocol][].
-
-### Charm Dependencies
-
-Each layer can include a `wheelhouse.txt` file with Python requirement lines.
-For example, this layer's `wheelhouse.txt` includes:
-
-```
-pip>=7.0.0,<8.0.0
-charmhelpers>=0.4.0,<1.0.0
-charms.reactive>=0.1.0,<2.0.0
-```
-
-All of these dependencies from each layer will be fetched (and updated) at build
-time and will be automatically installed by this base layer before any reactive
-handlers are run.
-
-Note that the `wheelhouse.txt` file is intended for **charm** dependencies only.
-That is, for libraries that the charm code itself needs to do its job of deploying
-and configuring the payload.  If the payload itself has Python dependencies, those
-should be handled separately, by the charm.
-
-See [PyPI][pypi charms.X] for packages under the `charms.` namespace which might
-be useful for your charm.
-
-### Layer Namespace
-
-Each layer has a reserved section in the `charms.layer.` Python package namespace,
-which it can populate by including a `lib/charms/layer/<layer-name>.py` file or
-by placing files under `lib/charms/layer/<layer-name>/`.  (If the layer name
-includes hyphens, replace them with underscores.)  These can be helpers that the
-layer uses internally, or it can expose classes or functions to be used by other
-layers to interact with that layer.
-
-For example, a layer named `foo` could include a `lib/charms/layer/foo.py` file
-with some helper functions that other layers could access using:
-
-```python
-from charms.layer.foo import my_helper
-```
-
-### Layer Options
-
-Any layer can define options in its `layer.yaml`.  Those options can then be set
-by other layers to change the behavior of your layer.  The options are defined
-using [jsonschema][], which is the same way that [action paramters][] are defined.
-
-For example, the `foo` layer could include the following option definitons:
-
-```yaml
-includes: ['layer:basic']
-defines:  # define some options for this layer (the layer "foo")
-  enable-bar:  # define an "enable-bar" option for this layer
-    description: If true, enable support for "bar".
-    type: boolean
-    default: false
-```
-
-A layer using `foo` could then set it:
-
-```yaml
-includes: ['layer:foo']
-options:
-  foo:  # setting options for the "foo" layer
-    enable-bar: true  # set the "enable-bar" option to true
-```
-
-The `foo` layer can then use the `charms.layer.options` helper to load the values
-for the options that it defined.  For example:
-
-```python
-from charms import layer
-
-@when('state')
-def do_thing():
-  layer_opts = layer.options('foo')  # load all of the options for the "foo" layer
-  if layer_opts['enable-bar']:  # check the value of the "enable-bar" option
-      hookenv.log("Bar is enabled")
-```
-
-You can also access layer options in other handlers, such as Bash, using
-the command-line interface:
-
-```bash
-. charms.reactive.sh
-
-@when 'state'
-function do_thing() {
-    if layer_option foo enable-bar; then
-        juju-log "Bar is enabled"
-        juju-log "bar-value is: $(layer_option foo bar-value)"
-    fi
-}
-
-reactive_handler_main
-```
-
-Note that options of type `boolean` will set the exit code, while other types
-will be printed out.
-
-# Hooks
-
-This layer provides hooks that other layers can react to using the decorators
-of the [charms.reactive][] library:
-
-  * `config-changed`
-  * `install`
-  * `leader-elected`
-  * `leader-settings-changed`
-  * `start`
-  * `stop`
-  * `upgrade-charm`
-  * `update-status`
-
-Other hooks are not implemented at this time. A new layer can implement storage
-or relation hooks in their own layer by putting them in the `hooks` directory.
-
-**Note:** Because `update-status` is invoked every 5 minutes, you should take
-care to ensure that your reactive handlers only invoke expensive operations
-when absolutely necessary.  It is recommended that you use helpers like
-[`@only_once`][], [`@when_file_changed`][], and [`data_changed`][] to ensure
-that handlers run only when necessary.
-
-# Layer Configuration
-
-This layer supports the following options, which can be set in `layer.yaml`:
-
-  * **packages**  A list of system packages to be installed before the reactive
-    handlers are invoked.
-
-  * **use_venv**  If set to true, the charm dependencies from the various
-    layers' `wheelhouse.txt` files will be installed in a Python virtualenv
-    located at `$CHARM_DIR/../.venv`.  This keeps charm dependencies from
-    conflicting with payload dependencies, but you must take care to preserve
-    the environment and interpreter if using `execl` or `subprocess`.
-
-  * **include_system_packages**  If set to true and using a venv, include
-    the `--system-site-packages` options to make system Python libraries
-    visible within the venv.
-
-An example `layer.yaml` using these options might be:
-
-```yaml
-includes: ['layer:basic']
-options:
-  basic:
-    packages: ['git']
-    use_venv: true
-    include_system_packages: true
-```
-
-
-# Reactive States
-
-This layer will set the following states:
-
-  * **`config.changed`**  Any config option has changed from its previous value.
-    This state is cleared automatically at the end of each hook invocation.
-
-  * **`config.changed.<option>`** A specific config option has changed.
-    **`<option>`** will be replaced by the config option name from `config.yaml`.
-    This state is cleared automatically at the end of each hook invocation.
-
-  * **`config.set.<option>`** A specific config option has a True or non-empty
-    value set.  **`<option>`** will be replaced by the config option name from
-    `config.yaml`.  This state is cleared automatically at the end of each hook
-    invocation.
-
-  * **`config.default.<option>`** A specific config option is set to its
-    default value.  **`<option>`** will be replaced by the config option name
-    from `config.yaml`.  This state is cleared automatically at the end of
-    each hook invocation.
-
-An example using the config states would be:
-
-```python
-@when('config.changed.my-opt')
-def my_opt_changed():
-    update_config()
-    restart_service()
-```
-
-
-# Actions
-
-This layer currently does not define any actions.
-
-
-[building]: https://jujucharms.com/docs/devel/authors-charm-building
-[charm-helpers]: https://pythonhosted.org/charmhelpers/
-[charms.reactive]: https://pythonhosted.org/charms.reactive/
-[interfaces.juju.solutions]: http://interfaces.juju.solutions/
-[non-python]: https://pythonhosted.org/charms.reactive/#non-python-reactive-handlers
-[external handler protocol]: https://pythonhosted.org/charms.reactive/charms.reactive.bus.html#charms.reactive.bus.ExternalHandler
-[jsonschema]: http://json-schema.org/
-[action paramters]: https://jujucharms.com/docs/stable/authors-charm-actions
-[pypi charms.X]: https://pypi.python.org/pypi?%3Aaction=search&term=charms.&submit=search
-[`@only_once`]: https://pythonhosted.org/charms.reactive/charms.reactive.decorators.html#charms.reactive.decorators.only_once
-[`@when_file_changed`]: https://pythonhosted.org/charms.reactive/charms.reactive.decorators.html#charms.reactive.decorators.when_file_changed
-[`data_changed`]: https://pythonhosted.org/charms.reactive/charms.reactive.helpers.html#charms.reactive.helpers.data_changed
diff --git a/builds/VyOS-proxy/actions.yaml b/builds/VyOS-proxy/actions.yaml
deleted file mode 100644 (file)
index 2acc33d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-"ping":
-  "description": "ping a thing!"
-  "params":
-    "count":
-      "description": "Stop after sending count ECHO_REQUEST packets"
-      "type": "integer"
-      "default": !!int "30"
-    "destination":
-      "description": "destination of ping request"
-      "type": "string"
-  "required":
-  - "destination"
diff --git a/builds/VyOS-proxy/actions/ping b/builds/VyOS-proxy/actions/ping
deleted file mode 100755 (executable)
index 9850fe7..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python3
-import sys
-sys.path.append('lib')
-
-from charms.reactive import main
-from charms.reactive import set_state
-from charmhelpers.core.hookenv import action_fail
-
-"""
-`set_state` only works here because it's flushed to disk inside the `main()`
-loop. remove_state will need to be called inside the action method.
-"""
-set_state('actions.ping')
-
-try:
-    main()
-except Exception as e:
-    action_fail(repr(e))
diff --git a/builds/VyOS-proxy/bin/layer_option b/builds/VyOS-proxy/bin/layer_option
deleted file mode 100755 (executable)
index 90dc400..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-sys.path.append('lib')
-
-import argparse
-from charms.layer import options
-
-
-parser = argparse.ArgumentParser(description='Access layer options.')
-parser.add_argument('section',
-                    help='the section, or layer, the option is from')
-parser.add_argument('option',
-                    help='the option to access')
-
-args = parser.parse_args()
-value = options(args.section).get(args.option, '')
-if isinstance(value, bool):
-    sys.exit(0 if value else 1)
-elif isinstance(value, list):
-    for val in value:
-        print(val)
-else:
-    print(value)
diff --git a/builds/VyOS-proxy/config.yaml b/builds/VyOS-proxy/config.yaml
deleted file mode 100644 (file)
index 0780d5f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-"options":
-  "hostname":
-    "default": !!null ""
-    "type": "string"
-    "description": "Hostname or IP of the VyOS"
-  "user":
-    "type": "string"
-    "default": "vyos"
-    "description": "Username for VyOS"
-  "pass":
-    "type": "string"
-    "default": !!null ""
-    "description": "Password for VyOS"
diff --git a/builds/VyOS-proxy/copyright b/builds/VyOS-proxy/copyright
deleted file mode 100644 (file)
index afa853f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0
-
-Files: *
-Copyright: 2015, Canonical Ltd.
-License: GPL-3
-
-License: GPL-3
- On Debian GNU/Linux system you can find the complete text of the
- GPL-3 license in '/usr/share/common-licenses/GPL-3'
diff --git a/builds/VyOS-proxy/hooks/config-changed b/builds/VyOS-proxy/hooks/config-changed
deleted file mode 100755 (executable)
index d36afe1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-
-# Load modules from $CHARM_DIR/lib
-import sys
-sys.path.append('lib')
-
-from charms.layer import basic
-basic.bootstrap_charm_deps()
-basic.init_config_states()
-
-
-# This will load and run the appropriate @hook and other decorated
-# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
-# and $CHARM_DIR/hooks/relations.
-#
-# See https://jujucharms.com/docs/stable/authors-charm-building
-# for more information on this pattern.
-from charms.reactive import main
-main()
diff --git a/builds/VyOS-proxy/hooks/hook.template b/builds/VyOS-proxy/hooks/hook.template
deleted file mode 100644 (file)
index d36afe1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-
-# Load modules from $CHARM_DIR/lib
-import sys
-sys.path.append('lib')
-
-from charms.layer import basic
-basic.bootstrap_charm_deps()
-basic.init_config_states()
-
-
-# This will load and run the appropriate @hook and other decorated
-# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
-# and $CHARM_DIR/hooks/relations.
-#
-# See https://jujucharms.com/docs/stable/authors-charm-building
-# for more information on this pattern.
-from charms.reactive import main
-main()
diff --git a/builds/VyOS-proxy/hooks/install b/builds/VyOS-proxy/hooks/install
deleted file mode 100755 (executable)
index d36afe1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-
-# Load modules from $CHARM_DIR/lib
-import sys
-sys.path.append('lib')
-
-from charms.layer import basic
-basic.bootstrap_charm_deps()
-basic.init_config_states()
-
-
-# This will load and run the appropriate @hook and other decorated
-# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
-# and $CHARM_DIR/hooks/relations.
-#
-# See https://jujucharms.com/docs/stable/authors-charm-building
-# for more information on this pattern.
-from charms.reactive import main
-main()
diff --git a/builds/VyOS-proxy/hooks/leader-elected b/builds/VyOS-proxy/hooks/leader-elected
deleted file mode 100755 (executable)
index d36afe1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-
-# Load modules from $CHARM_DIR/lib
-import sys
-sys.path.append('lib')
-
-from charms.layer import basic
-basic.bootstrap_charm_deps()
-basic.init_config_states()
-
-
-# This will load and run the appropriate @hook and other decorated
-# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
-# and $CHARM_DIR/hooks/relations.
-#
-# See https://jujucharms.com/docs/stable/authors-charm-building
-# for more information on this pattern.
-from charms.reactive import main
-main()
diff --git a/builds/VyOS-proxy/hooks/leader-settings-changed b/builds/VyOS-proxy/hooks/leader-settings-changed
deleted file mode 100755 (executable)
index d36afe1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-
-# Load modules from $CHARM_DIR/lib
-import sys
-sys.path.append('lib')
-
-from charms.layer import basic
-basic.bootstrap_charm_deps()
-basic.init_config_states()
-
-
-# This will load and run the appropriate @hook and other decorated
-# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
-# and $CHARM_DIR/hooks/relations.
-#
-# See https://jujucharms.com/docs/stable/authors-charm-building
-# for more information on this pattern.
-from charms.reactive import main
-main()
diff --git a/builds/VyOS-proxy/hooks/start b/builds/VyOS-proxy/hooks/start
deleted file mode 100755 (executable)
index d36afe1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-
-# Load modules from $CHARM_DIR/lib
-import sys
-sys.path.append('lib')
-
-from charms.layer import basic
-basic.bootstrap_charm_deps()
-basic.init_config_states()
-
-
-# This will load and run the appropriate @hook and other decorated
-# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
-# and $CHARM_DIR/hooks/relations.
-#
-# See https://jujucharms.com/docs/stable/authors-charm-building
-# for more information on this pattern.
-from charms.reactive import main
-main()
diff --git a/builds/VyOS-proxy/hooks/stop b/builds/VyOS-proxy/hooks/stop
deleted file mode 100755 (executable)
index d36afe1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-
-# Load modules from $CHARM_DIR/lib
-import sys
-sys.path.append('lib')
-
-from charms.layer import basic
-basic.bootstrap_charm_deps()
-basic.init_config_states()
-
-
-# This will load and run the appropriate @hook and other decorated
-# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
-# and $CHARM_DIR/hooks/relations.
-#
-# See https://jujucharms.com/docs/stable/authors-charm-building
-# for more information on this pattern.
-from charms.reactive import main
-main()
diff --git a/builds/VyOS-proxy/hooks/update-status b/builds/VyOS-proxy/hooks/update-status
deleted file mode 100755 (executable)
index d36afe1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-
-# Load modules from $CHARM_DIR/lib
-import sys
-sys.path.append('lib')
-
-from charms.layer import basic
-basic.bootstrap_charm_deps()
-basic.init_config_states()
-
-
-# This will load and run the appropriate @hook and other decorated
-# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
-# and $CHARM_DIR/hooks/relations.
-#
-# See https://jujucharms.com/docs/stable/authors-charm-building
-# for more information on this pattern.
-from charms.reactive import main
-main()
diff --git a/builds/VyOS-proxy/hooks/upgrade-charm b/builds/VyOS-proxy/hooks/upgrade-charm
deleted file mode 100755 (executable)
index 1465e8e..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env python3
-
-# Load modules from $CHARM_DIR/lib
-import os
-import sys
-sys.path.append('lib')
-
-# This is an upgrade-charm context, make sure we install latest deps
-if not os.path.exists('wheelhouse/.upgrade'):
-    open('wheelhouse/.upgrade', 'w').close()
-    if os.path.exists('wheelhouse/.bootstrapped'):
-        os.unlink('wheelhouse/.bootstrapped')
-else:
-    os.unlink('wheelhouse/.upgrade')
-
-from charms.layer import basic
-basic.bootstrap_charm_deps()
-basic.init_config_states()
-
-
-# This will load and run the appropriate @hook and other decorated
-# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
-# and $CHARM_DIR/hooks/relations.
-#
-# See https://jujucharms.com/docs/stable/authors-charm-building
-# for more information on this pattern.
-from charms.reactive import main
-main()
diff --git a/builds/VyOS-proxy/icon.svg b/builds/VyOS-proxy/icon.svg
deleted file mode 100644 (file)
index e092eef..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
-<!-- Created with Inkscape (http://www.inkscape.org/) -->\r
-\r
-<svg\r
-   xmlns:dc="http://purl.org/dc/elements/1.1/"\r
-   xmlns:cc="http://creativecommons.org/ns#"\r
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\r
-   xmlns:svg="http://www.w3.org/2000/svg"\r
-   xmlns="http://www.w3.org/2000/svg"\r
-   xmlns:xlink="http://www.w3.org/1999/xlink"\r
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"\r
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"\r
-   width="96"\r
-   height="96"\r
-   id="svg6517"\r
-   version="1.1"\r
-   inkscape:version="0.48+devel r12274"\r
-   sodipodi:docname="Juju_charm_icon_template.svg">\r
-  <defs\r
-     id="defs6519">\r
-    <linearGradient\r
-       inkscape:collect="always"\r
-       xlink:href="#Background"\r
-       id="linearGradient6461"\r
-       gradientUnits="userSpaceOnUse"\r
-       x1="0"\r
-       y1="970.29498"\r
-       x2="144"\r
-       y2="970.29498"\r
-       gradientTransform="matrix(0,-0.66666669,0.6660448,0,-866.25992,731.29077)" />\r
-    <linearGradient\r
-       id="Background">\r
-      <stop\r
-         id="stop4178"\r
-         offset="0"\r
-         style="stop-color:#b8b8b8;stop-opacity:1" />\r
-      <stop\r
-         id="stop4180"\r
-         offset="1"\r
-         style="stop-color:#c9c9c9;stop-opacity:1" />\r
-    </linearGradient>\r
-    <filter\r
-       style="color-interpolation-filters:sRGB;"\r
-       inkscape:label="Inner Shadow"\r
-       id="filter1121">\r
-      <feFlood\r
-         flood-opacity="0.59999999999999998"\r
-         flood-color="rgb(0,0,0)"\r
-         result="flood"\r
-         id="feFlood1123" />\r
-      <feComposite\r
-         in="flood"\r
-         in2="SourceGraphic"\r
-         operator="out"\r
-         result="composite1"\r
-         id="feComposite1125" />\r
-      <feGaussianBlur\r
-         in="composite1"\r
-         stdDeviation="1"\r
-         result="blur"\r
-         id="feGaussianBlur1127" />\r
-      <feOffset\r
-         dx="0"\r
-         dy="2"\r
-         result="offset"\r
-         id="feOffset1129" />\r
-      <feComposite\r
-         in="offset"\r
-         in2="SourceGraphic"\r
-         operator="atop"\r
-         result="composite2"\r
-         id="feComposite1131" />\r
-    </filter>\r
-    <filter\r
-       style="color-interpolation-filters:sRGB;"\r
-       inkscape:label="Drop Shadow"\r
-       id="filter950">\r
-      <feFlood\r
-         flood-opacity="0.25"\r
-         flood-color="rgb(0,0,0)"\r
-         result="flood"\r
-         id="feFlood952" />\r
-      <feComposite\r
-         in="flood"\r
-         in2="SourceGraphic"\r
-         operator="in"\r
-         result="composite1"\r
-         id="feComposite954" />\r
-      <feGaussianBlur\r
-         in="composite1"\r
-         stdDeviation="1"\r
-         result="blur"\r
-         id="feGaussianBlur956" />\r
-      <feOffset\r
-         dx="0"\r
-         dy="1"\r
-         result="offset"\r
-         id="feOffset958" />\r
-      <feComposite\r
-         in="SourceGraphic"\r
-         in2="offset"\r
-         operator="over"\r
-         result="composite2"\r
-         id="feComposite960" />\r
-    </filter>\r
-    <clipPath\r
-       clipPathUnits="userSpaceOnUse"\r
-       id="clipPath873">\r
-      <g\r
-         transform="matrix(0,-0.66666667,0.66604479,0,-258.25992,677.00001)"\r
-         id="g875"\r
-         inkscape:label="Layer 1"\r
-         style="fill:#ff00ff;fill-opacity:1;stroke:none;display:inline">\r
-        <path\r
-           style="fill:#ff00ff;fill-opacity:1;stroke:none;display:inline"\r
-           d="m 46.702703,898.22775 50.594594,0 C 138.16216,898.22775 144,904.06497 144,944.92583 l 0,50.73846 c 0,40.86071 -5.83784,46.69791 -46.702703,46.69791 l -50.594594,0 C 5.8378378,1042.3622 0,1036.525 0,995.66429 L 0,944.92583 C 0,904.06497 5.8378378,898.22775 46.702703,898.22775 Z"\r
-           id="path877"\r
-           inkscape:connector-curvature="0"\r
-           sodipodi:nodetypes="sssssssss" />\r
-      </g>\r
-    </clipPath>\r
-    <filter\r
-       inkscape:collect="always"\r
-       id="filter891"\r
-       inkscape:label="Badge Shadow">\r
-      <feGaussianBlur\r
-         inkscape:collect="always"\r
-         stdDeviation="0.71999962"\r
-         id="feGaussianBlur893" />\r
-    </filter>\r
-  </defs>\r
-  <sodipodi:namedview\r
-     id="base"\r
-     pagecolor="#ffffff"\r
-     bordercolor="#666666"\r
-     borderopacity="1.0"\r
-     inkscape:pageopacity="0.0"\r
-     inkscape:pageshadow="2"\r
-     inkscape:zoom="4.0745362"\r
-     inkscape:cx="18.514671"\r
-     inkscape:cy="49.018169"\r
-     inkscape:document-units="px"\r
-     inkscape:current-layer="layer1"\r
-     showgrid="true"\r
-     fit-margin-top="0"\r
-     fit-margin-left="0"\r
-     fit-margin-right="0"\r
-     fit-margin-bottom="0"\r
-     inkscape:window-width="1920"\r
-     inkscape:window-height="1029"\r
-     inkscape:window-x="0"\r
-     inkscape:window-y="24"\r
-     inkscape:window-maximized="1"\r
-     showborder="true"\r
-     showguides="true"\r
-     inkscape:guide-bbox="true"\r
-     inkscape:showpageshadow="false">\r
-    <inkscape:grid\r
-       type="xygrid"\r
-       id="grid821" />\r
-    <sodipodi:guide\r
-       orientation="1,0"\r
-       position="16,48"\r
-       id="guide823" />\r
-    <sodipodi:guide\r
-       orientation="0,1"\r
-       position="64,80"\r
-       id="guide825" />\r
-    <sodipodi:guide\r
-       orientation="1,0"\r
-       position="80,40"\r
-       id="guide827" />\r
-    <sodipodi:guide\r
-       orientation="0,1"\r
-       position="64,16"\r
-       id="guide829" />\r
-  </sodipodi:namedview>\r
-  <metadata\r
-     id="metadata6522">\r
-    <rdf:RDF>\r
-      <cc:Work\r
-         rdf:about="">\r
-        <dc:format>image/svg+xml</dc:format>\r
-        <dc:type\r
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />\r
-        <dc:title></dc:title>\r
-      </cc:Work>\r
-    </rdf:RDF>\r
-  </metadata>\r
-  <g\r
-     inkscape:label="BACKGROUND"\r
-     inkscape:groupmode="layer"\r
-     id="layer1"\r
-     transform="translate(268,-635.29076)"\r
-     style="display:inline">\r
-    <path\r
-       style="fill:url(#linearGradient6461);fill-opacity:1;stroke:none;display:inline;filter:url(#filter1121)"\r
-       d="m -268,700.15563 0,-33.72973 c 0,-27.24324 3.88785,-31.13513 31.10302,-31.13513 l 33.79408,0 c 27.21507,0 31.1029,3.89189 31.1029,31.13513 l 0,33.72973 c 0,27.24325 -3.88783,31.13514 -31.1029,31.13514 l -33.79408,0 C -264.11215,731.29077 -268,727.39888 -268,700.15563 Z"\r
-       id="path6455"\r
-       inkscape:connector-curvature="0"\r
-       sodipodi:nodetypes="sssssssss" />\r
-  </g>\r
-  <g\r
-     inkscape:groupmode="layer"\r
-     id="layer3"\r
-     inkscape:label="PLACE YOUR PICTOGRAM HERE"\r
-     style="display:inline" />\r
-  <g\r
-     inkscape:groupmode="layer"\r
-     id="layer2"\r
-     inkscape:label="BADGE"\r
-     style="display:none"\r
-     sodipodi:insensitive="true">\r
-    <g\r
-       style="display:inline"\r
-       transform="translate(-340.00001,-581)"\r
-       id="g4394"\r
-       clip-path="none">\r
-      <g\r
-         id="g855">\r
-        <g\r
-           inkscape:groupmode="maskhelper"\r
-           id="g870"\r
-           clip-path="url(#clipPath873)"\r
-           style="opacity:0.6;filter:url(#filter891)">\r
-          <path\r
-             transform="matrix(1.4999992,0,0,1.4999992,-29.999795,-237.54282)"\r
-             d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"\r
-             sodipodi:ry="12"\r
-             sodipodi:rx="12"\r
-             sodipodi:cy="552.36218"\r
-             sodipodi:cx="252"\r
-             id="path844"\r
-             style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"\r
-             sodipodi:type="arc" />\r
-        </g>\r
-        <g\r
-           id="g862">\r
-          <path\r
-             sodipodi:type="arc"\r
-             style="color:#000000;fill:#f5f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"\r
-             id="path4398"\r
-             sodipodi:cx="252"\r
-             sodipodi:cy="552.36218"\r
-             sodipodi:rx="12"\r
-             sodipodi:ry="12"\r
-             d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"\r
-             transform="matrix(1.4999992,0,0,1.4999992,-29.999795,-238.54282)" />\r
-          <path\r
-             transform="matrix(1.25,0,0,1.25,33,-100.45273)"\r
-             d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"\r
-             sodipodi:ry="12"\r
-             sodipodi:rx="12"\r
-             sodipodi:cy="552.36218"\r
-             sodipodi:cx="252"\r
-             id="path4400"\r
-             style="color:#000000;fill:#dd4814;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"\r
-             sodipodi:type="arc" />\r
-          <path\r
-             sodipodi:type="star"\r
-             style="color:#000000;fill:#f5f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"\r
-             id="path4459"\r
-             sodipodi:sides="5"\r
-             sodipodi:cx="666.19574"\r
-             sodipodi:cy="589.50385"\r
-             sodipodi:r1="7.2431178"\r
-             sodipodi:r2="4.3458705"\r
-             sodipodi:arg1="1.0471976"\r
-             sodipodi:arg2="1.6755161"\r
-             inkscape:flatsided="false"\r
-             inkscape:rounded="0.1"\r
-             inkscape:randomized="0"\r
-             d="m 669.8173,595.77657 c -0.39132,0.22593 -3.62645,-1.90343 -4.07583,-1.95066 -0.44938,-0.0472 -4.05653,1.36297 -4.39232,1.06062 -0.3358,-0.30235 0.68963,-4.03715 0.59569,-4.47913 -0.0939,-0.44198 -2.5498,-3.43681 -2.36602,-3.8496 0.18379,-0.41279 4.05267,-0.59166 4.44398,-0.81759 0.39132,-0.22593 2.48067,-3.48704 2.93005,-3.4398 0.44938,0.0472 1.81505,3.67147 2.15084,3.97382 0.3358,0.30236 4.08294,1.2817 4.17689,1.72369 0.0939,0.44198 -2.9309,2.86076 -3.11469,3.27355 C 669.9821,591.68426 670.20862,595.55064 669.8173,595.77657 Z"\r
-             transform="matrix(1.511423,-0.16366377,0.16366377,1.511423,-755.37346,-191.93651)" />\r
-        </g>\r
-      </g>\r
-    </g>\r
-  </g>\r
-</svg>\r
diff --git a/builds/VyOS-proxy/layer.yaml b/builds/VyOS-proxy/layer.yaml
deleted file mode 100644 (file)
index 16ac9ce..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-"options":
-  "basic":
-    "packages":
-    - "python-dev"
-    - "libffi-dev"
-    - "libssl-dev"
-    "use_venv": !!bool "false"
-    "include_system_packages": !!bool "false"
-  "vyos-proxy": {}
-"includes":
-- "layer:basic"
-"is": "vyos-proxy"
diff --git a/builds/VyOS-proxy/lib/charms/layer/__init__.py b/builds/VyOS-proxy/lib/charms/layer/__init__.py
deleted file mode 100644 (file)
index 33d37e9..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-import os
-
-
-class LayerOptions(dict):
-    def __init__(self, layer_file, section=None):
-        import yaml  # defer, might not be available until bootstrap
-        with open(layer_file) as f:
-            layer = yaml.safe_load(f.read())
-        opts = layer.get('options', {})
-        if section and section in opts:
-            super(LayerOptions, self).__init__(opts.get(section))
-        else:
-            super(LayerOptions, self).__init__(opts)
-
-
-def options(section=None, layer_file=None):
-    if not layer_file:
-        base_dir = os.environ.get('CHARM_DIR', os.getcwd())
-        layer_file = os.path.join(base_dir, 'layer.yaml')
-
-    return LayerOptions(layer_file, section)
diff --git a/builds/VyOS-proxy/lib/charms/layer/basic.py b/builds/VyOS-proxy/lib/charms/layer/basic.py
deleted file mode 100644 (file)
index 50bd625..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-import os
-import sys
-import shutil
-import platform
-from glob import glob
-from subprocess import check_call
-
-from charms.layer.execd import execd_preinstall
-
-
-def bootstrap_charm_deps():
-    """
-    Set up the base charm dependencies so that the reactive system can run.
-    """
-    # execd must happen first, before any attempt to install packages or
-    # access the network, because sites use this hook to do bespoke
-    # configuration and install secrets so the rest of this bootstrap
-    # and the charm itself can actually succeed. This call does nothing
-    # unless the operator has created and populated $CHARM_DIR/exec.d.
-    execd_preinstall()
-    # ensure that $CHARM_DIR/bin is on the path, for helper scripts
-    os.environ['PATH'] += ':%s' % os.path.join(os.environ['CHARM_DIR'], 'bin')
-    venv = os.path.abspath('../.venv')
-    vbin = os.path.join(venv, 'bin')
-    vpip = os.path.join(vbin, 'pip')
-    vpy = os.path.join(vbin, 'python')
-    if os.path.exists('wheelhouse/.bootstrapped'):
-        from charms import layer
-        cfg = layer.options('basic')
-        if cfg.get('use_venv') and '.venv' not in sys.executable:
-            # activate the venv
-            os.environ['PATH'] = ':'.join([vbin, os.environ['PATH']])
-            reload_interpreter(vpy)
-        return
-    # bootstrap wheelhouse
-    if os.path.exists('wheelhouse'):
-        with open('/root/.pydistutils.cfg', 'w') as fp:
-            # make sure that easy_install also only uses the wheelhouse
-            # (see https://github.com/pypa/pip/issues/410)
-            charm_dir = os.environ['CHARM_DIR']
-            fp.writelines([
-                "[easy_install]\n",
-                "allow_hosts = ''\n",
-                "find_links = file://{}/wheelhouse/\n".format(charm_dir),
-            ])
-        apt_install(['python3-pip', 'python3-setuptools', 'python3-yaml'])
-        from charms import layer
-        cfg = layer.options('basic')
-        # include packages defined in layer.yaml
-        apt_install(cfg.get('packages', []))
-        # if we're using a venv, set it up
-        if cfg.get('use_venv'):
-            if not os.path.exists(venv):
-                distname, version, series = platform.linux_distribution()
-                if series in ('precise', 'trusty'):
-                    apt_install(['python-virtualenv'])
-                else:
-                    apt_install(['virtualenv'])
-                cmd = ['virtualenv', '-ppython3', '--never-download', venv]
-                if cfg.get('include_system_packages'):
-                    cmd.append('--system-site-packages')
-                check_call(cmd)
-            os.environ['PATH'] = ':'.join([vbin, os.environ['PATH']])
-            pip = vpip
-        else:
-            pip = 'pip3'
-            # save a copy of system pip to prevent `pip3 install -U pip`
-            # from changing it
-            if os.path.exists('/usr/bin/pip'):
-                shutil.copy2('/usr/bin/pip', '/usr/bin/pip.save')
-        # need newer pip, to fix spurious Double Requirement error:
-        # https://github.com/pypa/pip/issues/56
-        check_call([pip, 'install', '-U', '--no-index', '-f', 'wheelhouse',
-                    'pip'])
-        # install the rest of the wheelhouse deps
-        check_call([pip, 'install', '-U', '--no-index', '-f', 'wheelhouse'] +
-                   glob('wheelhouse/*'))
-        if not cfg.get('use_venv'):
-            # restore system pip to prevent `pip3 install -U pip`
-            # from changing it
-            if os.path.exists('/usr/bin/pip.save'):
-                shutil.copy2('/usr/bin/pip.save', '/usr/bin/pip')
-                os.remove('/usr/bin/pip.save')
-        os.remove('/root/.pydistutils.cfg')
-        # flag us as having already bootstrapped so we don't do it again
-        open('wheelhouse/.bootstrapped', 'w').close()
-        # Ensure that the newly bootstrapped libs are available.
-        # Note: this only seems to be an issue with namespace packages.
-        # Non-namespace-package libs (e.g., charmhelpers) are available
-        # without having to reload the interpreter. :/
-        reload_interpreter(vpy if cfg.get('use_venv') else sys.argv[0])
-
-
-def reload_interpreter(python):
-    """
-    Reload the python interpreter to ensure that all deps are available.
-
-    Newly installed modules in namespace packages sometimes seemt to
-    not be picked up by Python 3.
-    """
-    os.execle(python, python, sys.argv[0], os.environ)
-
-
-def apt_install(packages):
-    """
-    Install apt packages.
-
-    This ensures a consistent set of options that are often missed but
-    should really be set.
-    """
-    if isinstance(packages, (str, bytes)):
-        packages = [packages]
-
-    env = os.environ.copy()
-
-    if 'DEBIAN_FRONTEND' not in env:
-        env['DEBIAN_FRONTEND'] = 'noninteractive'
-
-    cmd = ['apt-get',
-           '--option=Dpkg::Options::=--force-confold',
-           '--assume-yes',
-           'install']
-    check_call(cmd + packages, env=env)
-
-
-def init_config_states():
-    import yaml
-    from charmhelpers.core import hookenv
-    from charms.reactive import set_state
-    from charms.reactive import toggle_state
-    config = hookenv.config()
-    config_defaults = {}
-    config_defs = {}
-    config_yaml = os.path.join(hookenv.charm_dir(), 'config.yaml')
-    if os.path.exists(config_yaml):
-        with open(config_yaml) as fp:
-            config_defs = yaml.load(fp).get('options', {})
-            config_defaults = {key: value.get('default')
-                               for key, value in config_defs.items()}
-    for opt in config_defs.keys():
-        if config.changed(opt):
-            set_state('config.changed')
-            set_state('config.changed.{}'.format(opt))
-        toggle_state('config.set.{}'.format(opt), config.get(opt))
-        toggle_state('config.default.{}'.format(opt),
-                     config.get(opt) == config_defaults[opt])
-    hookenv.atexit(clear_config_states)
-
-
-def clear_config_states():
-    from charmhelpers.core import hookenv, unitdata
-    from charms.reactive import remove_state
-    config = hookenv.config()
-    remove_state('config.changed')
-    for opt in config.keys():
-        remove_state('config.changed.{}'.format(opt))
-        remove_state('config.set.{}'.format(opt))
-        remove_state('config.default.{}'.format(opt))
-    unitdata.kv().flush()
diff --git a/builds/VyOS-proxy/lib/charms/layer/execd.py b/builds/VyOS-proxy/lib/charms/layer/execd.py
deleted file mode 100644 (file)
index 3057419..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-# Copyright 2014-2016 Canonical Limited.
-#
-# This file is part of layer-basic, the reactive base layer for Juju.
-#
-# charm-helpers is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License version 3 as
-# published by the Free Software Foundation.
-#
-# charm-helpers is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with charm-helpers.  If not, see <http://www.gnu.org/licenses/>.
-
-# This module may only import from the Python standard library.
-import os
-import sys
-import subprocess
-import time
-
-'''
-execd/preinstall
-
-It is often necessary to configure and reconfigure machines
-after provisioning, but before attempting to run the charm.
-Common examples are specialized network configuration, enabling
-of custom hardware, non-standard disk partitioning and filesystems,
-adding secrets and keys required for using a secured network.
-
-The reactive framework's base layer invokes this mechanism as
-early as possible, before any network access is made or dependencies
-unpacked or non-standard modules imported (including the charms.reactive
-framework itself).
-
-Operators needing to use this functionality may branch a charm and
-create an exec.d directory in it. The exec.d directory in turn contains
-one or more subdirectories, each of which contains an executable called
-charm-pre-install and any other required resources. The charm-pre-install
-executables are run, and if successful, state saved so they will not be
-run again.
-
-    $CHARM_DIR/exec.d/mynamespace/charm-pre-install
-
-An alternative to branching a charm is to compose a new charm that contains
-the exec.d directory, using the original charm as a layer,
-
-A charm author could also abuse this mechanism to modify the charm
-environment in unusual ways, but for most purposes it is saner to use
-charmhelpers.core.hookenv.atstart().
-'''
-
-
-def default_execd_dir():
-    return os.path.join(os.environ['CHARM_DIR'], 'exec.d')
-
-
-def execd_module_paths(execd_dir=None):
-    """Generate a list of full paths to modules within execd_dir."""
-    if not execd_dir:
-        execd_dir = default_execd_dir()
-
-    if not os.path.exists(execd_dir):
-        return
-
-    for subpath in os.listdir(execd_dir):
-        module = os.path.join(execd_dir, subpath)
-        if os.path.isdir(module):
-            yield module
-
-
-def execd_submodule_paths(command, execd_dir=None):
-    """Generate a list of full paths to the specified command within exec_dir.
-    """
-    for module_path in execd_module_paths(execd_dir):
-        path = os.path.join(module_path, command)
-        if os.access(path, os.X_OK) and os.path.isfile(path):
-            yield path
-
-
-def execd_sentinel_path(submodule_path):
-    module_path = os.path.dirname(submodule_path)
-    execd_path = os.path.dirname(module_path)
-    module_name = os.path.basename(module_path)
-    submodule_name = os.path.basename(submodule_path)
-    return os.path.join(execd_path,
-                        '.{}_{}.done'.format(module_name, submodule_name))
-
-
-def execd_run(command, execd_dir=None, stop_on_error=True, stderr=None):
-    """Run command for each module within execd_dir which defines it."""
-    if stderr is None:
-        stderr = sys.stdout
-    for submodule_path in execd_submodule_paths(command, execd_dir):
-        # Only run each execd once. We cannot simply run them in the
-        # install hook, as potentially storage hooks are run before that.
-        # We cannot rely on them being idempotent.
-        sentinel = execd_sentinel_path(submodule_path)
-        if os.path.exists(sentinel):
-            continue
-
-        try:
-            subprocess.check_call([submodule_path], stderr=stderr,
-                                  universal_newlines=True)
-            with open(sentinel, 'w') as f:
-                f.write('{} ran successfully {}\n'.format(submodule_path,
-                                                          time.ctime()))
-                f.write('Removing this file will cause it to be run again\n')
-        except subprocess.CalledProcessError as e:
-            # Logs get the details. We can't use juju-log, as the
-            # output may be substantial and exceed command line
-            # length limits.
-            print("ERROR ({}) running {}".format(e.returncode, e.cmd),
-                  file=stderr)
-            print("STDOUT<<EOM", file=stderr)
-            print(e.output, file=stderr)
-            print("EOM", file=stderr)
-
-            # Unit workload status gets a shorter fail message.
-            short_path = os.path.relpath(submodule_path)
-            block_msg = "Error ({}) running {}".format(e.returncode,
-                                                       short_path)
-            try:
-                subprocess.check_call(['status-set', 'blocked', block_msg],
-                                      universal_newlines=True)
-                if stop_on_error:
-                    sys.exit(0)  # Leave unit in blocked state.
-            except Exception:
-                pass  # We care about the exec.d/* failure, not status-set.
-
-            if stop_on_error:
-                sys.exit(e.returncode or 1)  # Error state for pre-1.24 Juju
-
-
-def execd_preinstall(execd_dir=None):
-    """Run charm-pre-install for each module within execd_dir."""
-    execd_run('charm-pre-install', execd_dir=execd_dir)
diff --git a/builds/VyOS-proxy/metadata.yaml b/builds/VyOS-proxy/metadata.yaml
deleted file mode 100644 (file)
index 1d29b37..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-"name": "vyos-proxy"
-"summary": "VyOS Proxy charm for ping"
-"description": |
-  VyOS Proxy charm
-"tags":
-- "vnf"
-- "network"
-"maintainers":
-- "Marco Ceppi <marco.ceppi@canonical.com>"
-"series":
-- "xenial"
-- "trusty"
diff --git a/builds/VyOS-proxy/reactive/__init__.py b/builds/VyOS-proxy/reactive/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/builds/VyOS-proxy/reactive/vyos_proxy.py b/builds/VyOS-proxy/reactive/vyos_proxy.py
deleted file mode 100644 (file)
index a8fd5e0..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-
-import subprocess
-import paramiko
-
-from charmhelpers.core.hookenv import (
-    config,
-    status_set,
-    action_get,
-    action_set,
-    action_fail,
-)
-
-from charms.reactive import (
-    when,
-    when_not,
-    set_state as set_flag,
-    remove_state as remove_flag,
-)
-
-
-@when('config.changed')
-def test_connection():
-    status_set('maintenance', 'configuring ssh connection')
-    remove_flag('vyos-proxy.ready')
-    try:
-        who, _ = run('whoami')
-    except MgmtNotConfigured as e:
-        remove_flag('vyos-proxy.configured')
-        status_set('blocked', str(e))
-    except subprocess.CalledProcessError as e:
-        remove_flag('vyos-proxy.configured')
-        status_set('blocked', e.output)
-    else:
-        set_flag('vyos-proxy.configured')
-
-
-@when('vyos-proxy.configured')
-@when_not('vyos-proxy.ready')
-def vyos_proxy_ready():
-    status_set('active', 'ready')
-    set_flag('vyos-proxy.ready')
-
-
-@when('actions.ping')
-@when_not('vyos-proxy.configured')
-def pingme():
-    action_fail('proxy is not ready')
-
-
-@when('actions.ping')
-@when('vyos-proxy.configured')
-def pingme_forreal():
-    try:
-        result, err = run('ping -qc {} {}'.format(action_get('count'), action_get('destination')))
-    except:
-        action_fail('ping command failed')
-    finally:
-        remove_flag('actions.ping')
-
-    # Here you can send results back from ping, if you had time to parse it
-    action_set({'output': result})
-
-
-
-class MgmtNotConfigured(Exception):
-    pass
-
-
-def run(cmd):
-    ''' Suddenly this project needs to SSH to something. So we replicate what
-        _run was doing with subprocess using the Paramiko library. This is
-        temporary until this charm /is/ the VPE Router '''
-
-    cfg = config()
-
-    hostname = cfg.get('hostname')
-    password = cfg.get('pass')
-    username = cfg.get('user')
-
-    if not (username and password and hostname):
-        raise MgmtNotConfigured('incomplete remote credentials')
-
-    client = paramiko.SSHClient()
-    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-
-    try:
-        client.connect(cfg.get('hostname'), port=22,
-                       username=cfg.get('user'), password=cfg.get('pass'))
-    except paramiko.ssh_exception.AuthenticationException:
-        raise MgmtNotConfigured('invalid credentials')
-
-    stdin, stdout, stderr = client.exec_command(cmd)
-    retcode = stdout.channel.recv_exit_status()
-    client.close()  # @TODO re-use connections
-    if retcode > 0:
-        output = stderr.read().strip()
-        raise subprocess.CalledProcessError(returncode=retcode, cmd=cmd,
-                                            output=output)
-    return (''.join(stdout), ''.join(stderr))
diff --git a/builds/VyOS-proxy/requirements.txt b/builds/VyOS-proxy/requirements.txt
deleted file mode 100644 (file)
index 28ecaca..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-flake8
-pytest
diff --git a/builds/VyOS-proxy/revision b/builds/VyOS-proxy/revision
deleted file mode 100644 (file)
index c227083..0000000
+++ /dev/null
@@ -1 +0,0 @@
-0
\ No newline at end of file
diff --git a/builds/VyOS-proxy/tox.ini b/builds/VyOS-proxy/tox.ini
deleted file mode 100644 (file)
index 0b8b27a..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-[tox]
-skipsdist=True
-envlist = py34, py35
-skip_missing_interpreters = True
-
-[testenv]
-commands = py.test -v
-deps =
-    -r{toxinidir}/requirements.txt
-
-[flake8]
-exclude=docs
diff --git a/builds/VyOS-proxy/wheelhouse/Jinja2-2.8.tar.gz b/builds/VyOS-proxy/wheelhouse/Jinja2-2.8.tar.gz
deleted file mode 100644 (file)
index 9c38426..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/Jinja2-2.8.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/MarkupSafe-0.23.tar.gz b/builds/VyOS-proxy/wheelhouse/MarkupSafe-0.23.tar.gz
deleted file mode 100644 (file)
index 6b19006..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/MarkupSafe-0.23.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/PyYAML-3.11.zip b/builds/VyOS-proxy/wheelhouse/PyYAML-3.11.zip
deleted file mode 100644 (file)
index c361e86..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/PyYAML-3.11.zip and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/Tempita-0.5.2.tar.gz b/builds/VyOS-proxy/wheelhouse/Tempita-0.5.2.tar.gz
deleted file mode 100644 (file)
index 755befc..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/Tempita-0.5.2.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/cffi-1.7.0.tar.gz b/builds/VyOS-proxy/wheelhouse/cffi-1.7.0.tar.gz
deleted file mode 100644 (file)
index 55da260..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/cffi-1.7.0.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/charmhelpers-0.7.0.tar.gz b/builds/VyOS-proxy/wheelhouse/charmhelpers-0.7.0.tar.gz
deleted file mode 100644 (file)
index 93acb40..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/charmhelpers-0.7.0.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/charms.reactive-0.4.4.tar.gz b/builds/VyOS-proxy/wheelhouse/charms.reactive-0.4.4.tar.gz
deleted file mode 100644 (file)
index 0912b6a..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/charms.reactive-0.4.4.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/cryptography-1.4.tar.gz b/builds/VyOS-proxy/wheelhouse/cryptography-1.4.tar.gz
deleted file mode 100644 (file)
index e7dfece..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/cryptography-1.4.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/idna-2.1.tar.gz b/builds/VyOS-proxy/wheelhouse/idna-2.1.tar.gz
deleted file mode 100644 (file)
index c028c71..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/idna-2.1.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/netaddr-0.7.18.tar.gz b/builds/VyOS-proxy/wheelhouse/netaddr-0.7.18.tar.gz
deleted file mode 100644 (file)
index 0df6b47..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/netaddr-0.7.18.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/paramiko-2.0.1.tar.gz b/builds/VyOS-proxy/wheelhouse/paramiko-2.0.1.tar.gz
deleted file mode 100644 (file)
index 6f2d318..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/paramiko-2.0.1.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/pip-8.1.2.tar.gz b/builds/VyOS-proxy/wheelhouse/pip-8.1.2.tar.gz
deleted file mode 100644 (file)
index e7a1a3c..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/pip-8.1.2.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/pyaml-15.8.2.tar.gz b/builds/VyOS-proxy/wheelhouse/pyaml-15.8.2.tar.gz
deleted file mode 100644 (file)
index 3c49aaf..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/pyaml-15.8.2.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/pyasn1-0.1.9.tar.gz b/builds/VyOS-proxy/wheelhouse/pyasn1-0.1.9.tar.gz
deleted file mode 100644 (file)
index 1900b07..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/pyasn1-0.1.9.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/pycparser-2.14.tar.gz b/builds/VyOS-proxy/wheelhouse/pycparser-2.14.tar.gz
deleted file mode 100644 (file)
index 6cdaab1..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/pycparser-2.14.tar.gz and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/setuptools-23.1.0.zip b/builds/VyOS-proxy/wheelhouse/setuptools-23.1.0.zip
deleted file mode 100644 (file)
index 23e512a..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/setuptools-23.1.0.zip and /dev/null differ
diff --git a/builds/VyOS-proxy/wheelhouse/six-1.10.0.tar.gz b/builds/VyOS-proxy/wheelhouse/six-1.10.0.tar.gz
deleted file mode 100644 (file)
index ac8eec5..0000000
Binary files a/builds/VyOS-proxy/wheelhouse/six-1.10.0.tar.gz and /dev/null differ
diff --git a/layers/vyos-proxy/Makefile b/layers/vyos-proxy/Makefile
new file mode 100644 (file)
index 0000000..a1ad3a5
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/make
+
+all: lint unit_test
+
+
+.PHONY: clean
+clean:
+       @rm -rf .tox
+
+.PHONY: apt_prereqs
+apt_prereqs:
+       @# Need tox, but don't install the apt version unless we have to (don't want to conflict with pip)
+       @which tox >/dev/null || (sudo apt-get install -y python-pip && sudo pip install tox)
+
+.PHONY: lint
+lint: apt_prereqs
+       @tox --notest
+       @PATH=.tox/py34/bin:.tox/py35/bin flake8 $(wildcard hooks reactive lib unit_tests tests)
+       @charm proof
+
+.PHONY: unit_test
+unit_test: apt_prereqs
+       @echo Starting tests...
+       tox
diff --git a/layers/vyos-proxy/README.md b/layers/vyos-proxy/README.md
new file mode 100644 (file)
index 0000000..0337c83
--- /dev/null
@@ -0,0 +1,221 @@
+# Overview
+
+This is the base layer for all charms [built using layers][building].  It
+provides all of the standard Juju hooks and runs the
+[charms.reactive.main][charms.reactive] loop for them.  It also bootstraps the
+[charm-helpers][] and [charms.reactive][] libraries and all of their
+dependencies for use by the charm.
+
+# Usage
+
+To create a charm layer using this base layer, you need only include it in
+a `layer.yaml` file:
+
+```yaml
+includes: ['layer:basic']
+```
+
+This will fetch this layer from [interfaces.juju.solutions][] and incorporate
+it into your charm layer.  You can then add handlers under the `reactive/`
+directory.  Note that **any** file under `reactive/` will be expected to
+contain handlers, whether as Python decorated functions or [executables][non-python]
+using the [external handler protocol][].
+
+### Charm Dependencies
+
+Each layer can include a `wheelhouse.txt` file with Python requirement lines.
+For example, this layer's `wheelhouse.txt` includes:
+
+```
+pip>=7.0.0,<8.0.0
+charmhelpers>=0.4.0,<1.0.0
+charms.reactive>=0.1.0,<2.0.0
+```
+
+All of these dependencies from each layer will be fetched (and updated) at build
+time and will be automatically installed by this base layer before any reactive
+handlers are run.
+
+Note that the `wheelhouse.txt` file is intended for **charm** dependencies only.
+That is, for libraries that the charm code itself needs to do its job of deploying
+and configuring the payload.  If the payload itself has Python dependencies, those
+should be handled separately, by the charm.
+
+See [PyPI][pypi charms.X] for packages under the `charms.` namespace which might
+be useful for your charm.
+
+### Layer Namespace
+
+Each layer has a reserved section in the `charms.layer.` Python package namespace,
+which it can populate by including a `lib/charms/layer/<layer-name>.py` file or
+by placing files under `lib/charms/layer/<layer-name>/`.  (If the layer name
+includes hyphens, replace them with underscores.)  These can be helpers that the
+layer uses internally, or it can expose classes or functions to be used by other
+layers to interact with that layer.
+
+For example, a layer named `foo` could include a `lib/charms/layer/foo.py` file
+with some helper functions that other layers could access using:
+
+```python
+from charms.layer.foo import my_helper
+```
+
+### Layer Options
+
+Any layer can define options in its `layer.yaml`.  Those options can then be set
+by other layers to change the behavior of your layer.  The options are defined
+using [jsonschema][], which is the same way that [action paramters][] are defined.
+
+For example, the `foo` layer could include the following option definitons:
+
+```yaml
+includes: ['layer:basic']
+defines:  # define some options for this layer (the layer "foo")
+  enable-bar:  # define an "enable-bar" option for this layer
+    description: If true, enable support for "bar".
+    type: boolean
+    default: false
+```
+
+A layer using `foo` could then set it:
+
+```yaml
+includes: ['layer:foo']
+options:
+  foo:  # setting options for the "foo" layer
+    enable-bar: true  # set the "enable-bar" option to true
+```
+
+The `foo` layer can then use the `charms.layer.options` helper to load the values
+for the options that it defined.  For example:
+
+```python
+from charms import layer
+
+@when('state')
+def do_thing():
+  layer_opts = layer.options('foo')  # load all of the options for the "foo" layer
+  if layer_opts['enable-bar']:  # check the value of the "enable-bar" option
+      hookenv.log("Bar is enabled")
+```
+
+You can also access layer options in other handlers, such as Bash, using
+the command-line interface:
+
+```bash
+. charms.reactive.sh
+
+@when 'state'
+function do_thing() {
+    if layer_option foo enable-bar; then
+        juju-log "Bar is enabled"
+        juju-log "bar-value is: $(layer_option foo bar-value)"
+    fi
+}
+
+reactive_handler_main
+```
+
+Note that options of type `boolean` will set the exit code, while other types
+will be printed out.
+
+# Hooks
+
+This layer provides hooks that other layers can react to using the decorators
+of the [charms.reactive][] library:
+
+  * `config-changed`
+  * `install`
+  * `leader-elected`
+  * `leader-settings-changed`
+  * `start`
+  * `stop`
+  * `upgrade-charm`
+  * `update-status`
+
+Other hooks are not implemented at this time. A new layer can implement storage
+or relation hooks in their own layer by putting them in the `hooks` directory.
+
+**Note:** Because `update-status` is invoked every 5 minutes, you should take
+care to ensure that your reactive handlers only invoke expensive operations
+when absolutely necessary.  It is recommended that you use helpers like
+[`@only_once`][], [`@when_file_changed`][], and [`data_changed`][] to ensure
+that handlers run only when necessary.
+
+# Layer Configuration
+
+This layer supports the following options, which can be set in `layer.yaml`:
+
+  * **packages**  A list of system packages to be installed before the reactive
+    handlers are invoked.
+
+  * **use_venv**  If set to true, the charm dependencies from the various
+    layers' `wheelhouse.txt` files will be installed in a Python virtualenv
+    located at `$CHARM_DIR/../.venv`.  This keeps charm dependencies from
+    conflicting with payload dependencies, but you must take care to preserve
+    the environment and interpreter if using `execl` or `subprocess`.
+
+  * **include_system_packages**  If set to true and using a venv, include
+    the `--system-site-packages` options to make system Python libraries
+    visible within the venv.
+
+An example `layer.yaml` using these options might be:
+
+```yaml
+includes: ['layer:basic']
+options:
+  basic:
+    packages: ['git']
+    use_venv: true
+    include_system_packages: true
+```
+
+
+# Reactive States
+
+This layer will set the following states:
+
+  * **`config.changed`**  Any config option has changed from its previous value.
+    This state is cleared automatically at the end of each hook invocation.
+
+  * **`config.changed.<option>`** A specific config option has changed.
+    **`<option>`** will be replaced by the config option name from `config.yaml`.
+    This state is cleared automatically at the end of each hook invocation.
+
+  * **`config.set.<option>`** A specific config option has a True or non-empty
+    value set.  **`<option>`** will be replaced by the config option name from
+    `config.yaml`.  This state is cleared automatically at the end of each hook
+    invocation.
+
+  * **`config.default.<option>`** A specific config option is set to its
+    default value.  **`<option>`** will be replaced by the config option name
+    from `config.yaml`.  This state is cleared automatically at the end of
+    each hook invocation.
+
+An example using the config states would be:
+
+```python
+@when('config.changed.my-opt')
+def my_opt_changed():
+    update_config()
+    restart_service()
+```
+
+
+# Actions
+
+This layer currently does not define any actions.
+
+
+[building]: https://jujucharms.com/docs/devel/authors-charm-building
+[charm-helpers]: https://pythonhosted.org/charmhelpers/
+[charms.reactive]: https://pythonhosted.org/charms.reactive/
+[interfaces.juju.solutions]: http://interfaces.juju.solutions/
+[non-python]: https://pythonhosted.org/charms.reactive/#non-python-reactive-handlers
+[external handler protocol]: https://pythonhosted.org/charms.reactive/charms.reactive.bus.html#charms.reactive.bus.ExternalHandler
+[jsonschema]: http://json-schema.org/
+[action paramters]: https://jujucharms.com/docs/stable/authors-charm-actions
+[pypi charms.X]: https://pypi.python.org/pypi?%3Aaction=search&term=charms.&submit=search
+[`@only_once`]: https://pythonhosted.org/charms.reactive/charms.reactive.decorators.html#charms.reactive.decorators.only_once
+[`@when_file_changed`]: https://pythonhosted.org/charms.reactive/charms.reactive.decorators.html#charms.reactive.decorators.when_file_changed
+[`data_changed`]: https://pythonhosted.org/charms.reactive/charms.reactive.helpers.html#charms.reactive.helpers.data_changed
diff --git a/layers/vyos-proxy/actions.yaml b/layers/vyos-proxy/actions.yaml
new file mode 100644 (file)
index 0000000..2acc33d
--- /dev/null
@@ -0,0 +1,12 @@
+"ping":
+  "description": "ping a thing!"
+  "params":
+    "count":
+      "description": "Stop after sending count ECHO_REQUEST packets"
+      "type": "integer"
+      "default": !!int "30"
+    "destination":
+      "description": "destination of ping request"
+      "type": "string"
+  "required":
+  - "destination"
diff --git a/layers/vyos-proxy/actions/ping b/layers/vyos-proxy/actions/ping
new file mode 100755 (executable)
index 0000000..9850fe7
--- /dev/null
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+import sys
+sys.path.append('lib')
+
+from charms.reactive import main
+from charms.reactive import set_state
+from charmhelpers.core.hookenv import action_fail
+
+"""
+`set_state` only works here because it's flushed to disk inside the `main()`
+loop. remove_state will need to be called inside the action method.
+"""
+set_state('actions.ping')
+
+try:
+    main()
+except Exception as e:
+    action_fail(repr(e))
diff --git a/layers/vyos-proxy/config.yaml b/layers/vyos-proxy/config.yaml
new file mode 100644 (file)
index 0000000..0780d5f
--- /dev/null
@@ -0,0 +1,13 @@
+"options":
+  "hostname":
+    "default": !!null ""
+    "type": "string"
+    "description": "Hostname or IP of the VyOS"
+  "user":
+    "type": "string"
+    "default": "vyos"
+    "description": "Username for VyOS"
+  "pass":
+    "type": "string"
+    "default": !!null ""
+    "description": "Password for VyOS"
diff --git a/layers/vyos-proxy/copyright b/layers/vyos-proxy/copyright
new file mode 100644 (file)
index 0000000..afa853f
--- /dev/null
@@ -0,0 +1,9 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0
+
+Files: *
+Copyright: 2015, Canonical Ltd.
+License: GPL-3
+
+License: GPL-3
+ On Debian GNU/Linux system you can find the complete text of the
+ GPL-3 license in '/usr/share/common-licenses/GPL-3'
diff --git a/layers/vyos-proxy/icon.svg b/layers/vyos-proxy/icon.svg
new file mode 100644 (file)
index 0000000..e092eef
--- /dev/null
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<!-- Created with Inkscape (http://www.inkscape.org/) -->\r
+\r
+<svg\r
+   xmlns:dc="http://purl.org/dc/elements/1.1/"\r
+   xmlns:cc="http://creativecommons.org/ns#"\r
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\r
+   xmlns:svg="http://www.w3.org/2000/svg"\r
+   xmlns="http://www.w3.org/2000/svg"\r
+   xmlns:xlink="http://www.w3.org/1999/xlink"\r
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"\r
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"\r
+   width="96"\r
+   height="96"\r
+   id="svg6517"\r
+   version="1.1"\r
+   inkscape:version="0.48+devel r12274"\r
+   sodipodi:docname="Juju_charm_icon_template.svg">\r
+  <defs\r
+     id="defs6519">\r
+    <linearGradient\r
+       inkscape:collect="always"\r
+       xlink:href="#Background"\r
+       id="linearGradient6461"\r
+       gradientUnits="userSpaceOnUse"\r
+       x1="0"\r
+       y1="970.29498"\r
+       x2="144"\r
+       y2="970.29498"\r
+       gradientTransform="matrix(0,-0.66666669,0.6660448,0,-866.25992,731.29077)" />\r
+    <linearGradient\r
+       id="Background">\r
+      <stop\r
+         id="stop4178"\r
+         offset="0"\r
+         style="stop-color:#b8b8b8;stop-opacity:1" />\r
+      <stop\r
+         id="stop4180"\r
+         offset="1"\r
+         style="stop-color:#c9c9c9;stop-opacity:1" />\r
+    </linearGradient>\r
+    <filter\r
+       style="color-interpolation-filters:sRGB;"\r
+       inkscape:label="Inner Shadow"\r
+       id="filter1121">\r
+      <feFlood\r
+         flood-opacity="0.59999999999999998"\r
+         flood-color="rgb(0,0,0)"\r
+         result="flood"\r
+         id="feFlood1123" />\r
+      <feComposite\r
+         in="flood"\r
+         in2="SourceGraphic"\r
+         operator="out"\r
+         result="composite1"\r
+         id="feComposite1125" />\r
+      <feGaussianBlur\r
+         in="composite1"\r
+         stdDeviation="1"\r
+         result="blur"\r
+         id="feGaussianBlur1127" />\r
+      <feOffset\r
+         dx="0"\r
+         dy="2"\r
+         result="offset"\r
+         id="feOffset1129" />\r
+      <feComposite\r
+         in="offset"\r
+         in2="SourceGraphic"\r
+         operator="atop"\r
+         result="composite2"\r
+         id="feComposite1131" />\r
+    </filter>\r
+    <filter\r
+       style="color-interpolation-filters:sRGB;"\r
+       inkscape:label="Drop Shadow"\r
+       id="filter950">\r
+      <feFlood\r
+         flood-opacity="0.25"\r
+         flood-color="rgb(0,0,0)"\r
+         result="flood"\r
+         id="feFlood952" />\r
+      <feComposite\r
+         in="flood"\r
+         in2="SourceGraphic"\r
+         operator="in"\r
+         result="composite1"\r
+         id="feComposite954" />\r
+      <feGaussianBlur\r
+         in="composite1"\r
+         stdDeviation="1"\r
+         result="blur"\r
+         id="feGaussianBlur956" />\r
+      <feOffset\r
+         dx="0"\r
+         dy="1"\r
+         result="offset"\r
+         id="feOffset958" />\r
+      <feComposite\r
+         in="SourceGraphic"\r
+         in2="offset"\r
+         operator="over"\r
+         result="composite2"\r
+         id="feComposite960" />\r
+    </filter>\r
+    <clipPath\r
+       clipPathUnits="userSpaceOnUse"\r
+       id="clipPath873">\r
+      <g\r
+         transform="matrix(0,-0.66666667,0.66604479,0,-258.25992,677.00001)"\r
+         id="g875"\r
+         inkscape:label="Layer 1"\r
+         style="fill:#ff00ff;fill-opacity:1;stroke:none;display:inline">\r
+        <path\r
+           style="fill:#ff00ff;fill-opacity:1;stroke:none;display:inline"\r
+           d="m 46.702703,898.22775 50.594594,0 C 138.16216,898.22775 144,904.06497 144,944.92583 l 0,50.73846 c 0,40.86071 -5.83784,46.69791 -46.702703,46.69791 l -50.594594,0 C 5.8378378,1042.3622 0,1036.525 0,995.66429 L 0,944.92583 C 0,904.06497 5.8378378,898.22775 46.702703,898.22775 Z"\r
+           id="path877"\r
+           inkscape:connector-curvature="0"\r
+           sodipodi:nodetypes="sssssssss" />\r
+      </g>\r
+    </clipPath>\r
+    <filter\r
+       inkscape:collect="always"\r
+       id="filter891"\r
+       inkscape:label="Badge Shadow">\r
+      <feGaussianBlur\r
+         inkscape:collect="always"\r
+         stdDeviation="0.71999962"\r
+         id="feGaussianBlur893" />\r
+    </filter>\r
+  </defs>\r
+  <sodipodi:namedview\r
+     id="base"\r
+     pagecolor="#ffffff"\r
+     bordercolor="#666666"\r
+     borderopacity="1.0"\r
+     inkscape:pageopacity="0.0"\r
+     inkscape:pageshadow="2"\r
+     inkscape:zoom="4.0745362"\r
+     inkscape:cx="18.514671"\r
+     inkscape:cy="49.018169"\r
+     inkscape:document-units="px"\r
+     inkscape:current-layer="layer1"\r
+     showgrid="true"\r
+     fit-margin-top="0"\r
+     fit-margin-left="0"\r
+     fit-margin-right="0"\r
+     fit-margin-bottom="0"\r
+     inkscape:window-width="1920"\r
+     inkscape:window-height="1029"\r
+     inkscape:window-x="0"\r
+     inkscape:window-y="24"\r
+     inkscape:window-maximized="1"\r
+     showborder="true"\r
+     showguides="true"\r
+     inkscape:guide-bbox="true"\r
+     inkscape:showpageshadow="false">\r
+    <inkscape:grid\r
+       type="xygrid"\r
+       id="grid821" />\r
+    <sodipodi:guide\r
+       orientation="1,0"\r
+       position="16,48"\r
+       id="guide823" />\r
+    <sodipodi:guide\r
+       orientation="0,1"\r
+       position="64,80"\r
+       id="guide825" />\r
+    <sodipodi:guide\r
+       orientation="1,0"\r
+       position="80,40"\r
+       id="guide827" />\r
+    <sodipodi:guide\r
+       orientation="0,1"\r
+       position="64,16"\r
+       id="guide829" />\r
+  </sodipodi:namedview>\r
+  <metadata\r
+     id="metadata6522">\r
+    <rdf:RDF>\r
+      <cc:Work\r
+         rdf:about="">\r
+        <dc:format>image/svg+xml</dc:format>\r
+        <dc:type\r
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />\r
+        <dc:title></dc:title>\r
+      </cc:Work>\r
+    </rdf:RDF>\r
+  </metadata>\r
+  <g\r
+     inkscape:label="BACKGROUND"\r
+     inkscape:groupmode="layer"\r
+     id="layer1"\r
+     transform="translate(268,-635.29076)"\r
+     style="display:inline">\r
+    <path\r
+       style="fill:url(#linearGradient6461);fill-opacity:1;stroke:none;display:inline;filter:url(#filter1121)"\r
+       d="m -268,700.15563 0,-33.72973 c 0,-27.24324 3.88785,-31.13513 31.10302,-31.13513 l 33.79408,0 c 27.21507,0 31.1029,3.89189 31.1029,31.13513 l 0,33.72973 c 0,27.24325 -3.88783,31.13514 -31.1029,31.13514 l -33.79408,0 C -264.11215,731.29077 -268,727.39888 -268,700.15563 Z"\r
+       id="path6455"\r
+       inkscape:connector-curvature="0"\r
+       sodipodi:nodetypes="sssssssss" />\r
+  </g>\r
+  <g\r
+     inkscape:groupmode="layer"\r
+     id="layer3"\r
+     inkscape:label="PLACE YOUR PICTOGRAM HERE"\r
+     style="display:inline" />\r
+  <g\r
+     inkscape:groupmode="layer"\r
+     id="layer2"\r
+     inkscape:label="BADGE"\r
+     style="display:none"\r
+     sodipodi:insensitive="true">\r
+    <g\r
+       style="display:inline"\r
+       transform="translate(-340.00001,-581)"\r
+       id="g4394"\r
+       clip-path="none">\r
+      <g\r
+         id="g855">\r
+        <g\r
+           inkscape:groupmode="maskhelper"\r
+           id="g870"\r
+           clip-path="url(#clipPath873)"\r
+           style="opacity:0.6;filter:url(#filter891)">\r
+          <path\r
+             transform="matrix(1.4999992,0,0,1.4999992,-29.999795,-237.54282)"\r
+             d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"\r
+             sodipodi:ry="12"\r
+             sodipodi:rx="12"\r
+             sodipodi:cy="552.36218"\r
+             sodipodi:cx="252"\r
+             id="path844"\r
+             style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"\r
+             sodipodi:type="arc" />\r
+        </g>\r
+        <g\r
+           id="g862">\r
+          <path\r
+             sodipodi:type="arc"\r
+             style="color:#000000;fill:#f5f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"\r
+             id="path4398"\r
+             sodipodi:cx="252"\r
+             sodipodi:cy="552.36218"\r
+             sodipodi:rx="12"\r
+             sodipodi:ry="12"\r
+             d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"\r
+             transform="matrix(1.4999992,0,0,1.4999992,-29.999795,-238.54282)" />\r
+          <path\r
+             transform="matrix(1.25,0,0,1.25,33,-100.45273)"\r
+             d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"\r
+             sodipodi:ry="12"\r
+             sodipodi:rx="12"\r
+             sodipodi:cy="552.36218"\r
+             sodipodi:cx="252"\r
+             id="path4400"\r
+             style="color:#000000;fill:#dd4814;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"\r
+             sodipodi:type="arc" />\r
+          <path\r
+             sodipodi:type="star"\r
+             style="color:#000000;fill:#f5f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"\r
+             id="path4459"\r
+             sodipodi:sides="5"\r
+             sodipodi:cx="666.19574"\r
+             sodipodi:cy="589.50385"\r
+             sodipodi:r1="7.2431178"\r
+             sodipodi:r2="4.3458705"\r
+             sodipodi:arg1="1.0471976"\r
+             sodipodi:arg2="1.6755161"\r
+             inkscape:flatsided="false"\r
+             inkscape:rounded="0.1"\r
+             inkscape:randomized="0"\r
+             d="m 669.8173,595.77657 c -0.39132,0.22593 -3.62645,-1.90343 -4.07583,-1.95066 -0.44938,-0.0472 -4.05653,1.36297 -4.39232,1.06062 -0.3358,-0.30235 0.68963,-4.03715 0.59569,-4.47913 -0.0939,-0.44198 -2.5498,-3.43681 -2.36602,-3.8496 0.18379,-0.41279 4.05267,-0.59166 4.44398,-0.81759 0.39132,-0.22593 2.48067,-3.48704 2.93005,-3.4398 0.44938,0.0472 1.81505,3.67147 2.15084,3.97382 0.3358,0.30236 4.08294,1.2817 4.17689,1.72369 0.0939,0.44198 -2.9309,2.86076 -3.11469,3.27355 C 669.9821,591.68426 670.20862,595.55064 669.8173,595.77657 Z"\r
+             transform="matrix(1.511423,-0.16366377,0.16366377,1.511423,-755.37346,-191.93651)" />\r
+        </g>\r
+      </g>\r
+    </g>\r
+  </g>\r
+</svg>\r
diff --git a/layers/vyos-proxy/layer.yaml b/layers/vyos-proxy/layer.yaml
new file mode 100644 (file)
index 0000000..16ac9ce
--- /dev/null
@@ -0,0 +1,12 @@
+"options":
+  "basic":
+    "packages":
+    - "python-dev"
+    - "libffi-dev"
+    - "libssl-dev"
+    "use_venv": !!bool "false"
+    "include_system_packages": !!bool "false"
+  "vyos-proxy": {}
+"includes":
+- "layer:basic"
+"is": "vyos-proxy"
diff --git a/layers/vyos-proxy/metadata.yaml b/layers/vyos-proxy/metadata.yaml
new file mode 100644 (file)
index 0000000..1d29b37
--- /dev/null
@@ -0,0 +1,12 @@
+"name": "vyos-proxy"
+"summary": "VyOS Proxy charm for ping"
+"description": |
+  VyOS Proxy charm
+"tags":
+- "vnf"
+- "network"
+"maintainers":
+- "Marco Ceppi <marco.ceppi@canonical.com>"
+"series":
+- "xenial"
+- "trusty"
diff --git a/layers/vyos-proxy/reactive/__init__.py b/layers/vyos-proxy/reactive/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/layers/vyos-proxy/reactive/vyos_proxy.py b/layers/vyos-proxy/reactive/vyos_proxy.py
new file mode 100644 (file)
index 0000000..a8fd5e0
--- /dev/null
@@ -0,0 +1,99 @@
+
+import subprocess
+import paramiko
+
+from charmhelpers.core.hookenv import (
+    config,
+    status_set,
+    action_get,
+    action_set,
+    action_fail,
+)
+
+from charms.reactive import (
+    when,
+    when_not,
+    set_state as set_flag,
+    remove_state as remove_flag,
+)
+
+
+@when('config.changed')
+def test_connection():
+    status_set('maintenance', 'configuring ssh connection')
+    remove_flag('vyos-proxy.ready')
+    try:
+        who, _ = run('whoami')
+    except MgmtNotConfigured as e:
+        remove_flag('vyos-proxy.configured')
+        status_set('blocked', str(e))
+    except subprocess.CalledProcessError as e:
+        remove_flag('vyos-proxy.configured')
+        status_set('blocked', e.output)
+    else:
+        set_flag('vyos-proxy.configured')
+
+
+@when('vyos-proxy.configured')
+@when_not('vyos-proxy.ready')
+def vyos_proxy_ready():
+    status_set('active', 'ready')
+    set_flag('vyos-proxy.ready')
+
+
+@when('actions.ping')
+@when_not('vyos-proxy.configured')
+def pingme():
+    action_fail('proxy is not ready')
+
+
+@when('actions.ping')
+@when('vyos-proxy.configured')
+def pingme_forreal():
+    try:
+        result, err = run('ping -qc {} {}'.format(action_get('count'), action_get('destination')))
+    except:
+        action_fail('ping command failed')
+    finally:
+        remove_flag('actions.ping')
+
+    # Here you can send results back from ping, if you had time to parse it
+    action_set({'output': result})
+
+
+
+class MgmtNotConfigured(Exception):
+    pass
+
+
+def run(cmd):
+    ''' Suddenly this project needs to SSH to something. So we replicate what
+        _run was doing with subprocess using the Paramiko library. This is
+        temporary until this charm /is/ the VPE Router '''
+
+    cfg = config()
+
+    hostname = cfg.get('hostname')
+    password = cfg.get('pass')
+    username = cfg.get('user')
+
+    if not (username and password and hostname):
+        raise MgmtNotConfigured('incomplete remote credentials')
+
+    client = paramiko.SSHClient()
+    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+
+    try:
+        client.connect(cfg.get('hostname'), port=22,
+                       username=cfg.get('user'), password=cfg.get('pass'))
+    except paramiko.ssh_exception.AuthenticationException:
+        raise MgmtNotConfigured('invalid credentials')
+
+    stdin, stdout, stderr = client.exec_command(cmd)
+    retcode = stdout.channel.recv_exit_status()
+    client.close()  # @TODO re-use connections
+    if retcode > 0:
+        output = stderr.read().strip()
+        raise subprocess.CalledProcessError(returncode=retcode, cmd=cmd,
+                                            output=output)
+    return (''.join(stdout), ''.join(stderr))
diff --git a/layers/vyos-proxy/requirements.txt b/layers/vyos-proxy/requirements.txt
new file mode 100644 (file)
index 0000000..28ecaca
--- /dev/null
@@ -0,0 +1,2 @@
+flake8
+pytest
diff --git a/layers/vyos-proxy/revision b/layers/vyos-proxy/revision
new file mode 100644 (file)
index 0000000..c227083
--- /dev/null
@@ -0,0 +1 @@
+0
\ No newline at end of file
diff --git a/layers/vyos-proxy/tox.ini b/layers/vyos-proxy/tox.ini
new file mode 100644 (file)
index 0000000..0b8b27a
--- /dev/null
@@ -0,0 +1,12 @@
+[tox]
+skipsdist=True
+envlist = py34, py35
+skip_missing_interpreters = True
+
+[testenv]
+commands = py.test -v
+deps =
+    -r{toxinidir}/requirements.txt
+
+[flake8]
+exclude=docs
diff --git a/layers/vyos-proxy/wheelhouse.txt b/layers/vyos-proxy/wheelhouse.txt
new file mode 100644 (file)
index 0000000..24d2c9c
--- /dev/null
@@ -0,0 +1 @@
+paramiko==2.0.1