diff --git a/.gitignore b/.gitignore index 4fae9b4d..c7425d17 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,9 @@ output/*/index.html # Sphinx doc/build +# oslo-config-generator +etc/*.sample + # pbr generates these AUTHORS ChangeLog @@ -57,4 +60,4 @@ ChangeLog .vagrant # generated openrc -openrc \ No newline at end of file +openrc diff --git a/etc/oslo-config-generator/kolla-mesos.conf b/etc/oslo-config-generator/kolla-mesos.conf new file mode 100644 index 00000000..3ce0e338 --- /dev/null +++ b/etc/oslo-config-generator/kolla-mesos.conf @@ -0,0 +1,5 @@ +[DEFAULT] +output_file = etc/kolla-mesos.conf.sample +wrap_width = 79 + +namespace = kolla_mesos diff --git a/kolla_mesos/cmd/config.py b/kolla_mesos/cmd/config.py index 0331b9d7..e642b6f9 100644 --- a/kolla_mesos/cmd/config.py +++ b/kolla_mesos/cmd/config.py @@ -12,11 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -import argparse import logging -import os +import sys + +from oslo_config import cfg -from kolla_mesos.common import config_utils from kolla_mesos.common import zk_utils @@ -24,37 +24,19 @@ logging.basicConfig() LOG = logging.getLogger(__name__) LOG.setLevel(logging.INFO) - -def merge_args_and_config(settings_from_config_file): - parser = argparse.ArgumentParser(description='Kolla build script') - defaults = { - "zookeeper_host": os.environ.get('ZK_HOSTS', 'localhost:2181'), - } - defaults.update(settings_from_config_file.items('kolla-build')) - parser.set_defaults(**defaults) - parser.add_argument('--zookeeper-host', - help='Zookeeper host:port', - type=str) - parser.add_argument('-d', '--debug', - help='Turn on debugging log level', - action='store_true') - parser.add_argument('-s', '--show', - help='Show node data', - action='store_true') - parser.add_argument('path', - help='Zookeeper node path (try /kolla)') - return vars(parser.parse_args()) +CONF = cfg.CONF +CONF.import_group('zookeeper', 'kolla_mesos.config.zookeeper') +CONF.import_opt('path', 'kolla_mesos.config.config_cli') +CONF.import_opt('show', 'kolla_mesos.config.config_cli') def main(): - cmd_opts, kolla_config = config_utils.load('kolla-build.conf', - merge_args_and_config) - - with zk_utils.connection(cmd_opts['zookeeper_host']) as zk: - if cmd_opts['show']: - zk_utils.cat(zk, cmd_opts['path']) + CONF(sys.argv[1:], project='kolla-mesos') + with zk_utils.connection(CONF.zookeeper.host) as zk: + if CONF.show: + zk_utils.cat(zk, CONF.path) else: - zk_utils.tree(zk, cmd_opts['path']) + zk_utils.tree(zk, CONF.path) if __name__ == '__main__': main() diff --git a/kolla_mesos/cmd/deploy.py b/kolla_mesos/cmd/deploy.py index 413bff13..85723b83 100755 --- a/kolla_mesos/cmd/deploy.py +++ b/kolla_mesos/cmd/deploy.py @@ -12,21 +12,21 @@ # See the License for the specific language governing permissions and # limitations under the License. -import argparse import datetime import json import logging import os import signal +import sys import tempfile import time +from oslo_config import cfg import shutil from six.moves import configparser from six.moves import cStringIO import yaml -from kolla_mesos.common import config_utils from kolla_mesos.common import file_utils from kolla_mesos.common import jinja_utils from kolla_mesos.common import zk_utils @@ -38,72 +38,25 @@ LOG.setLevel(logging.INFO) signal.signal(signal.SIGINT, signal.SIG_DFL) +CONF = cfg.CONF +CONF.import_group('kolla', 'kolla_mesos.config.kolla') +CONF.import_group('profiles', 'kolla_mesos.config.profiles') +CONF.import_group('zookeeper', 'kolla_mesos.config.zookeeper') +CONF.import_group('marathon', 'kolla_mesos.config.marathon') +CONF.import_group('chronos', 'kolla_mesos.config.chronos') + class KollaDirNotFoundException(Exception): pass -def merge_args_and_config(settings_from_config_file): - parser = argparse.ArgumentParser(description='Kolla build script') - - defaults = { - "namespace": "kollaglue", - "tag": "latest", - "base": "centos", - "base_tag": "latest", - "install_type": "binary", - } - defaults.update(settings_from_config_file.items('kolla-build')) - parser.set_defaults(**defaults) - - parser.add_argument('-n', '--namespace', - help='Set the Docker namespace name', - type=str) - parser.add_argument('--tag', - help='Set the Docker tag', - type=str) - parser.add_argument('-b', '--base', - help='The base distro to use when building', - type=str) - parser.add_argument('--base-tag', - help='The base distro image tag', - type=str) - parser.add_argument('-t', '--type', - help='The method of the Openstack install', - type=str, - dest='install_type') - parser.add_argument('--zookeeper-host', - help='Zookeeper host:port (default localhost:2181)', - default="localhost:2181", - type=str) - parser.add_argument('-d', '--debug', - help='Turn on debugging log level', - action='store_true') - parser.add_argument('-p', '--profile', - help=('Build a pre-defined set of images, see ' - '[profiles] section in ' - '{}'.format( - file_utils.find_config_file( - 'kolla-build.conf'))), - type=str, - action='append') - - return vars(parser.parse_args()) - - class KollaWorker(object): - def __init__(self, config, profiles): + def __init__(self): self.base_dir = os.path.abspath(file_utils.find_base_dir( project='kolla-mesos')) self.config_dir = os.path.join(self.base_dir, 'config') LOG.debug("Kolla-Mesos base directory: " + self.base_dir) - self.namespace = config['namespace'] - self.base = config['base'] - self.install_type = config['install_type'] - self.image_prefix = self.base + '-' + config['install_type'] + '-' - self.build_config = config - self.profiles = profiles self.required_vars = {} def setup_working_dir(self): @@ -114,9 +67,7 @@ class KollaWorker(object): LOG.debug('Created output dir: {}'.format(self.temp_dir)) def get_projects(self): - projects = set() - for prof in self.build_config.get('profiles', ['default']): - projects |= set(self.profiles[prof].split(',')) + projects = set(getattr(CONF.profiles, CONF.kolla.profile)) return projects def get_jinja_vars(self): @@ -217,14 +168,14 @@ class KollaWorker(object): kc_name = os.path.join(self.config_dir, 'config.json') # override container_config_directory cont_conf_dir = 'zk://%s' % ( - self.build_config['zookeeper_host']) + CONF.zookeeper.host) jinja_vars['container_config_directory'] = cont_conf_dir kolla_config = jinja_utils.jinja_render(kc_name, jinja_vars) # 4. parse the marathon app file and add the KOLLA_CONFIG values = { 'kolla_config': kolla_config.replace('"', '\\"'), - 'zookeeper_hosts': self.build_config['zookeeper_host'] + 'zookeeper_hosts': CONF.zookeeper.host } for app_type in ['marathon', 'chronos']: app_file = os.path.join(self.base_dir, @@ -256,7 +207,7 @@ class KollaWorker(object): shutil.rmtree(self.temp_dir) def write_to_zookeeper(self): - with zk_utils.connection(self.build_config['zookeeper_host']) as zk: + with zk_utils.connection(CONF.zookeeper.host) as zk: # to clean these up, uncomment zk.delete('/kolla', recursive=True) @@ -281,10 +232,8 @@ class KollaWorker(object): def start(self): # find all marathon files and run. # find all cronos files and run. - marathon_api = self.build_config['zookeeper_host'].replace('2181', - '8080') - chronos_api = self.build_config['zookeeper_host'].replace('2181', - '4400') + marathon_api = CONF.marathon.host + chronos_api = CONF.chronos.host content_type = '-L -H "Content-type: application/json"' for root, dirs, names in os.walk(self.temp_dir): for name in names: @@ -300,11 +249,8 @@ class KollaWorker(object): def main(): - cmd_opts, kolla_config = config_utils.load('kolla-build.conf', - merge_args_and_config) - profiles = dict(kolla_config.items('profiles')) - - kolla = KollaWorker(cmd_opts, profiles) + CONF(sys.argv[1:], project='kolla-mesos') + kolla = KollaWorker() kolla.setup_working_dir() kolla.write_to_zookeeper() kolla.write_openrc() diff --git a/kolla_mesos/common/network_utils.py b/kolla_mesos/common/network_utils.py new file mode 100644 index 00000000..4c6d8db7 --- /dev/null +++ b/kolla_mesos/common/network_utils.py @@ -0,0 +1,29 @@ +# 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 fcntl +import socket +import struct + + +# TODO(nihilifer): Autodetect networks and find a way to share commons between +# kolla_mesos and kolla_mesos_start.py. +def get_ip_address(ifname='eth0'): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + try: + return socket.inet_ntoa(fcntl.ioctl( + s.fileno(), + 0x8915, # SIOCGIFADDR + struct.pack('256s', ifname[:15]) + )[20:24]) + except IOError: + return '127.0.0.1' diff --git a/kolla_mesos/config/__init__.py b/kolla_mesos/config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/kolla_mesos/config/chronos.py b/kolla_mesos/config/chronos.py new file mode 100644 index 00000000..6afd517d --- /dev/null +++ b/kolla_mesos/config/chronos.py @@ -0,0 +1,33 @@ +# 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. + +from oslo_config import cfg + +from kolla_mesos.common import network_utils + + +CHRONOS_URL = 'http://{}:4400'.format(network_utils.get_ip_address()) + +CONF = cfg.CONF +chronos_opts = [ + cfg.StrOpt('host', + default=CHRONOS_URL, + help='Chronos connection URL (http://host:port)'), + cfg.IntOpt('timeout', + default=5, + help='Timeout for the request to the Chronos API') +] +chronos_opt_group = cfg.OptGroup(name='chronos', + title='Options for Chronos') +CONF.register_group(chronos_opt_group) +CONF.register_cli_opts(chronos_opts, chronos_opt_group) +CONF.register_opts(chronos_opts, chronos_opt_group) diff --git a/kolla_mesos/common/config_utils.py b/kolla_mesos/config/config_cli.py similarity index 55% rename from kolla_mesos/common/config_utils.py rename to kolla_mesos/config/config_cli.py index b058b240..ed889fdb 100644 --- a/kolla_mesos/common/config_utils.py +++ b/kolla_mesos/config/config_cli.py @@ -10,19 +10,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging - -from six.moves import configparser - -from kolla_mesos.common import file_utils - -LOG = logging.getLogger(__name__) +from oslo_config import cfg -def load(config_name, merge_args_and_config): - kolla_config = configparser.SafeConfigParser() - kolla_config.read(file_utils.find_config_file(config_name)) - cmd_opts = merge_args_and_config(kolla_config) - if cmd_opts['debug']: - LOG.setLevel(logging.DEBUG) - return cmd_opts, kolla_config +CONF = cfg.CONF +config_cli_opts = [ + cfg.StrOpt('path', + default='/kolla'), + cfg.BoolOpt('show', + default=False) +] +CONF.register_cli_opts(config_cli_opts) diff --git a/kolla_mesos/config/kolla.py b/kolla_mesos/config/kolla.py new file mode 100644 index 00000000..a3d66fdb --- /dev/null +++ b/kolla_mesos/config/kolla.py @@ -0,0 +1,41 @@ +# 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. + +from oslo_config import cfg + + +CONF = cfg.CONF +kolla_opts = [ + cfg.StrOpt('namespace', + default='kollaglue', + help='The Docker namespace name'), + cfg.StrOpt('tag', + default='latest', + help='The Docker tag'), + cfg.StrOpt('base', + default='centos', + help='The base distro which was used to build images'), + cfg.StrOpt('base-tag', + default='latest', + help='The base distro image tag'), + cfg.StrOpt('install-type', + default='binary', + help='The method of the OpenStack install'), + cfg.StrOpt('profile', + default='default', + help='Build profile which was used to build images') +] +kolla_opt_group = cfg.OptGroup(name='kolla', + title='Options for Kolla Docker images') +CONF.register_group(kolla_opt_group) +CONF.register_cli_opts(kolla_opts, kolla_opt_group) +CONF.register_opts(kolla_opts, kolla_opt_group) diff --git a/kolla_mesos/config/marathon.py b/kolla_mesos/config/marathon.py new file mode 100644 index 00000000..7fa5e34c --- /dev/null +++ b/kolla_mesos/config/marathon.py @@ -0,0 +1,33 @@ +# 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. + +from oslo_config import cfg + +from kolla_mesos.common import network_utils + + +MARATHON_URL = 'http://{}:8080'.format(network_utils.get_ip_address()) + +CONF = cfg.CONF +marathon_opts = [ + cfg.StrOpt('host', + default=MARATHON_URL, + help='Marathon connection URL (http://host:port)'), + cfg.IntOpt('timeout', + default=5, + help='Timeout for the request to the Marathon API') +] +marathon_opt_group = cfg.OptGroup(name='marathon', + title='Options for Marathon') +CONF.register_group(marathon_opt_group) +CONF.register_cli_opts(marathon_opts, marathon_opt_group) +CONF.register_opts(marathon_opts, marathon_opt_group) diff --git a/kolla_mesos/config/profiles.py b/kolla_mesos/config/profiles.py new file mode 100644 index 00000000..d584c44f --- /dev/null +++ b/kolla_mesos/config/profiles.py @@ -0,0 +1,42 @@ +# 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. + +from oslo_config import cfg + + +CONF = cfg.CONF +profiles_opts = [ + cfg.ListOpt('infra', + default=['ceph', 'data', 'mariadb', 'haproxy', 'keepalived', + 'kolla-ansible', 'memcached', 'mongodb', + 'openvswitch', 'rabbitmq', 'rsyslog']), + cfg.ListOpt('main', + default=['cinder', 'ceilometer', 'glance', 'heat', 'horizon', + 'keystone', 'neutron', 'nova', 'swift']), + cfg.ListOpt('aux', + default=['designate', 'gnocchi', 'ironic', 'magnum', 'zaqar']), + cfg.ListOpt('default', + default=['data', 'kolla-ansible', 'glance', 'haproxy', 'heat', + 'horizon', 'keepalived', 'keystone', 'memcached', + 'mariadb', 'neutron', 'nova', 'openvswitch', + 'rabbitmq', 'rsyslog']), + cfg.ListOpt('gate', + default=['ceph', 'cinder', 'data', 'dind', 'glance', 'haproxy', + 'heat', 'horizon', 'keepalived', 'keystone', + 'kolla-ansible', 'mariadb', 'memcached', 'neutron', + 'nova', 'openvswitch', 'rabbitmq', 'rsyslog']) +] +profiles_opt_group = cfg.OptGroup(name='profiles', + title='Common sets of images') +CONF.register_group(profiles_opt_group) +CONF.register_cli_opts(profiles_opts, profiles_opt_group) +CONF.register_opts(profiles_opts, profiles_opt_group) diff --git a/kolla_mesos/config/zookeeper.py b/kolla_mesos/config/zookeeper.py new file mode 100644 index 00000000..57d47569 --- /dev/null +++ b/kolla_mesos/config/zookeeper.py @@ -0,0 +1,30 @@ +# 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. + +from oslo_config import cfg + +from kolla_mesos.common import network_utils + + +ZOOKEEPER_URL = '{}:2181'.format(network_utils.get_ip_address()) + +CONF = cfg.CONF +zookeeper_opts = [ + cfg.StrOpt('host', + default=ZOOKEEPER_URL, + help='ZooKeeper connection URL (host:port)') +] +zookeeper_opt_group = cfg.OptGroup(name='zookeeper', + title='Options for ZooKeeper') +CONF.register_group(zookeeper_opt_group) +CONF.register_cli_opts(zookeeper_opts, zookeeper_opt_group) +CONF.register_opts(zookeeper_opts, zookeeper_opt_group) diff --git a/kolla_mesos/opts.py b/kolla_mesos/opts.py new file mode 100644 index 00000000..a7a58d58 --- /dev/null +++ b/kolla_mesos/opts.py @@ -0,0 +1,27 @@ +# 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. + +from kolla_mesos.config import chronos +from kolla_mesos.config import kolla +from kolla_mesos.config import marathon +from kolla_mesos.config import profiles +from kolla_mesos.config import zookeeper + + +def list_opts(): + return [ + ('chronos', chronos.chronos_opts), + ('kolla', kolla.kolla_opts), + ('marathon', marathon.marathon_opts), + ('profiles', profiles.profiles_opts), + ('zookeeper', zookeeper.zookeeper_opts) + ] diff --git a/kolla_mesos/tests/config/__init__.py b/kolla_mesos/tests/config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/kolla_mesos/tests/config/test_chronos_config.py b/kolla_mesos/tests/config/test_chronos_config.py new file mode 100644 index 00000000..ed06ea9d --- /dev/null +++ b/kolla_mesos/tests/config/test_chronos_config.py @@ -0,0 +1,44 @@ +# 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. + +from oslo_config import cfg + +from kolla_mesos.tests import base +from kolla_mesos.tests.fakes import config_file as fake_config_file + + +CONF = cfg.CONF +CONF.import_group('chronos', 'kolla_mesos.config.chronos') + + +CHRONOS_TEXT_CONFIG = """ +[chronos] +host = test.local:4400 +timeout = 30 +""" + + +class TestChronosConfig(base.BaseTestCase): + + def _asserts(self): + self.assertEqual(CONF.chronos.host, 'test.local:4400') + self.assertEqual(CONF.chronos.timeout, 30) + + def test_cli_config(self): + argv = ['--chronos-host', 'test.local:4400', '--chronos-timeout', '30'] + CONF(argv, project='kolla-mesos') + self._asserts() + + @fake_config_file.FakeConfigFile(CHRONOS_TEXT_CONFIG) + def test_file_config(self): + CONF([], project='kolla-mesos', default_config_files=['/dev/null']) + self._asserts() diff --git a/kolla_mesos/tests/config/test_config_cli_config.py b/kolla_mesos/tests/config/test_config_cli_config.py new file mode 100644 index 00000000..315e64e7 --- /dev/null +++ b/kolla_mesos/tests/config/test_config_cli_config.py @@ -0,0 +1,29 @@ +# 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. + +from oslo_config import cfg + +from kolla_mesos.tests import base + + +CONF = cfg.CONF +CONF.import_opt('path', 'kolla_mesos.config.config_cli') +CONF.import_opt('show', 'kolla_mesos.config.config_cli') + + +class TestConfigCliConfig(base.BaseTestCase): + + def test_config_cli(self): + argv = ['--path', 'test_path', '--show'] + CONF(argv, project='kolla-mesos') + self.assertEqual(CONF.path, 'test_path') + self.assertTrue(CONF.show) diff --git a/kolla_mesos/tests/config/test_kolla_config.py b/kolla_mesos/tests/config/test_kolla_config.py new file mode 100644 index 00000000..a76d5e3b --- /dev/null +++ b/kolla_mesos/tests/config/test_kolla_config.py @@ -0,0 +1,55 @@ +# 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. + +from oslo_config import cfg + +from kolla_mesos.tests import base +from kolla_mesos.tests.fakes import config_file as fake_config_file + + +CONF = cfg.CONF +CONF.import_group('kolla', 'kolla_mesos.config.kolla') + + +KOLLA_TEXT_CONFIG = """ +[kolla] +namespace = test_namespace +tag = test_tag +base = test_base +base_tag = test_base_tag +install_type = test_install_type +profile = test_profile +""" + + +class TestKollaConfig(base.BaseTestCase): + + def _asserts(self): + self.assertEqual(CONF.kolla.namespace, 'test_namespace') + self.assertEqual(CONF.kolla.tag, 'test_tag') + self.assertEqual(CONF.kolla.base, 'test_base') + self.assertEqual(CONF.kolla.base_tag, 'test_base_tag') + self.assertEqual(CONF.kolla.install_type, 'test_install_type') + self.assertEqual(CONF.kolla.profile, 'test_profile') + + def test_cli_config(self): + argv = ['--kolla-namespace', 'test_namespace', '--kolla-tag', + 'test_tag', '--kolla-base', 'test_base', '--kolla-base-tag', + 'test_base_tag', '--kolla-install-type', 'test_install_type', + '--kolla-profile', 'test_profile'] + CONF(argv, project='kolla-mesos') + self._asserts() + + @fake_config_file.FakeConfigFile(KOLLA_TEXT_CONFIG) + def test_file_config(self): + CONF([], project='kolla-mesos', default_config_files=['/dev/null']) + self._asserts() diff --git a/kolla_mesos/tests/config/test_marathon_config.py b/kolla_mesos/tests/config/test_marathon_config.py new file mode 100644 index 00000000..f99626f9 --- /dev/null +++ b/kolla_mesos/tests/config/test_marathon_config.py @@ -0,0 +1,43 @@ +# 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. + +from oslo_config import cfg + +from kolla_mesos.tests import base +from kolla_mesos.tests.fakes import config_file as fake_config_file + + +CONF = cfg.CONF +CONF.import_group('marathon', 'kolla_mesos.config.marathon') + + +MARATHON_TEXT_CONFIG = """ +[marathon] +host = test.local:8080 +timeout = 30 +""" + + +class TestMarathonConfig(base.BaseTestCase): + + def test_cli_config(self): + argv = ['--marathon-host', 'test.local:8080', '--marathon-timeout', + '30'] + CONF(argv, project='kolla-mesos') + self.assertEqual(CONF.marathon.host, 'test.local:8080') + self.assertEqual(CONF.marathon.timeout, 30) + + @fake_config_file.FakeConfigFile(MARATHON_TEXT_CONFIG) + def test_file_config(self): + CONF([], project='kolla-mesos', default_config_files=['/dev/null']) + self.assertEqual(CONF.marathon.host, 'test.local:8080') + self.assertEqual(CONF.marathon.timeout, 30) diff --git a/kolla_mesos/tests/config/test_profiles_config.py b/kolla_mesos/tests/config/test_profiles_config.py new file mode 100644 index 00000000..2d15d1de --- /dev/null +++ b/kolla_mesos/tests/config/test_profiles_config.py @@ -0,0 +1,56 @@ +# 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. + +from oslo_config import cfg + +from kolla_mesos.tests import base +from kolla_mesos.tests.fakes import config_file as fake_config_file + + +CONF = cfg.CONF +CONF.import_group('profiles', 'kolla_mesos.config.profiles') + + +PROFILES_TEXT_CONFIG = """ +[profiles] +infra = test1, test2 +main = test1 +aux = test1, test2, test3 +default = test1, test2, test3, test4, test5 +gate = test1, test2, test3, test4 +""" + + +class TestProfilesConfig(base.BaseTestCase): + + def _asserts(self): + self.assertEqual(CONF.profiles.infra, ['test1', 'test2']) + self.assertEqual(CONF.profiles.main, ['test1']) + self.assertEqual(CONF.profiles.aux, ['test1', 'test2', 'test3']) + self.assertEqual(CONF.profiles.default, ['test1', 'test2', 'test3', + 'test4', 'test5']) + self.assertEqual(CONF.profiles.gate, ['test1', 'test2', 'test3', + 'test4']) + + def test_cli_config(self): + argv = ['--profiles-infra', 'test1,test2', + '--profiles-main', 'test1', '--profiles-aux', + 'test1,test2,test3', '--profiles-default', + 'test1,test2,test3,test4,test5', '--profiles-gate', + 'test1,test2,test3,test4'] + CONF(argv, project='kolla-mesos') + self._asserts() + + @fake_config_file.FakeConfigFile(PROFILES_TEXT_CONFIG) + def test_file_config(self): + CONF([], project='kolla-mesos', default_config_files=['/dev/null']) + self._asserts() diff --git a/kolla_mesos/tests/config/test_zookeeper_config.py b/kolla_mesos/tests/config/test_zookeeper_config.py new file mode 100644 index 00000000..ca24e88b --- /dev/null +++ b/kolla_mesos/tests/config/test_zookeeper_config.py @@ -0,0 +1,42 @@ +# 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. + +from oslo_config import cfg + +from kolla_mesos.tests import base +from kolla_mesos.tests.fakes import config_file as fake_config_file + + +CONF = cfg.CONF +CONF.import_group('zookeeper', 'kolla_mesos.config.zookeeper') + + +ZOOKEEPER_TEXT_CONFIG = """ +[zookeeper] +host = test.local:2181 +""" + + +class TestZookeeperConfig(base.BaseTestCase): + + def _asserts(self): + self.assertEqual(CONF.zookeeper.host, 'test.local:2181') + + def test_cli_config(self): + argv = ['--zookeeper-host', 'test.local:2181'] + CONF(argv, project='kolla-mesos') + self._asserts() + + @fake_config_file.FakeConfigFile(ZOOKEEPER_TEXT_CONFIG) + def test_file_config(self): + CONF([], project='kolla-mesos', default_config_files=['/dev/null']) + self._asserts() diff --git a/kolla_mesos/tests/fakes/__init__.py b/kolla_mesos/tests/fakes/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/kolla_mesos/tests/fakes/config_file.py b/kolla_mesos/tests/fakes/config_file.py new file mode 100644 index 00000000..8ca47f64 --- /dev/null +++ b/kolla_mesos/tests/fakes/config_file.py @@ -0,0 +1,47 @@ +# 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 functools +import io + +import mock +import six + + +class FakeConfigFile(object): + """Contextmanager and decorator for mocking config files. + + :param text_config: contents of configuration to parse by oslo.config + :type text_config: str + """ + def __init__(self, text_config): + self.text_config = text_config + + def __enter__(self): + if six.PY3: + func = 'builtins.open' + else: + func = '__builtin__.open' + + self.patcher = mock.patch(func, + return_value=io.BytesIO(self.text_config)) + self.patcher.start() + + def __exit__(self, *args, **kwargs): + self.patcher.stop() + + def __call__(self, f): + @functools.wraps(f) + def wrapper(*args, **kwargs): + with self: + return f(*args, **kwargs) + return wrapper diff --git a/requirements.txt b/requirements.txt index a8b55d12..9a03e547 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,5 @@ pbr>=1.6 Babel>=1.3 Jinja2>=2.8 # BSD License (3 clause) kazoo>=2.2 +oslo.config>=2.7.0 # Apache-2.0 PyYAML>=3.1.0 diff --git a/setup.cfg b/setup.cfg index 924c6dcd..c223896a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,6 +30,8 @@ data_files = console_scripts = kolla-mesos-deploy = kolla_mesos.cmd.deploy:main kolla-mesos-config = kolla_mesos.cmd.config:main +oslo.config.opts = + kolla_mesos = kolla_mesos.opts:list_opts [build_sphinx] source-dir = doc/source diff --git a/tools/generate_config_file_samples.sh b/tools/generate_config_file_samples.sh new file mode 100755 index 00000000..b0c314a9 --- /dev/null +++ b/tools/generate_config_file_samples.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +# 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. + +set -e + +GEN_CMD=oslo-config-generator + +if ! type "$GEN_CMD" > /dev/null; then + echo "ERROR: $GEN_CMD not installed on the system." + exit 1 +fi + +for file in `ls etc/oslo-config-generator/*`; do + $GEN_CMD --config-file=$file +done + +set -x diff --git a/tox.ini b/tox.ini index 2d633381..17dfa428 100644 --- a/tox.ini +++ b/tox.ini @@ -45,3 +45,6 @@ show-source = True ignore = E123,E125 builtins = _ exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build + +[testenv:genconfig] +commands = {toxinidir}/tools/generate_config_file_samples.sh diff --git a/vagrant/provision.sh b/vagrant/provision.sh index 5163f050..981bb87a 100644 --- a/vagrant/provision.sh +++ b/vagrant/provision.sh @@ -12,16 +12,23 @@ enabled=1 gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg EOF -yum -y install docker-engine epel-release git python-pip +yum -y install docker-engine epel-release git python-devel vim-enhanced +yum -y install python-pip +yum -y groupinstall "Development Tools" +yum clean # Start services systemctl enable docker systemctl start docker # Fetch and install pip packages +pip install tox sudo -u vagrant git clone https://github.com/openstack/kolla ~vagrant/kolla pip install ~vagrant/kolla pip install ~vagrant/kolla-mesos -# Copy configuration +# Generate and copy configuration +sudo -u vagrant bash -c "cd ~vagrant/kolla-mesos && tox -e genconfig" +mkdir -p /etc/kolla-mesos cp -r ~vagrant/kolla/etc/kolla/ /etc/kolla +cp ~vagrant/kolla-mesos/etc/kolla-mesos.conf.sample /etc/kolla-mesos/kolla-mesos.conf