Initial Cookiecutter Commit.

This commit is contained in:
Gustavo Sanchez 2021-11-23 10:42:36 -04:00
commit cb09203a67
No known key found for this signature in database
GPG Key ID: CB6FDA23F1075685
18 changed files with 574 additions and 0 deletions

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
build
layers
.tox
interfaces
.testrepository
.stestr
*__pycache__*
*.pyc
/*.charm

3
.stestr.conf Normal file
View File

@ -0,0 +1,3 @@
[DEFAULT]
test_path=./unit_tests
top_dir=./

19
README.md Normal file
View File

@ -0,0 +1,19 @@
Solidfire Storage Backend for Cinder
-------------------------------
Overview
========
This charm provides a Solidfire storage backend for use with the Cinder
charm.
To use:
juju deploy cinder
juju deploy cinder-solidfire
juju add-relation cinder-solidfire cinder
Configuration
=============
See config.yaml for details of configuration options.

1
build-requirements.txt Normal file
View File

@ -0,0 +1 @@
git+https://github.com/canonical/charmcraft.git@0.10.2#egg=charmcraft

5
config.yaml Normal file
View File

@ -0,0 +1,5 @@
options:
volume-dd-blocksize:
default: 1024
description: Disk block size for the volume
type: int

24
metadata.yaml Normal file
View File

@ -0,0 +1,24 @@
name: cinder-solidfire
summary: Solidfire integration for OpenStack Block Storage
maintainer: OpenStack Charmers <openstack-charmers@lists.ubuntu.com>
description: |
Cinder is the block storage service for the Openstack project.
.
This charm provides a Solidfire backend for Cinder
tags:
- openstack
- storage
- file-servers
- misc
series:
- focal
- bionic
subordinate: true
provides:
storage-backend:
interface: cinder-backend
scope: container
requires:
juju-info:
interface: juju-info
scope: container

18
pip.sh Executable file
View File

@ -0,0 +1,18 @@
#!/usr/bin/env bash
#
# This file is managed centrally by release-tools and should not be modified
# within individual charm repos. See the 'global' dir contents for available
# choices of tox.ini for OpenStack Charms:
# https://github.com/openstack-charmers/release-tools
#
# setuptools 58.0 dropped the support for use_2to3=true which is needed to
# install blessings (an indirect dependency of charm-tools).
#
# More details on the beahvior of tox and virtualenv creation can be found at
# https://github.com/tox-dev/tox/issues/448
#
# This script is wrapper to force the use of the pinned versions early in the
# process when the virtualenv was created and upgraded before installing the
# depedencies declared in the target.
pip install 'pip<20.3' 'setuptools<50.0.0'
pip "$@"

2
requirements.txt Normal file
View File

@ -0,0 +1,2 @@
ops
git+https://opendev.org/openstack/charm-ops-openstack#egg=ops_openstack

89
src/charm.py Executable file
View File

@ -0,0 +1,89 @@
#! /usr/bin/env python3
# Copyright 2021 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 json
from ops_openstack.core import OSBaseCharm
from ops.framework import StoredState
from ops.main import main
from ops.model import ActiveStatus
class CinderSolidfireCharm(OSBaseCharm):
_stored = StoredState()
PACKAGES = ['cinder-common']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# We listen to the following events:
# - Installation: Just to set the charm status
# - Configuration changes: Rewrite the cinder.conf file and inform
# other charms of the changes
# - Backend storage join/change: Inform the other charm of what the
# configuration is and the backend name.
self.framework.observe(self.on.install, self._on_install)
self.framework.observe(self.on.config_changed, self._on_config)
self.framework.observe(
self.on.storage_backend_relation_joined,
self._on_storage_backend)
self.framework.observe(
self.on.storage_backend_relation_changed,
self._on_storage_backend)
def _on_install(self, _):
self.install_pkgs()
self.unit.status = ActiveStatus('Unit is ready')
def _render_config(self, config, app_name):
# Generate the JSON with the updated configuration.
volume_driver = ''
options = [
('volume_driver', volume_driver),
]
return json.dumps({
"cinder": {
"/etc/cinder/cinder.confg": {
"sections": {app_name: options}
}
}
})
def _set_data(self, data, config, app_name):
# Inform another charm of the backend name and our configuration.
data['backend-name'] = config['volume-backend-name'] or app_name
data['subordinate_configuration'] = self._render_config(
config, app_name)
def _on_config(self, event):
config = dict(self.framework.model.config)
rel = self.framework.model.relations.get('storage-backend')[0]
app_name = self.framework.model.app.name
for unit in self.framework.model.get_relation('storage-backend').units:
self._set_data(rel.data[self.unit], config, app_name)
self.unit.status = ActiveStatus('Unit is ready')
def _on_storage_backend(self, event):
self._set_data(
event.relation.data[self.unit],
self.framework.model.config,
self.framework.model.app.name)
if __name__ == '__main__':
main(CinderSolidfireCharm)

View File

@ -0,0 +1,9 @@
# This file is managed centrally by release-tools and should not be modified
# within individual charm repos. See the 'global' dir contents for available
# choices of *requirements.txt files for OpenStack Charms:
# https://github.com/openstack-charmers/release-tools
#
# Functional Test Requirements (let Zaza's dependencies solve all dependencies here!)
git+https://github.com/openstack-charmers/zaza.git#egg=zaza
git+https://github.com/openstack-charmers/zaza-openstack-tests.git#egg=zaza.openstack

61
src/tox.ini Normal file
View File

@ -0,0 +1,61 @@
# Source charm (with zaza): ./src/tox.ini
# This file is managed centrally by release-tools and should not be modified
# within individual charm repos. See the 'global' dir contents for available
# choices of tox.ini for OpenStack Charms:
# https://github.com/openstack-charmers/release-tools
[tox]
envlist = pep8
skipsdist = True
# NOTE: Avoid build/test env pollution by not enabling sitepackages.
sitepackages = False
# NOTE: Avoid false positives by not skipping missing interpreters.
skip_missing_interpreters = False
# NOTES:
# * We avoid the new dependency resolver by pinning pip < 20.3, see
# https://github.com/pypa/pip/issues/9187
# * Pinning dependencies requires tox >= 3.2.0, see
# https://tox.readthedocs.io/en/latest/config.html#conf-requires
# * It is also necessary to pin virtualenv as a newer virtualenv would still
# lead to fetching the latest pip in the func* tox targets, see
# https://stackoverflow.com/a/38133283
requires = pip < 20.3
virtualenv < 20.0
# NOTE: https://wiki.canonical.com/engineering/OpenStack/InstallLatestToxOnOsci
minversion = 3.18.0
[testenv]
setenv = VIRTUAL_ENV={envdir}
PYTHONHASHSEED=0
allowlist_externals = juju
passenv = HOME TERM CS_* OS_* TEST_*
deps = -r{toxinidir}/test-requirements.txt
install_command =
pip install {opts} {packages}
[testenv:pep8]
basepython = python3
commands = charm-proof
[testenv:func-noop]
basepython = python3
commands =
functest-run-suite --help
[testenv:func]
basepython = python3
commands =
functest-run-suite --keep-model
[testenv:func-smoke]
basepython = python3
commands =
functest-run-suite --keep-model --smoke
[testenv:func-target]
basepython = python3
commands =
functest-run-suite --keep-model --bundle {posargs}
[testenv:venv]
commands = {posargs}

16
test-requirements.txt Normal file
View File

@ -0,0 +1,16 @@
# 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>=4.0.1
stestr>=2.2.0
requests>=2.18.4
psutil
# oslo.i18n dropped py35 support
oslo.i18n<4.0.0
git+https://github.com/openstack-charmers/zaza.git#egg=zaza
git+https://github.com/openstack-charmers/zaza-openstack-tests.git#egg=zaza.openstack
pytz # workaround for 14.04 pip/tox
pyudev # for ceph-* charm unit tests (not mocked?)

View File

@ -0,0 +1,50 @@
series: bionic
comment:
- 'machines section to decide order of deployment. database sooner = faster'
machines:
'0':
constraints: mem=3072M
'1':
'2':
'3':
local_overlay_enabled: false
relations:
- - keystone:shared-db
- mysql:shared-db
- - cinder:shared-db
- mysql:shared-db
- - cinder:identity-service
- keystone:identity-service
- - cinder:amqp
- rabbitmq-server:amqp
- - cinder:storage-backend
- cinder-solidfire:storage-backend
applications:
mysql:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
to:
- '0'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
options:
openstack-origin: cloud:bionic-queens
to:
- '1'
cinder:
charm: cs:~openstack-charmers-next/cinder
num_units: 1
options:
openstack-origin: cloud:bionic-queens
to:
- '2'
cinder-solidfire:
charm: ../../cinder-solidfire.charm
options:
# Add config options here
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
to:
- '3'

9
tests/tests.yaml Normal file
View File

@ -0,0 +1,9 @@
charm_name: cinder-solidfire
tests:
- tests.tests_cinder_solidfire.CinderSolidfireTest
configure:
- zaza.openstack.charm_tests.keystone.setup.add_demo_user
gate_bundles:
- bionic-queens
smoke_bundles:
- bionic-queens

View File

@ -0,0 +1,70 @@
#!/usr/bin/env python3
# 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.
"""Encapsulate cinder-solidfire testing."""
import logging
import uuid
import zaza.model
import zaza.openstack.charm_tests.test_utils as test_utils
import zaza.openstack.utilities.openstack as openstack_utils
class CinderSolidfireTest(test_utils.OpenStackBaseTest):
"""Encapsulate Solidfire tests."""
@classmethod
def setUpClass(cls):
"""Run class setup for running tests."""
super(CinderSolidfireTest, cls).setUpClass()
cls.keystone_session = openstack_utils.get_overcloud_keystone_session()
cls.model_name = zaza.model.get_juju_model()
cls.cinder_client = openstack_utils.get_cinder_session_client(
cls.keystone_session)
def test_cinder_config(self):
logging.info('solidfire')
expected_contents = {
'cinder-solidfire': {
'iscsi_helper': ['tgtadm'],
'volume_dd_blocksize': ['512']}}
zaza.model.run_on_leader(
'cinder',
'sudo cp /etc/cinder/cinder.conf /tmp/',
model_name=self.model_name)
zaza.model.block_until_oslo_config_entries_match(
'cinder',
'/tmp/cinder.conf',
expected_contents,
model_name=self.model_name,
timeout=2)
def test_create_volume(self):
test_vol_name = "zaza{}".format(uuid.uuid1().fields[0])
vol_new = self.cinder_client.volumes.create(
name=test_vol_name,
size=2)
openstack_utils.resource_reaches_status(
self.cinder_client.volumes,
vol_new.id,
expected_status='available')
test_vol = self.cinder_client.volumes.find(name=test_vol_name)
self.assertEqual(
getattr(test_vol, 'os-vol-host-attr:host').split('#')[0],
'cinder@cinder-solidfire')
self.cinder_client.volumes.delete(vol_new)

133
tox.ini Normal file
View File

@ -0,0 +1,133 @@
# Operator charm (with zaza): tox.ini
[tox]
envlist = pep8,py3
skipsdist = True
# NOTE: Avoid build/test env pollution by not enabling sitepackages.
sitepackages = False
# NOTE: Avoid false positives by not skipping missing interpreters.
skip_missing_interpreters = False
# NOTES:
# * We avoid the new dependency resolver by pinning pip < 20.3, see
# https://github.com/pypa/pip/issues/9187
# * Pinning dependencies requires tox >= 3.2.0, see
# https://tox.readthedocs.io/en/latest/config.html#conf-requires
# * It is also necessary to pin virtualenv as a newer virtualenv would still
# lead to fetching the latest pip in the func* tox targets, see
# https://stackoverflow.com/a/38133283
requires = pip < 20.3
virtualenv < 20.0
# NOTE: https://wiki.canonical.com/engineering/OpenStack/InstallLatestToxOnOsci
minversion = 3.2.0
[testenv]
setenv = VIRTUAL_ENV={envdir}
PYTHONHASHSEED=0
CHARM_DIR={envdir}
install_command =
pip install {opts} {packages}
commands = stestr run --slowest {posargs}
whitelist_externals =
git
add-to-archive.py
bash
passenv = HOME TERM CS_* OS_* TEST_*
deps = -r{toxinidir}/test-requirements.txt
[testenv:py35]
basepython = python3.5
# python3.5 is irrelevant on a focal+ charm.
commands = /bin/true
[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:py38]
basepython = python3.8
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
[testenv:py3]
basepython = python3
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} src unit_tests 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 --slowest {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:build]
basepython = python3
deps = -r{toxinidir}/build-requirements.txt
commands =
charmcraft build
[testenv:func-noop]
basepython = python3
commands =
functest-run-suite --help
[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
[testenv:func-target]
basepython = python3
commands =
functest-run-suite --keep-model --bundle {posargs}
[flake8]
# Ignore E902 because the unit_tests directory is missing in the built charm.
ignore = E402,E226,W503,W504,E902

13
unit_tests/__init__.py Normal file
View File

@ -0,0 +1,13 @@
# Copyright 2021 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.

View File

@ -0,0 +1,43 @@
# Copyright 2016 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 unittest
from src.charm import CinderSolidfireCharm
from ops.model import ActiveStatus
from ops.testing import Harness
class TestCinderSolidfireCharm(unittest.TestCase):
def setUp(self):
self.harness = Harness(CinderSolidfireCharm)
self.addCleanup(self.harness.cleanup)
self.harness.begin()
self.harness.set_leader(True)
backend = self.harness.add_relation('storage-backend', 'cinder')
self.harness.update_config({'volume-backend-name': 'test'})
self.harness.add_relation_unit(backend, 'cinder/0')
def test_cinder_base(self):
self.assertEqual(
self.harness.framework.model.app.name,
'cinder-solidfire')
# Test that charm is active upon installation.
self.harness.update_config({})
self.assertTrue(isinstance(
self.harness.model.unit.status, ActiveStatus))
def test_cinder_configuration(self):
# Add check here that configuration is as expected.
pass