From 4c64770343600815f626beaba26dbc138f0947f7 Mon Sep 17 00:00:00 2001 From: Chris MacNaughton Date: Thu, 10 Oct 2019 16:28:02 +0200 Subject: [PATCH] initial commit --- .gitignore | 6 + LICENSE | 202 ++++++++++++++++ copyright | 16 ++ rebuild | 5 + requirements.txt | 3 + src/README.ex | 65 +++++ src/config.yaml | 40 ++++ src/icon.svg | 279 ++++++++++++++++++++++ src/layer.yaml | 12 + src/lib/__init__.py | 13 + src/lib/charm/__init__.py | 13 + src/lib/charm/openstack/__init__.py | 13 + src/lib/charm/openstack/manila_ganesha.py | 134 +++++++++++ src/metadata.yaml | 28 +++ src/reactive/manila_ganesha.py | 75 ++++++ src/templates/rocky/api-paste.ini | 59 +++++ src/templates/rocky/logging.conf | 77 ++++++ src/templates/rocky/manila.conf | 57 +++++ src/test-requirements.txt | 11 + src/tests/bundles/bionic-rocky.yaml | 73 ++++++ src/tests/bundles/bionic-stein.yaml | 75 ++++++ src/tests/tests.yaml | 12 + src/tox.ini | 105 ++++++++ src/wheelhouse.txt | 3 + test-requirements.txt | 15 ++ tox.ini | 97 ++++++++ 26 files changed, 1488 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 copyright create mode 100644 rebuild create mode 100644 requirements.txt create mode 100644 src/README.ex create mode 100644 src/config.yaml create mode 100644 src/icon.svg create mode 100644 src/layer.yaml create mode 100644 src/lib/__init__.py create mode 100644 src/lib/charm/__init__.py create mode 100644 src/lib/charm/openstack/__init__.py create mode 100644 src/lib/charm/openstack/manila_ganesha.py create mode 100644 src/metadata.yaml create mode 100644 src/reactive/manila_ganesha.py create mode 100644 src/templates/rocky/api-paste.ini create mode 100644 src/templates/rocky/logging.conf create mode 100644 src/templates/rocky/manila.conf create mode 100644 src/test-requirements.txt create mode 100644 src/tests/bundles/bionic-rocky.yaml create mode 100644 src/tests/bundles/bionic-stein.yaml create mode 100644 src/tests/tests.yaml create mode 100644 src/tox.ini create mode 100644 src/wheelhouse.txt create mode 100644 test-requirements.txt create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c364bcd --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.tox +.stestr +*__pycache__* +*.pyc +build +.idea \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/copyright b/copyright new file mode 100644 index 0000000..a6441e1 --- /dev/null +++ b/copyright @@ -0,0 +1,16 @@ +Format: http://dep.debian.net/deps/dep5/ + +Files: * +Copyright: Copyright 2017, Canonical Ltd. +License: GPL-3 + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License version 3, as + published by the Free Software Foundation. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranties of + MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + PURPOSE. See the GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see . diff --git a/rebuild b/rebuild new file mode 100644 index 0000000..538bb06 --- /dev/null +++ b/rebuild @@ -0,0 +1,5 @@ +# This file is used to trigger rebuilds +# when dependencies of the charm change, +# but nothing in the charm needs to. +# simply change the uuid to something new +f57f307b-74f9-4f1d-bdc2-50e20aecbb63 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..bad6c5d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +# Build requirements +charm-tools>=2.4.4 +simplejson diff --git a/src/README.ex b/src/README.ex new file mode 100644 index 0000000..b6816b2 --- /dev/null +++ b/src/README.ex @@ -0,0 +1,65 @@ +# 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/src/config.yaml b/src/config.yaml new file mode 100644 index 0000000..e07c8af --- /dev/null +++ b/src/config.yaml @@ -0,0 +1,40 @@ +options: + openstack-origin: + default: distro + type: string + description: | + Repository from which to install. May be one of the following: + distro (default), ppa:somecustom/ppa, a deb url sources entry, + or a supported Cloud Archive release pocket. + + Supported Cloud Archive sources include: cloud:precise-folsom, + cloud:precise-folsom/updates, cloud:precise-folsom/staging, + cloud:precise-folsom/proposed. + + Note that updating this setting to a source that is known to + provide a later version of OpenStack will trigger a software + upgrade. + rabbit-user: + default: manila + type: string + description: Username used to access rabbitmq queue + rabbit-vhost: + default: openstack + type: string + description: Rabbitmq vhost + database-user: + default: manila + type: string + description: Username for Manila database access + database: + default: manila + type: string + description: Database name for Manila + debug: + default: False + type: boolean + description: Enable debug logging + verbose: + default: False + type: boolean + description: Enable verbose logging \ No newline at end of file diff --git a/src/icon.svg b/src/icon.svg new file mode 100644 index 0000000..96a5d0c --- /dev/null +++ b/src/icon.svg @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/src/layer.yaml b/src/layer.yaml new file mode 100644 index 0000000..127dd73 --- /dev/null +++ b/src/layer.yaml @@ -0,0 +1,12 @@ +includes: + - layer:openstack-api + - layer:ceph + - interface:ceph-client + - interface:mysql-shared + - interface:rabbitmq + - interface:keystone-credentials + - interface:manila-plugin +options: + basic: + use_venv: True + include_system_packages: False \ No newline at end of file diff --git a/src/lib/__init__.py b/src/lib/__init__.py new file mode 100644 index 0000000..5705e5d --- /dev/null +++ b/src/lib/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2019 Canonical Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/src/lib/charm/__init__.py b/src/lib/charm/__init__.py new file mode 100644 index 0000000..5705e5d --- /dev/null +++ b/src/lib/charm/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2019 Canonical Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/src/lib/charm/openstack/__init__.py b/src/lib/charm/openstack/__init__.py new file mode 100644 index 0000000..5705e5d --- /dev/null +++ b/src/lib/charm/openstack/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2019 Canonical Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/src/lib/charm/openstack/manila_ganesha.py b/src/lib/charm/openstack/manila_ganesha.py new file mode 100644 index 0000000..16633f7 --- /dev/null +++ b/src/lib/charm/openstack/manila_ganesha.py @@ -0,0 +1,134 @@ +# Copyright 2019 Canonical Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import collections +# import json +# import socket +# import subprocess + +# import charms.reactive as reactive + +import charms_openstack.charm +import charms_openstack.adapters +import charms_openstack.plugins +from charms_openstack.ip import resolve_address + +# import charmhelpers.core as ch_core + + +MANILA_DIR = '/etc/manila/' +MANILA_CONF = MANILA_DIR + "manila.conf" +MANILA_LOGGING_CONF = MANILA_DIR + "logging.conf" +MANILA_API_PASTE_CONF = MANILA_DIR + "api-paste.ini" + + +@charms_openstack.adapters.config_property +def access_ip(config): + """Return the list of lines from the backends that need to go into the + various configuration files. + + This one is for manila.conf + :returns list of lines: the config for the manila.conf file + """ + return config.charm_instance.access_ip() + + +class GaneshaCharmRelationAdapters( + charms_openstack.adapters.OpenStackRelationAdapters): + relation_adapters = { + 'amqp': charms_openstack.adapters.RabbitMQRelationAdapter, + 'ceph': charms_openstack.plugins.CephRelationAdapter, + 'manila-gahesha': charms_openstack.adapters.OpenStackRelationAdapter, + } + + +class ManilaGaneshaCharm(charms_openstack.charm.HAOpenStackCharm, + charms_openstack.plugins.BaseOpenStackCephCharm, + ): + release = 'rocky' + name = 'ganesha' + python_version = 3 + source_config_key = 'openstack-origin' + packages = [ + 'ceph-common', + 'nfs-ganesha-ceph', + 'manila-share', + 'python3-manila', + ] + required_relations = [ + 'amqp', + 'ceph', + 'identity-service', + 'shared-db', + ] + group = 'manila' + adapters_class = GaneshaCharmRelationAdapters + ceph_key_per_unit_name = True + services = [ + 'nfs-ganesha', + 'manila-share', + ] + ha_resources = ['vips', 'dnsha'] + release_pkg = 'manila-common' + + package_codenames = { + 'manila-common': collections.OrderedDict([ + ('7', 'rocky'), + ('8', 'stein'), + ('9', 'train'), + ]), + } + + @property + def restart_map(self): + services = self.services + return { + MANILA_CONF: ['manila-share'], + MANILA_API_PASTE_CONF: ['manila-share'], + MANILA_LOGGING_CONF: ['manila-share'], + + } + + @property + def access_ip(self): + resolve_address() + + def enable_memcache(self, *args, **kwargs): + return False + + def get_amqp_credentials(self): + """Provide the default amqp username and vhost as a tuple. + + :returns (username, host): two strings to send to the amqp provider. + """ + return (self.options.rabbit_user, self.options.rabbit_vhost) + + def get_database_setup(self): + """Provide the default database credentials as a list of 3-tuples + + returns a structure of: + [ + {'database': , + 'username': , + 'hostname': + 'prefix': , }, + ] + + :returns [{'database': ...}, ...]: credentials for multiple databases + """ + return [ + dict( + database=self.options.database, + username=self.options.database_user, ) + ] diff --git a/src/metadata.yaml b/src/metadata.yaml new file mode 100644 index 0000000..d5b53f2 --- /dev/null +++ b/src/metadata.yaml @@ -0,0 +1,28 @@ +name: manila-ganesha +summary: Manila-Ganesha allows binding Manila to CephFS via Ganesha +maintainer: OpenStack Charmers +description: | + Nfs-ganesha is a user-mode file server for NFS v3, 4.0, 4.1, 4.1 pNFS, + and 4.2; and for 9P from the Plan9 operating system. It can support + all these protocols concurrently. Manila-Ganesha allows connecting + a Manila server to a Ceph cluster via CephFS. +tags: + - storage + - file-servers +series: + - bionic + - disco + - eoan +subordinate: false +provides: + manila-plugin: + interface: manila-plugin +requires: + ceph: + interface: ceph-client + shared-db: + interface: mysql-shared + amqp: + interface: rabbitmq + identity-service: + interface: keystone-credentials \ No newline at end of file diff --git a/src/reactive/manila_ganesha.py b/src/reactive/manila_ganesha.py new file mode 100644 index 0000000..3534551 --- /dev/null +++ b/src/reactive/manila_ganesha.py @@ -0,0 +1,75 @@ +import charms.reactive as reactive + +import charms_openstack.bus +import charms_openstack.charm as charm +import charms.reactive.relations as relations + +import charmhelpers.core as ch_core + + +charms_openstack.bus.discover() + +# Use the charms.openstack defaults for common states and hooks +charm.use_defaults( + 'charm.installed', + 'amqp.connected', + 'shared-db.connected', + # 'identity-service.connected', + 'config.changed', + 'update-status', + 'upgrade-charm', + 'certificates.available', +) + + +@reactive.when('ceph.connected') +@reactive.when_not('ceph.available') +def storage_ceph_connected(ceph): + ceph.create_pool(ch_core.hookenv.service_name()) + + +@reactive.when('manila-plugin.available') +def setup_manila(): + manila_relation = relations.endpoint_from_flag('manila-plugin.available') + manila_relation.name = 'ganesha' + manila_relation.configuration_data = { + 'complete': True, + } + +@reactive.when_not('identity-service.available') +@reactive.when('identity-service.connected') +def configure_ident_username(keystone): + """Requests a user to the Identity Service + """ + username = 'manila' + keystone.register_endpoints(username, 'None', 'None', 'None', 'None') + + +@reactive.when('ceph.available', + 'amqp.available', + 'manila-plugin.available', + 'shared-db.available', + 'identity-service.available', + ) +def render_things(*args): + with charm.provide_charm_instance() as charm_instance: + ceph_relation = relations.endpoint_from_flag('ceph.available') + if not ceph_relation.key: + ch_core.hookenv.log( + ( + 'Ceph endpoint "{}" flagged available yet ' + 'no key. Relation is probably departing.' + ).format(ceph_relation.relation_name), + level=ch_core.hookenv.INFO) + return + ch_core.hookenv.log('Ceph endpoint "{}" available, configuring ' + 'keyring'.format(ceph_relation.relation_name), + level=ch_core.hookenv.INFO) + + charm_instance.configure_ceph_keyring(ceph_relation.key()) + charm_instance.render_with_interfaces(args) + for service in charm_instance.services: + ch_core.host.service('enable', service) + ch_core.host.service('start', service) + reactive.set_flag('config.rendered') + charm_instance.assess_status() diff --git a/src/templates/rocky/api-paste.ini b/src/templates/rocky/api-paste.ini new file mode 100644 index 0000000..4e0f32e --- /dev/null +++ b/src/templates/rocky/api-paste.ini @@ -0,0 +1,59 @@ +############# +# OpenStack # +############# + +[composite:osapi_share] +use = call:manila.api:root_app_factory +/: apiversions +/v1: openstack_share_api +/v2: openstack_share_api_v2 + +[composite:openstack_share_api] +use = call:manila.api.middleware.auth:pipeline_factory +noauth = cors faultwrap ssl sizelimit noauth api +keystone = cors faultwrap ssl sizelimit authtoken keystonecontext api +keystone_nolimit = cors faultwrap ssl sizelimit authtoken keystonecontext api + +[composite:openstack_share_api_v2] +use = call:manila.api.middleware.auth:pipeline_factory +noauth = cors faultwrap ssl sizelimit noauth apiv2 +keystone = cors faultwrap ssl sizelimit authtoken keystonecontext apiv2 +keystone_nolimit = cors faultwrap ssl sizelimit authtoken keystonecontext apiv2 + +[filter:faultwrap] +paste.filter_factory = manila.api.middleware.fault:FaultWrapper.factory + +[filter:noauth] +paste.filter_factory = manila.api.middleware.auth:NoAuthMiddleware.factory + +[filter:sizelimit] +paste.filter_factory = oslo_middleware.sizelimit:RequestBodySizeLimiter.factory + +[filter:ssl] +paste.filter_factory = oslo_middleware.ssl:SSLMiddleware.factory + +[app:api] +paste.app_factory = manila.api.v1.router:APIRouter.factory + +[app:apiv2] +paste.app_factory = manila.api.v2.router:APIRouter.factory + +[pipeline:apiversions] +pipeline = cors faultwrap osshareversionapp + +[app:osshareversionapp] +paste.app_factory = manila.api.versions:VersionsRouter.factory + +########## +# Shared # +########## + +[filter:keystonecontext] +paste.filter_factory = manila.api.middleware.auth:ManilaKeystoneContext.factory + +[filter:authtoken] +paste.filter_factory = keystonemiddleware.auth_token:filter_factory + +[filter:cors] +paste.filter_factory = oslo_middleware.cors:filter_factory +oslo_config_project = manila diff --git a/src/templates/rocky/logging.conf b/src/templates/rocky/logging.conf new file mode 100644 index 0000000..8de2024 --- /dev/null +++ b/src/templates/rocky/logging.conf @@ -0,0 +1,77 @@ +[loggers] +keys = root, manila + +[handlers] +keys = stderr, stdout, watchedfile, syslog, null + +[formatters] +keys = legacymanila, default + +[logger_root] +level = {{ options.computed_debug_level }} +handlers = null + +[logger_manila] +# level = INFO +level = {{ options.computed_debug_level }} +handlers = stderr +qualname = manila + +[logger_amqplib] +level = WARNING +handlers = stderr +qualname = amqplib + +[logger_sqlalchemy] +level = WARNING +handlers = stderr +qualname = sqlalchemy +# "level = INFO" logs SQL queries. +# "level = DEBUG" logs SQL queries and results. +# "level = WARNING" logs neither. (Recommended for production systems.) + +[logger_boto] +level = WARNING +handlers = stderr +qualname = boto + +[logger_suds] +level = INFO +handlers = stderr +qualname = suds + +[logger_eventletwsgi] +level = WARNING +handlers = stderr +qualname = eventlet.wsgi.server + +[handler_stderr] +class = StreamHandler +args = (sys.stderr,) +formatter = legacymanila + +[handler_stdout] +class = StreamHandler +args = (sys.stdout,) +formatter = legacymanila + +[handler_watchedfile] +class = handlers.WatchedFileHandler +args = ('manila.log',) +formatter = legacymanila + +[handler_syslog] +class = handlers.SysLogHandler +args = ('/dev/log', handlers.SysLogHandler.LOG_USER) +formatter = legacymanila + +[handler_null] +class = manila.common.openstack.NullHandler +formatter = default +args = () + +[formatter_legacymanila] +class = manila.openstack.common.log.LegacyFormatter + +[formatter_default] +format = %(message)s diff --git a/src/templates/rocky/manila.conf b/src/templates/rocky/manila.conf new file mode 100644 index 0000000..0fb68fd --- /dev/null +++ b/src/templates/rocky/manila.conf @@ -0,0 +1,57 @@ +# Note that the original manila.conf file is extensive and has many options +# that the charm does not set. Please refer to that file if there are options +# that you think the charm should set, but doesn't, or provide options for. +# Please file a bug at: https://bugs.launchpad.net/charm-barbican/+filebug for +# any changes you need made or intend to modify in the charm. + +[DEFAULT] + +osapi_share_extension = manila.api.contrib.standard_extenstions +rootwrap_config = /etc/manila/rootwrap.conf +api_paste_config = /etc/manila/api-paste.ini +share_name_template = share-%s + +my_ip = {{ options.access_ip }} + +scheduler_driver = manila.scheduler.drivers.filter.FilterScheduler + +debug = {{ options.debug }} + +# Number of workers for OpenStack Share API service. (integer value) +osapi_share_workers = {{ options.workers }} + +{% include "parts/section-transport-url" %} + +# parts/section-database includes the [database] section identifier +{% include "parts/section-database" %} + + +# parts/section-keystone-authtoken includes the [keystone_authtoken] section +# identifier +{% include "parts/section-keystone-authtoken" %} + +[oslo_messaging_amqp] + +# +# From oslo.messaging +# + +[oslo_messaging_notifications] + +# +# From oslo.messaging +# + +{% include "parts/section-oslo-messaging-rabbit" %} + +[ganesha] +driver_handles_share_servers = False +share_backend_name = GANESHA +share_driver = manila.share.drivers.cephfs.driver.CephFSDriver +cephfs_protocol_helper_type = NFS +cephfs_conf_path = /etc/ceph/ceph.conf +cephfs_auth_id = manila +cephfs_cluster_name = ceph +cephfs_enable_snapshots = False +cephfs_ganesha_server_is_remote = False +cephfs_ganesha_server_ip = {{ options.access_ip }} diff --git a/src/test-requirements.txt b/src/test-requirements.txt new file mode 100644 index 0000000..f4a766d --- /dev/null +++ b/src/test-requirements.txt @@ -0,0 +1,11 @@ +# This file is managed centrally. If you find the need to modify this as a +# one-off, please don't. Intead, consult #openstack-charms and ask about +# requirements management in charms via bot-control. Thank you. +charm-tools>=2.4.4 +coverage>=3.6 +mock>=1.2 +flake8>=2.2.4,<=2.4.1 +stestr>=2.2.0 +requests>=2.18.4 +git+https://github.com/openstack-charmers/zaza.git#egg=zaza +git+https://github.com/openstack-charmers/zaza-openstack-tests.git#egg=zaza.openstack \ No newline at end of file diff --git a/src/tests/bundles/bionic-rocky.yaml b/src/tests/bundles/bionic-rocky.yaml new file mode 100644 index 0000000..5a374cc --- /dev/null +++ b/src/tests/bundles/bionic-rocky.yaml @@ -0,0 +1,73 @@ +series: bionic +variables: + source: &source cloud:bionic-rocky +services: + manila-ganesha: + num_units: 1 + series: bionic + charm: ../../../manila-ganesha + options: + openstack-origin: *source + ceph-mon: + charm: cs:~openstack-charmers-next/ceph-mon + num_units: 3 + options: + source: *source + ceph-osd: + charm: cs:~openstack-charmers-next/ceph-osd + num_units: 3 + options: + source: *source + storage: + osd-devices: 'cinder,10G' + ceph-fs: + charm: cs:~openstack-charmers-next/ceph-fs + num_units: 2 + options: + source: *source + manila: + charm: cs:~openstack-charmers-next/manila + num_units: 1 + options: + openstack-origin: *source + default-share-backend: ganesha + share-protocols: NFS + rabbitmq-server: + charm: cs:~openstack-charmers-next/rabbitmq-server + num_units: 1 + options: + source: *source + percona-cluster: + charm: cs:~openstack-charmers-next/percona-cluster + num_units: 1 + options: + source: *source + keystone: + charm: cs:~openstack-charmers-next/keystone + num_units: 1 + options: + openstack-origin: *source + +relations: + - - ceph-mon + - ceph-osd + - - ceph-mon + - ceph-fs + - - ceph-mon + - manila-ganesha + - - manila-ganesha + - percona-cluster + - - manila-ganesha + - rabbitmq-server + - - manila-ganesha + - keystone + - - manila + - manila-ganesha + - - manila + - rabbitmq-server + - - manila + - keystone + - - keystone + - percona-cluster + - - manila + - percona-cluster diff --git a/src/tests/bundles/bionic-stein.yaml b/src/tests/bundles/bionic-stein.yaml new file mode 100644 index 0000000..d495e70 --- /dev/null +++ b/src/tests/bundles/bionic-stein.yaml @@ -0,0 +1,75 @@ +series: bionic +options: + source: &source cloud:bionic-stein +services: + manila-ganesha: + num_units: 1 + series: bionic + charm: ../../../manila-ganesha + options: + openstack-origin: *source + ceph-mon: + charm: cs:~openstack-charmers-next/ceph-mon + num_units: 3 + options: + source: *source + ceph-osd: + charm: cs:~openstack-charmers-next/ceph-osd + num_units: 3 + options: + source: *source + storage: + osd-devices: 'cinder,10G' + ceph-fs: + charm: cs:~openstack-charmers-next/ceph-fs + num_units: 2 + options: + source: *source + manila: + # charm: cs:~openstack-charmers-next/manila + charm: /home/ubuntu/manila/build/builds/manila + num_units: 1 + options: + openstack-origin: *source + default-share-backend: ganesha + share-protocols: NFS + # default-share-type: + rabbitmq-server: + charm: cs:~openstack-charmers-next/rabbitmq-server + num_units: 1 + options: + source: *source + percona-cluster: + charm: cs:~openstack-charmers-next/percona-cluster + num_units: 1 + options: + source: *source + keystone: + charm: cs:~openstack-charmers-next/keystone + num_units: 1 + options: + openstack-origin: *source + +relations: + - - ceph-mon + - ceph-osd + - - ceph-mon + - ceph-fs + - - ceph-mon + - manila-ganesha + - - manila-ganesha + - percona-cluster + - - manila-ganesha + - rabbitmq-server + - - manila-ganesha + - keystone + - - manila + - manila-ganesha + - - manila + - rabbitmq-server + - - manila + - keystone + - - keystone + - percona-cluster + - - manila + - percona-cluster diff --git a/src/tests/tests.yaml b/src/tests/tests.yaml new file mode 100644 index 0000000..c6f9756 --- /dev/null +++ b/src/tests/tests.yaml @@ -0,0 +1,12 @@ +charm_name: manila-ganesha +configure: [] +dev_bundles: +- bionic +gate_bundles: +- bionic-rocky +- bionic-queens +- bionic-stein +smoke_bundles: +- bionic-stein +target_deploy_status: {} +tests: [] diff --git a/src/tox.ini b/src/tox.ini new file mode 100644 index 0000000..9934010 --- /dev/null +++ b/src/tox.ini @@ -0,0 +1,105 @@ +# Classic charm: ./tox.ini +# This file is managed centrally by release-tools and should not be modified +# within individual charm repos. +[tox] +envlist = pep8,py37 +skipsdist = True + +[testenv] +setenv = VIRTUAL_ENV={envdir} + PYTHONHASHSEED=0 + CHARM_DIR={envdir} + AMULET_SETUP_TIMEOUT=5400 +install_command = + pip install {opts} {packages} +commands = stestr run {posargs} +whitelist_externals = juju +passenv = HOME TERM AMULET_* CS_API_* +deps = -r{toxinidir}/test-requirements.txt + +[testenv:py27] +basepython = python2.7 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt +# temporarily disable py27 +commands = /bin/true + +[testenv:py3] +basepython = python3 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +; keep zuul happy until we change the py35 job +[testenv:py35] +basepython = python3.5 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +[testenv:py36] +basepython = python3.6 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +[testenv:py37] +basepython = python3.7 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +[testenv:pep8] +basepython = python3 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt +commands = flake8 {posargs} hooks unit_tests tests actions lib + charm-proof + +[testenv:cover] +# Technique based heavily upon +# https://github.com/openstack/nova/blob/master/tox.ini +basepython = python3 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt +setenv = + {[testenv]setenv} + PYTHON=coverage run +commands = + coverage erase + stestr run {posargs} + coverage combine + coverage html -d cover + coverage xml -o cover/coverage.xml + coverage report + +[coverage:run] +branch = True +concurrency = multiprocessing +parallel = True +source = + . +omit = + .tox/* + */charmhelpers/* + unit_tests/* + +[testenv:venv] +basepython = python3 +commands = {posargs} + + +[testenv:func] +basepython = python3 +commands = + functest-run-suite --keep-model + +[testenv:func-smoke] +basepython = python3 +commands = + functest-run-suite --keep-model --smoke + +[testenv:func-dev] +basepython = python3 +commands = + functest-run-suite --keep-model --dev + +[flake8] +ignore = E402,E226 +exclude = */charmhelpers diff --git a/src/wheelhouse.txt b/src/wheelhouse.txt new file mode 100644 index 0000000..17c1230 --- /dev/null +++ b/src/wheelhouse.txt @@ -0,0 +1,3 @@ + +jinja2 +psutil diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000..bc1ce30 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,15 @@ +# Lint and unit test requirements +flake8 +stestr>=2.2.0 +requests>=2.18.4 +charms.reactive +mock>=1.2 +nose>=1.3.7 +coverage>=3.6 +git+https://github.com/openstack/charms.openstack.git#egg=charms-openstack +netifaces # vault +hvac<0.7.0 # vault +psycopg2-binary # vault +tenacity # vault +pbr # vault +cryptography # vault diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..0deba4c --- /dev/null +++ b/tox.ini @@ -0,0 +1,97 @@ +# Source charm: ./tox.ini +# This file is managed centrally by release-tools and should not be modified +# within individual charm repos. +[tox] +skipsdist = True +envlist = pep8,py37 +# NOTE(beisner): Avoid build/test env pollution by not enabling sitepackages. +sitepackages = False +# NOTE(beisner): Avoid false positives by not skipping missing interpreters. +skip_missing_interpreters = False + +[testenv] +setenv = VIRTUAL_ENV={envdir} + PYTHONHASHSEED=0 + TERM=linux + LAYER_PATH={toxinidir}/layers + INTERFACE_PATH={toxinidir}/interfaces + JUJU_REPOSITORY={toxinidir}/build +passenv = http_proxy https_proxy USER +install_command = + pip install {opts} {packages} + +[testenv:build] +basepython = python2.7 +deps = + -r{toxinidir}/requirements.txt +commands = + charm-build --log-level DEBUG -o {toxinidir}/build src {posargs} + +[testenv:py27] +basepython = python2.7 +deps = +# Reactive source charms are Python3-only, but a py27 unit test target +# is required by OpenStack Governance. Remove this shim as soon as +# permitted. http://governance.openstack.org/reference/cti/python_cti.html +whitelist_externals = true +commands = true + +[testenv:py34] +basepython = python3.4 +deps = -r{toxinidir}/test-requirements.txt +commands = stestr run {posargs} + +[testenv:py35] +basepython = python3.5 +deps = -r{toxinidir}/test-requirements.txt +commands = stestr run {posargs} + +[testenv:py36] +basepython = python3.6 +deps = -r{toxinidir}/test-requirements.txt +commands = stestr run {posargs} + +[testenv:py37] +basepython = python3.7 +deps = -r{toxinidir}/test-requirements.txt +commands = stestr run {posargs} + +[testenv:pep8] +basepython = python3 +deps = -r{toxinidir}/test-requirements.txt +commands = flake8 {posargs} src unit_tests + +[testenv:cover] +# Technique based heavily upon +# https://github.com/openstack/nova/blob/master/tox.ini +basepython = python3 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt +setenv = + {[testenv]setenv} + PYTHON=coverage run +commands = + coverage erase + stestr run {posargs} + coverage combine + coverage html -d cover + coverage xml -o cover/coverage.xml + coverage report + +[coverage:run] +branch = True +concurrency = multiprocessing +parallel = True +source = + . +omit = + .tox/* + */charmhelpers/* + unit_tests/* + +[testenv:venv] +commands = {posargs} + +[flake8] +# E402 ignore necessary for path append before sys module import in actions +ignore = E402,W504