summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiam Young <liam.young@canonical.com>2018-06-25 12:44:12 +0000
committerLiam Young <liam.young@canonical.com>2018-06-28 08:21:28 +0000
commit29d6d050adbcbc5f974ba1e759018100cf88120a (patch)
tree066e47d5bebd61c4813ab82d220d00fa2390ab7b
initial commit
-rw-r--r--.gitignore8
-rw-r--r--requirements.txt2
-rw-r--r--src/config.yaml93
-rw-r--r--src/layer.yaml10
-rw-r--r--src/lib/charm/openstack/__init__.py13
-rw-r--r--src/lib/charm/openstack/nova_cell_controller.py113
-rw-r--r--src/metadata.yaml45
-rw-r--r--src/reactive/__init__.py13
-rw-r--r--src/reactive/nova_cell_controller_handlers.py107
-rw-r--r--src/templates/mitaka/nova.conf18
-rw-r--r--tox.ini54
11 files changed, 476 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..98c9c5a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
1build
2.tox
3layers
4interfaces
5trusty
6.testrepository
7__pycache__
8.stestr
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..96d5c76
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,2 @@
1charm-tools
2simplejson
diff --git a/src/config.yaml b/src/config.yaml
new file mode 100644
index 0000000..1639ef3
--- /dev/null
+++ b/src/config.yaml
@@ -0,0 +1,93 @@
1options:
2 debug:
3 type: boolean
4 default: False
5 description: Enable debug logging.
6 verbose:
7 type: boolean
8 default: False
9 description: Enable verbose logging.
10 use-syslog:
11 type: boolean
12 default: False
13 description: |
14 Setting this to True will allow supporting services to log to syslog.
15 openstack-origin:
16 type: string
17 default: distro
18 description: |
19 Repository from which to install. May be one of the following:
20 distro (default), ppa:somecustom/ppa, a deb url sources entry,
21 or a supported Ubuntu Cloud Archive e.g.
22 .
23 cloud:<series>-<openstack-release>
24 cloud:<series>-<openstack-release>/updates
25 cloud:<series>-<openstack-release>/staging
26 cloud:<series>-<openstack-release>/proposed
27 .
28 See https://wiki.ubuntu.com/OpenStack/CloudArchive for info on which
29 cloud archives are available and supported.
30 .
31 NOTE: updating this setting to a source that is known to provide
32 a later version of OpenStack will trigger a software upgrade unless
33 action-managed-upgrade is set to True.
34 harden:
35 type: string
36 default:
37 description: |
38 Apply system hardening. Supports a space-delimited list of modules
39 to run. Supported modules currently include os, ssh, apache and mysql.
40 nova-alchemy-flags:
41 type: string
42 default:
43 description: |
44 Comma-separated list of key=value sqlalchemy related config flags to be
45 set in nova.conf [database] section.
46 network-manager:
47 type: string
48 default: FlatDHCPManager
49 description: |
50 Network manager for the cloud; supports the following options:
51 .
52 FlatDHCPManager (nova-network) (default)
53 FlatManager (nova-network)
54 Neutron (Full SDN solution)
55 .
56 When using the Neutron option you will most likely want to use
57 the neutron-gateway charm to provide L3 routing and DHCP Services.
58 config-flags:
59 type: string
60 default:
61 description: |
62 Comma-separated list of key=value config flags. These values will be
63 placed in the nova.conf [DEFAULT] section.
64 region:
65 type: string
66 default: RegionOne
67 description: OpenStack Region
68 # Monitoring config
69 nagios_context:
70 type: string
71 default: "juju"
72 description: |
73 Used by the nrpe-external-master subordinate charm.
74 A string that will be prepended to instance name to set the host name
75 in nagios. So for instance the hostname would be something like:
76 .
77 juju-myservice-0
78 .
79 If you're running multiple environments with the same services in them
80 this allows you to differentiate between them.
81 nagios_servicegroups:
82 type: string
83 default: ""
84 description: |
85 A comma-separated list of nagios servicegroups. If left empty, the
86 nagios_context will be used as the servicegroup.
87 cell-name:
88 type: string
89 default:
90 description: |
91 Name of the compute cell this controller is associated with. If this is
92 left unset or set to api then it is assumed that this controller will be
93 the top level api and cell0 controller.
diff --git a/src/layer.yaml b/src/layer.yaml
new file mode 100644
index 0000000..506143b
--- /dev/null
+++ b/src/layer.yaml
@@ -0,0 +1,10 @@
1includes:
2 - layer:openstack-api
3 - interface:mysql-shared
4 - interface:rabbitmq
5 - interface:nova-compute
6 - interface:nova-cell
7options:
8 basic:
9 use_venv: true
10 include_system_packages: true
diff --git a/src/lib/charm/openstack/__init__.py b/src/lib/charm/openstack/__init__.py
new file mode 100644
index 0000000..9b088de
--- /dev/null
+++ b/src/lib/charm/openstack/__init__.py
@@ -0,0 +1,13 @@
1# Copyright 2016 Canonical Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
diff --git a/src/lib/charm/openstack/nova_cell_controller.py b/src/lib/charm/openstack/nova_cell_controller.py
new file mode 100644
index 0000000..c7b9d7a
--- /dev/null
+++ b/src/lib/charm/openstack/nova_cell_controller.py
@@ -0,0 +1,113 @@
1# Copyright 2016 Canonical Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# The nova_cell_controller handlers class
15
16# bare functions are provided to the reactive handlers to perform the functions
17# needed on the class.
18from __future__ import absolute_import
19
20import collections
21import subprocess
22
23import charmhelpers.core.hookenv as hookenv
24
25import charms_openstack.charm
26import charms_openstack.adapters
27import charms_openstack.ip as os_ip
28
29PACKAGES = ['nova-conductor']
30NOVA_DIR = '/etc/nova/'
31NOVA_CONF = NOVA_DIR + "nova.conf"
32
33OPENSTACK_RELEASE_KEY = 'nova-charm.openstack-release-version'
34
35
36# select the default release function
37charms_openstack.charm.use_defaults('charm.default-select-release')
38
39
40class NovaCellControllerCharm(charms_openstack.charm.HAOpenStackCharm):
41 """NovaCellControllerCharm provides the specialisation of the OpenStackCharm
42 functionality to manage a nova_cell_controller unit.
43 """
44
45 release = 'mitaka'
46 name = 'nova-cell-controller'
47 packages = PACKAGES
48 service_type = 'nova-cell-controller'
49 default_service = 'nova-conductor'
50 services = ['nova-conductor']
51
52 # Note that the hsm interface is optional - defined in config.yaml
53 required_relations = ['shared-db', 'amqp']
54
55 restart_map = {
56 NOVA_CONF: services,
57 }
58
59 # Package for release version detection
60 release_pkg = 'nova-common'
61
62 # Package codename map for nova-common
63 package_codenames = {
64 'nova-common': collections.OrderedDict([
65 ('13', 'mitaka'),
66 ('14', 'newton'),
67 ('15', 'ocata'),
68 ('16', 'pike'),
69 ('17', 'queens'),
70 ('18', 'rocky'),
71 ]),
72 }
73
74 sync_cmd = ['nova-manage', 'db', 'sync' ,'--local_cell']
75
76 def get_amqp_credentials(self):
77 """Provide the default amqp username and vhost as a tuple.
78
79 :returns (username, host): two strings to send to the amqp provider.
80 """
81 return ('nova', 'openstack')
82
83 def get_database_setup(self):
84 """Provide the default database credentials as a list of 3-tuples
85
86 returns a structure of:
87 [
88 {'database': <database>,
89 'username': <username>,
90 'hostname': <hostname of this unit>
91 'prefix': <the optional prefix for the database>, },
92 ]
93
94 :returns [{'database': ...}, ...]: credentials for multiple databases
95 """
96 return [{'username': 'nova', 'database': 'nova'}]
97
98
99 def states_to_check(self, required_relations=None):
100 """Override the default states_to_check() for the assess_status
101 functionality so that, if we have to have an HSM relation, then enforce
102 it on the assess_status() call.
103
104 If param required_relations is not None then it overrides the
105 instance/class variable self.required_relations.
106
107 :param required_relations: [list of state names]
108 :returns: [states{} as per parent method]
109 """
110 if required_relations is None:
111 required_relations = self.required_relations
112 return super(NovaCellControllerCharm, self).states_to_check(
113 required_relations=required_relations)
diff --git a/src/metadata.yaml b/src/metadata.yaml
new file mode 100644
index 0000000..0703f59
--- /dev/null
+++ b/src/metadata.yaml
@@ -0,0 +1,45 @@
1name: nova-cell-controller
2summary: OpenStack Compute - Nova cloud controller for a cell.
3maintainer: OpenStack Charmers <openstack-charmers@lists.ubuntu.com>
4description: |
5 OpenStack is a reliable cloud infrastructure. Its mission is to produce
6 the ubiquitous cloud computing platform that will meet the needs of public
7 and private cloud providers regardless of size, by being simple to implement
8 and massively scalable.
9 .
10 OpenStack Compute, codenamed Nova, is a cloud computing fabric controller. In
11 addition to its "native" API (the OpenStack API), it also supports the Amazon
12 EC2 API.
13 .
14 This charm provides the cloud controller service for OpenStack Nova cell
15 and includes nova-conductor service.
16tags:
17 - openstack
18series:
19 - xenial
20 - bionic
21 - artful
22 - trusty
23extra-bindings:
24 public:
25 admin:
26 internal:
27provides:
28 nrpe-external-master:
29 interface: nrpe-external-master
30 scope: container
31 cloud-controller:
32 interface: nova
33requires:
34 shared-db:
35 interface: mysql-shared
36 amqp:
37 interface: rabbitmq
38 cloud-compute:
39 interface: nova-compute
40 nova-cell-compute:
41 interface: nova-cell
42peers:
43 cluster:
44 interface: nova-ha
45
diff --git a/src/reactive/__init__.py b/src/reactive/__init__.py
new file mode 100644
index 0000000..9b088de
--- /dev/null
+++ b/src/reactive/__init__.py
@@ -0,0 +1,13 @@
1# Copyright 2016 Canonical Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
diff --git a/src/reactive/nova_cell_controller_handlers.py b/src/reactive/nova_cell_controller_handlers.py
new file mode 100644
index 0000000..1ceb4af
--- /dev/null
+++ b/src/reactive/nova_cell_controller_handlers.py
@@ -0,0 +1,107 @@
1# Copyright 2018 Canonical Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15# this is just for the reactive handlers and calls into the charm.
16from __future__ import absolute_import
17
18import charms.reactive as reactive
19import charmhelpers.core.hookenv as hookenv
20
21import charms_openstack.charm as charm
22
23from charms.reactive.relations import (
24 endpoint_from_flag,
25)
26
27from charms.reactive.flags import (
28 is_flag_set,
29 set_flag,
30 clear_flag,
31)
32
33# This charm's library contains all of the handler code associated with
34# nova_cell_controller -- we need to import it to get the definitions for the
35# charm.
36import charm.openstack.nova_cell_controller as nova_cell_controller # noqa
37
38
39# Use the charms.openstack defaults for common states and hooks
40charm.use_defaults(
41 'charm.installed',
42 'amqp.connected',
43 'shared-db.connected',
44 'config.changed',
45 'update-status')
46
47
48# Note that because of the way reactive.when works, (which is to 'find' the
49# __code__ segment of the decorated function, it's very, very difficult to add
50# other kinds of decorators here. This rules out adding other things into the
51# charm args list. It is also CPython dependent.
52@reactive.when('shared-db.available')
53@reactive.when('amqp.available')
54def render_stuff(*args):
55 """Render the configuration for Nova cell controller when all the interfaces
56 are available.
57
58 """
59 hookenv.log("about to call the render_configs with {}".format(args))
60 with charm.provide_charm_instance() as nova_cell_controller_charm:
61 nova_cell_controller_charm.render_with_interfaces(args)
62 nova_cell_controller_charm.assess_status()
63 set_flag('config.rendered')
64
65
66@reactive.when_not('shared-db.synced')
67@reactive.when('config.rendered')
68def db_setup(*args):
69 with charm.provide_charm_instance() as cell_charm:
70 cell_charm.db_sync()
71 cell_charm.restart_all()
72 set_flag('shared-db.synced')
73
74
75@reactive.when('endpoint.nova-cell-compute.changed')
76@reactive.when('endpoint.cloud-compute.joined')
77def send_compute_data():
78 nc = endpoint_from_flag('endpoint.cloud-compute.joined')
79 ncc_ep = endpoint_from_flag('endpoint.nova-cell-compute.changed')
80 ncc_console_data = ncc_ep.get_console_data()
81 ncc_network_data = ncc_ep.get_network_data()
82 nc.set_network_data(
83 ncc_network_data['quantum_url'],
84 neutron_plugin=ncc_network_data['quantum_plugin'],
85 network_manager=ncc_network_data['network_manager'],
86 enable_security_groups=ncc_network_data['quantum_security_groups'])
87 nc.set_console_data(
88 serial_console_base_url=ncc_console_data['serial_console_base_url'],
89 enable_serial_console=ncc_console_data['enable_serial_console'])
90 nc.set_region(ncc_ep.get_region()['region'])
91 nc.set_volume_data(ncc_ep.get_volume_data()['volume_service'])
92 nc.set_ec2_data(ncc_ep.get_ec2_data()['ec2_host'])
93
94@reactive.when('shared-db.available')
95@reactive.when('amqp.available')
96@reactive.when('endpoint.nova-cell-compute.joined')
97def send_cell_data():
98 ncc_ep = endpoint_from_flag('endpoint.nova-cell-compute.joined')
99 amqp_conv = endpoint_from_flag('amqp.available').conversation()
100 # Push this calculation of service names down into the interfaces
101 amqp_service_names = [u.split('/')[0] for u in amqp_conv.units if u]
102 db_conv = endpoint_from_flag('shared-db.available').conversation()
103 db_service_names = [u.split('/')[0] for u in db_conv.units if u]
104 ncc_ep.send_cell_data(
105 hookenv.config('cell-name'),
106 amqp_service_names[0],
107 db_service_names[0])
diff --git a/src/templates/mitaka/nova.conf b/src/templates/mitaka/nova.conf
new file mode 100644
index 0000000..5ef0626
--- /dev/null
+++ b/src/templates/mitaka/nova.conf
@@ -0,0 +1,18 @@
1# mitaka
2###############################################################################
3# [ WARNING ]
4# Configuration file maintained by Juju. Local changes may be overwritten.
5###############################################################################
6[DEFAULT]
7verbose={{ options.verbose }}
8debug={{ options.debug }}
9logdir=/var/log/nova
10state_path=/var/lib/nova
11root_helper=sudo nova-rootwrap /etc/nova/rootwrap.conf
12
13{% include "parts/database" %}
14
15[conductor]
16workers = {{ options.workers }}
17
18{% include "parts/section-rabbitmq-oslo" %}
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 0000000..744d2df
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,54 @@
1# Source charm: ./tox.ini
2# This file is managed centrally by release-tools and should not be modified
3# within individual charm repos.
4[tox]
5skipsdist = True
6envlist = pep8,py34,py35
7skip_missing_interpreters = True
8
9[testenv]
10setenv = VIRTUAL_ENV={envdir}
11 PYTHONHASHSEED=0
12 TERM=linux
13 LAYER_PATH={toxinidir}/layers
14 JUJU_REPOSITORY={toxinidir}/build
15passenv = http_proxy https_proxy INTERFACE_PATH
16install_command =
17 pip install {opts} {packages}
18deps =
19 -r{toxinidir}/requirements.txt
20
21[testenv:build]
22basepython = python2.7
23commands =
24 charm-build --log-level DEBUG -o {toxinidir}/build src {posargs}
25
26[testenv:py27]
27basepython = python2.7
28# Reactive source charms are Python3-only, but a py27 unit test target
29# is required by OpenStack Governance. Remove this shim as soon as
30# permitted. http://governance.openstack.org/reference/cti/python_cti.html
31whitelist_externals = true
32commands = true
33
34[testenv:py34]
35basepython = python3.4
36deps = -r{toxinidir}/test-requirements.txt
37commands = ostestr {posargs}
38
39[testenv:py35]
40basepython = python3.5
41deps = -r{toxinidir}/test-requirements.txt
42commands = ostestr {posargs}
43
44[testenv:pep8]
45basepython = python3.5
46deps = -r{toxinidir}/test-requirements.txt
47commands = flake8 {posargs} src unit_tests
48
49[testenv:venv]
50commands = {posargs}
51
52[flake8]
53# E402 ignore necessary for path append before sys module import in actions
54ignore = E402