mirror of
https://github.com/clearlinux/clearstack.git
synced 2026-06-15 18:46:35 +00:00
initial commit
add sources
This commit is contained in:
+22
@@ -0,0 +1,22 @@
|
||||
.coverage
|
||||
cover/
|
||||
.testrepository
|
||||
subunit.log
|
||||
.venv
|
||||
*.pyc
|
||||
.idea
|
||||
*.sw?
|
||||
*.egg?
|
||||
*~
|
||||
.tox
|
||||
ChangeLog
|
||||
build
|
||||
dist
|
||||
clearstack.egg-info
|
||||
clearstack/versioninfo
|
||||
# Development environment files
|
||||
.project
|
||||
.pydevproject
|
||||
.DS_Store
|
||||
covhtml/
|
||||
tags
|
||||
@@ -0,0 +1,4 @@
|
||||
Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
Julio Montes <julio.montes@intel.com>
|
||||
Obed Muñoz <obed.n.munoz@intel.com>
|
||||
Victor Morales <victor.morales@intel.com>
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
Clearstack Style Commandments
|
||||
==============================
|
||||
|
||||
- Step 1: Read the OpenStack Style Commandments
|
||||
http://docs.openstack.org/developer/hacking/
|
||||
- Step 2: Read on
|
||||
|
||||
Docstrings
|
||||
----------
|
||||
|
||||
Docstrings should ONLY use triple-double-quotes (``"""``)
|
||||
|
||||
Single-line docstrings should NEVER have extraneous whitespace
|
||||
between enclosing triple-double-quotes.
|
||||
|
||||
Deviation! Sentence fragments do not have punctuation. Specifically in the
|
||||
command classes the one line docstring is also the help string for that
|
||||
command and those do not have periods.
|
||||
|
||||
"""A one line docstring looks like this"""
|
||||
|
||||
Calling Methods
|
||||
---------------
|
||||
|
||||
Deviation! When breaking up method calls due to the 79 char line length limit,
|
||||
use the alternate 4 space indent. With the first argument on the succeeding
|
||||
line all arguments will then be vertically aligned. Use the same convention
|
||||
used with other data structure literals and terminate the method call with
|
||||
the last argument line ending with a comma and the closing paren on its own
|
||||
line indented to the starting line level.
|
||||
|
||||
unnecessarily_long_function_name(
|
||||
'string one',
|
||||
'string two',
|
||||
kwarg1=constants.ACTIVE,
|
||||
kwarg2=['a', 'b', 'c'],
|
||||
)
|
||||
|
||||
Python 3.x Compatibility
|
||||
------------------------
|
||||
|
||||
Clearstack is only Python 3.4 compatible. Common guidelines:
|
||||
|
||||
* print statements are functions: print statements should be converted
|
||||
to an appropriate log or other output mechanism.
|
||||
* Use six where applicable: x.iteritems is converted to six.iteritems(x)
|
||||
for example
|
||||
|
||||
Running Tests
|
||||
-------------
|
||||
The testing system is based on a combination of tox and testr. If you just
|
||||
want to run the whole suite, run `tox` and all will be fine. However, if
|
||||
you'd like to dig in a bit more, you might want to learn some things about
|
||||
testr itself. A basic walkthrough for OpenStack can be found at
|
||||
http://wiki.openstack.org/testr
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
@@ -174,29 +175,3 @@
|
||||
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.
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
Metadata-Version: 1.1
|
||||
Name: clearstack
|
||||
Version: 1.1.4
|
||||
Summary: Tool for set up an Openstack environment
|
||||
Home-page:
|
||||
Author: Alberto Murillo, Julio Montes, Obed Muñoz, Victor Morales
|
||||
License: Apache-2.0
|
||||
Description: Tool for set up an Openstack environment
|
||||
Keywords: Openstack
|
||||
Platform: Unix
|
||||
Classifier: Environment :: OpenStack
|
||||
Classifier: Intended Audience :: Information Technology
|
||||
Classifier: Intended Audience :: System Administrators
|
||||
Classifier: License :: OSI Approved :: Apache Software License
|
||||
Classifier: Operating System :: POSIX :: Linux
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.3
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
|
||||
A tool to deploy components of Openstack on multiple servers with Clear Linux* Project for Intel Architecture installed
|
||||
|
||||
====
|
||||
|
||||
Contents:
|
||||
|
||||
1) Description of this project
|
||||
2) Compiling, prerequisites
|
||||
3) Bugs and feedback?
|
||||
|
||||
====
|
||||
|
||||
|
||||
====
|
||||
|
||||
2. Compiling
|
||||
|
||||
$ pip3 install -r requirements-py3.txt
|
||||
$ python3 setup.py install
|
||||
|
||||
====
|
||||
|
||||
3. Bugs, feedback, contact
|
||||
|
||||
clearstack is hosted on github. You can find releases, an issue
|
||||
tracker and git sources on github.com/clearlinux/clearstack. For
|
||||
mailing lists, subscribe to dev@lists.clearlinux.org (via
|
||||
lists.clearlinux.org).
|
||||
|
||||
This project has many contributors. Not all may be mentioned in the
|
||||
AUTHORS file.
|
||||
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 pbr.version
|
||||
|
||||
|
||||
__version__ = pbr.version.VersionInfo('clearstack').version_string()
|
||||
@@ -0,0 +1,65 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 os
|
||||
|
||||
import configparser
|
||||
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.common.util import LOG
|
||||
from clearstack.common.singleton import Singleton
|
||||
|
||||
|
||||
@Singleton
|
||||
class AnswerFile:
|
||||
def generate(self, file, variables_cmd):
|
||||
with open(file, "w") as f:
|
||||
f.write("[general]\n\n")
|
||||
for group in Controller.get().get_all_groups():
|
||||
for argument in group.get_all_arguments():
|
||||
f.write("# {0}\n".format(argument.description))
|
||||
value = variables_cmd.get(argument.conf_name,
|
||||
argument.default_value)
|
||||
f.write("{0}={1}\n\n".format(argument.conf_name, value))
|
||||
|
||||
def read(self, file, variables_cmd):
|
||||
conf = Controller.get().CONF
|
||||
config = configparser.RawConfigParser()
|
||||
config.optionxform = str
|
||||
if not os.path.isfile(file):
|
||||
raise IOError("file {0} not found".format(file))
|
||||
|
||||
""" Validate option in answer file"""
|
||||
config.read(file)
|
||||
if not config.has_section('general'):
|
||||
raise KeyError("answer file {0} doesn't have general"
|
||||
" section".format(file))
|
||||
conf_file = dict(config['general'])
|
||||
conf_file.update(variables_cmd) # override variables
|
||||
conf.update(conf_file)
|
||||
|
||||
try:
|
||||
Controller.get().validate_groups(conf_file)
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
all_args = Controller.get().get_all_arguments()
|
||||
for non_supported in (set(conf_file) - set(all_args)):
|
||||
LOG.warn("clearstack: variable {0} is not"
|
||||
" supported yet".format(non_supported))
|
||||
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
|
||||
class Argument(object):
|
||||
def __init__(self, cmd_option, description,
|
||||
conf_name, default_value, validators=[],
|
||||
options=None):
|
||||
self.cmd_option = cmd_option
|
||||
self.description = description
|
||||
self.conf_name = conf_name
|
||||
self.default_value = default_value
|
||||
self.validators = validators
|
||||
self.option_list = options
|
||||
|
||||
def validate(self, option):
|
||||
for validator in self.validators:
|
||||
try:
|
||||
validator(option)
|
||||
except ValueError as e:
|
||||
raise ValueError("{0}: {1}".format(self.conf_name, str(e)))
|
||||
@@ -0,0 +1,35 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
|
||||
class Singleton:
|
||||
def __init__(self, decorated):
|
||||
self._decorated = decorated
|
||||
|
||||
def get(self):
|
||||
try:
|
||||
return self._instance
|
||||
except AttributeError:
|
||||
self._instance = self._decorated()
|
||||
return self._instance
|
||||
|
||||
def __call__(self):
|
||||
raise TypeError('Singletons must be accessed through `Get()`.')
|
||||
|
||||
def __instancecheck__(self, inst):
|
||||
return isinstance(inst, self._decorated)
|
||||
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 os
|
||||
|
||||
from common import util
|
||||
from common.util import LOG
|
||||
|
||||
|
||||
class Client():
|
||||
def install(bundle):
|
||||
if not os.path.isfile("/usr/share/clear/bundles/" + str(bundle)) and \
|
||||
not os.path.isfile("/usr/share/clear/bundles/"
|
||||
"openstack-all-in-one"):
|
||||
LOG.info("Installing {0} bundle".format(bundle))
|
||||
cmd = "clr_bundle_add -V {0}".format(bundle)
|
||||
if(os.path.isfile("/bin/swupd")):
|
||||
cmd = "swupd bundle-add -V {0}".format(bundle)
|
||||
|
||||
try:
|
||||
stdout, stderr = util.run_command(cmd)
|
||||
if stderr:
|
||||
LOG.error("swupd bundle-add: {0}\n{1}"
|
||||
.format(stdout, stderr))
|
||||
except Exception:
|
||||
LOG.error("clearstack: cannot install"
|
||||
" {0} bundle".format(bundle))
|
||||
@@ -0,0 +1,210 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 os
|
||||
import socket
|
||||
import subprocess
|
||||
import configparser
|
||||
import netifaces
|
||||
import ipaddress
|
||||
import logging
|
||||
from errno import EACCES, EPERM, ENOENT
|
||||
|
||||
HOST_LOG_DIR = '/var/log/clearstack'
|
||||
HOST_LOG_FILE = "{0}/clearstack.log".format(HOST_LOG_DIR)
|
||||
LOG_DIR = '/var/log/clearstack'
|
||||
if os.geteuid() != 0:
|
||||
LOG_DIR = '/tmp/log/clearstack'
|
||||
LOG_FILE = "{0}/clearstack.log".format(LOG_DIR)
|
||||
LOG = logging.getLogger("Clearstack")
|
||||
|
||||
|
||||
def _print_error_message(self, e, file_name):
|
||||
# PermissionError
|
||||
if e.errno == EPERM or e.errno == EACCES:
|
||||
print("PermissionError error({0}): {1} for:\n{2}".format(e.errno,
|
||||
e.strerror, file_name))
|
||||
# FileNotFoundError
|
||||
elif e.errno == ENOENT:
|
||||
print("FileNotFoundError error({0}): {1} as:\n{2}".format(e.errno,
|
||||
e.strerror, file_name))
|
||||
elif IOError:
|
||||
print("I/O error({0}): {1} as:\n{2}".format(e.errno, e.strerror,
|
||||
file_name))
|
||||
elif OSError:
|
||||
print("OS error({0}): {1} as:\n{2}".format(e.errno, e.strerror,
|
||||
file_name))
|
||||
|
||||
|
||||
def setup_debugging(debug, is_remote_host=True):
|
||||
if not os.path.isdir(LOG_DIR):
|
||||
os.makedirs(LOG_DIR)
|
||||
try:
|
||||
logging.basicConfig(filename=LOG_FILE,
|
||||
format='%(message)s',
|
||||
level=logging.INFO)
|
||||
except (IOError, OSError) as e:
|
||||
_print_error_message(e, LOG_FILE)
|
||||
|
||||
''' paramiko detects all output as error (stderr)'''
|
||||
''' if it is a remote host redirect output to log file '''
|
||||
if not is_remote_host:
|
||||
sh = logging.StreamHandler()
|
||||
sh.setLevel(logging.INFO)
|
||||
LOG.addHandler(sh)
|
||||
|
||||
if debug:
|
||||
LOG.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
def run_command(command, stdin=None, environ=None, debug=True):
|
||||
"""Returns (stdout, stderr), raises error on non-zero return code"""
|
||||
if environ is None:
|
||||
env = None
|
||||
else:
|
||||
env = os.environ.copy()
|
||||
env.update(environ)
|
||||
|
||||
if debug: # to avoid show passwords
|
||||
LOG.debug("command: %s", command)
|
||||
|
||||
proc = subprocess.Popen(['bash', '-c', command],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
stdin=subprocess.PIPE, env=env)
|
||||
stdout, stderr = proc.communicate()
|
||||
if proc.returncode and stderr:
|
||||
raise Exception("Error running: {0}\n{1}"
|
||||
.format(command, stderr.decode("utf-8")))
|
||||
|
||||
return stdout, stderr
|
||||
|
||||
|
||||
def str2bool(value):
|
||||
return value.lower() in ("yes", "true", "t", "1", "y")
|
||||
|
||||
|
||||
def write_config(file, data):
|
||||
directory = os.path.dirname(file)
|
||||
if not os.path.isdir(directory):
|
||||
os.makedirs(directory)
|
||||
config = configparser.RawConfigParser(allow_no_value=True)
|
||||
if os.path.isfile(file):
|
||||
config.read(file)
|
||||
config.read_string(data)
|
||||
with open(file, 'w') as f:
|
||||
config.write(f)
|
||||
|
||||
|
||||
def write_properties(file, data):
|
||||
directory = os.path.dirname(file)
|
||||
if not os.path.isdir(directory):
|
||||
os.makedirs(directory)
|
||||
if os.path.isfile(file):
|
||||
with open(file, 'r') as f:
|
||||
for l in f.readlines():
|
||||
key, value = [x.strip() for x in l.split('=')]
|
||||
data[key] = value
|
||||
output = ""
|
||||
for key, value in data.items():
|
||||
output += "%s = %s\n" % (key, value)
|
||||
with open(file, 'w') as f:
|
||||
f.write(output)
|
||||
|
||||
|
||||
def get_option(file, section, option):
|
||||
config = configparser.RawConfigParser(allow_no_value=True)
|
||||
config.read(file)
|
||||
return config[section][option]
|
||||
|
||||
|
||||
def delete_option(file, section, option=None):
|
||||
config = configparser.RawConfigParser(allow_no_value=True)
|
||||
config.read(file)
|
||||
if option:
|
||||
config.remove_option(section, option)
|
||||
else:
|
||||
config.remove_section(section)
|
||||
with open(file, 'w') as f:
|
||||
config.write(f)
|
||||
|
||||
|
||||
# write in file if not exist the line
|
||||
def write_in_file_ine(file, data):
|
||||
with open(file, 'a+') as f:
|
||||
f.seek(0)
|
||||
if not any(data == x.rstrip('\r\n') for x in f):
|
||||
f.write(data + '\n')
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_dns():
|
||||
with open('/etc/resolv.conf', 'r') as f:
|
||||
return [l.split(' ')[1].strip() for l in f.readlines()
|
||||
if l.startswith('nameserver')]
|
||||
|
||||
|
||||
def get_netmask():
|
||||
interface = get_net_interface()
|
||||
mask = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['netmask']
|
||||
return ipaddress.IPv4Network('0.0.0.0/%s' % mask).prefixlen
|
||||
|
||||
|
||||
def get_gateway():
|
||||
return netifaces.gateways()['default'][netifaces.AF_INET][0]
|
||||
|
||||
|
||||
def get_net_interface():
|
||||
return (netifaces.gateways())['default'][netifaces.AF_INET][1]
|
||||
|
||||
|
||||
def get_ip():
|
||||
interface = get_net_interface()
|
||||
return netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr']
|
||||
|
||||
|
||||
def is_localhost(host):
|
||||
return host == "localhost" or host == "127.0.0.1" or \
|
||||
host == socket.gethostname() or host == get_ip()
|
||||
|
||||
|
||||
def has_localhost(hosts):
|
||||
for host in hosts:
|
||||
if is_localhost(host):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def remove_localhost(hosts):
|
||||
for host in hosts.copy():
|
||||
if is_localhost(host):
|
||||
hosts.remove(host)
|
||||
|
||||
|
||||
def ensure_directory(dir):
|
||||
if not os.path.exists(dir):
|
||||
os.makedirs(dir)
|
||||
|
||||
|
||||
def link_file(source, target):
|
||||
dir = os.path.dirname(target)
|
||||
ensure_directory(dir)
|
||||
if os.path.exists(target):
|
||||
os.remove(target)
|
||||
os.symlink(source, target)
|
||||
@@ -0,0 +1,89 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 clearstack.group import Group
|
||||
from clearstack.sequence import Sequence
|
||||
from clearstack.common.singleton import Singleton
|
||||
|
||||
DEBUG = False
|
||||
|
||||
|
||||
@Singleton
|
||||
class Controller:
|
||||
CONF = {}
|
||||
_plugins = []
|
||||
_groups = []
|
||||
_sequences = []
|
||||
|
||||
def add_sequence(self, desc, function, args=None):
|
||||
self._sequences.append(Sequence(desc, function, args))
|
||||
|
||||
def run_all_sequences(self):
|
||||
for seq in self._sequences:
|
||||
try:
|
||||
seq.run()
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
def add_plugin(self, plugin):
|
||||
self._plugins.append(plugin)
|
||||
|
||||
def get_all_plugins(self):
|
||||
return self._plugins
|
||||
|
||||
def add_group(self, name, args):
|
||||
self._groups.append(Group(name, args))
|
||||
|
||||
def get_all_groups(self):
|
||||
return self._groups
|
||||
|
||||
def get_all_arguments(self):
|
||||
"""Get a list of the configuration argument loaded"""
|
||||
arguments = []
|
||||
for group in self._groups:
|
||||
arguments.extend([argument.conf_name
|
||||
for argument in group.get_all_arguments()])
|
||||
return arguments
|
||||
|
||||
def remove_argument(self, group_name, conf_name):
|
||||
for group in self._groups:
|
||||
if group.group_name == group_name:
|
||||
for arg in group.arguments:
|
||||
if arg.conf_name == conf_name:
|
||||
group.arguments.remove(arg)
|
||||
return True
|
||||
return False
|
||||
|
||||
def remove_validators(self, conf_names):
|
||||
for group in self._groups:
|
||||
for arg in group.arguments:
|
||||
if arg.conf_name in conf_names:
|
||||
arg.validators.clear()
|
||||
|
||||
def validate_groups(self, conf_values):
|
||||
""" Load validation functions, in order to check
|
||||
the values in the answer file """
|
||||
arguments = {}
|
||||
for group in self._groups:
|
||||
for arg in group.get_all_arguments():
|
||||
try:
|
||||
arg.validate(conf_values[arg.conf_name])
|
||||
except Exception as e:
|
||||
raise Exception("{0}: {1}".format(arg.conf_name, str(e)))
|
||||
return arguments
|
||||
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
|
||||
class Group(object):
|
||||
def __init__(self, group_name, arguments):
|
||||
self.group_name = group_name
|
||||
self.arguments = arguments
|
||||
|
||||
def get_group_name(self):
|
||||
return self.group_name
|
||||
|
||||
def get_all_arguments(self):
|
||||
return self.arguments
|
||||
@@ -0,0 +1,58 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 socket
|
||||
|
||||
from modules.keystone import Keystone
|
||||
from modules.openstack import OpenStackService
|
||||
from modules.conf import CONF
|
||||
from common import util
|
||||
from common.singleton import Singleton
|
||||
|
||||
|
||||
@Singleton
|
||||
class Ceilometer(OpenStackService):
|
||||
_name = "ceilometer"
|
||||
_bundle = "openstack-telemetry"
|
||||
_services = ["ceilometer-agent-central", "ceilometer-agent-notification",
|
||||
"ceilometer-api", "ceilometer-collector",
|
||||
"ceilometer-alarm-evaluator", "ceilometer-alarm-notifier"]
|
||||
_type = "metering"
|
||||
_description = "OpenStack Telemetry Service"
|
||||
_public_url = "http://{0}:8777".format(CONF['CONFIG_CONTROLLER_HOST'])
|
||||
|
||||
def config_database(self, configfile):
|
||||
dbpass = CONF['CONFIG_%s_DB_PW' % self._name.upper()]
|
||||
dbhost = socket.gethostbyaddr(CONF['CONFIG_MONGODB_HOST'])[0]
|
||||
config = ("[database]\n"
|
||||
"connection=mongodb://{0}:{1}@{2}:27017/{0}"
|
||||
.format(self._name, dbpass, dbhost))
|
||||
util.write_config(configfile, config)
|
||||
|
||||
def config_service_credentials(self, configfile):
|
||||
keystone = Keystone.get()
|
||||
config = \
|
||||
"[service_credentials]\n" + \
|
||||
"os_auth_url = %s\n" % keystone._admin_url + \
|
||||
"os_username = %s\n" % self._name + \
|
||||
"os_tenant_name = service\n" + \
|
||||
"os_password = %s\n" % self._password + \
|
||||
"os_endpoint_type = internalURL\n" + \
|
||||
"os_region_name = %s\n" % self._region
|
||||
util.write_config(configfile, config)
|
||||
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 common import util
|
||||
|
||||
|
||||
def support_hw_acceleration():
|
||||
stdout, stderr = util.run_command("egrep -c '(vmx|svm)' /proc/cpuinfo")
|
||||
return bool(int(stdout.decode('utf-8')))
|
||||
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 os
|
||||
import configparser
|
||||
|
||||
|
||||
_conf_file = "{0}/../defaults.conf".format(os.path.dirname(__file__))
|
||||
_config = configparser.RawConfigParser()
|
||||
_config.optionxform = str
|
||||
_config.read(_conf_file)
|
||||
|
||||
CONF = dict(_config['general'])
|
||||
|
||||
ENV = {"OS_PROJECT_DOMAIN_ID": "default",
|
||||
"OS_USER_DOMAIN_ID": "default",
|
||||
"OS_PROJECT_NAME": "admin",
|
||||
"OS_USERNAME": "admin",
|
||||
"OS_PASSWORD": "{0}".format(CONF['CONFIG_KEYSTONE_ADMIN_PW']),
|
||||
"OS_TENANT_NAME": "admin",
|
||||
"OS_AUTH_URL": "http://{0}:35357/v3"
|
||||
.format(CONF['CONFIG_CONTROLLER_HOST']),
|
||||
"OS_IDENTITY_API_VERSION": "3",
|
||||
"OS_IMAGE_API_VERSION": "2"}
|
||||
@@ -0,0 +1,64 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 os
|
||||
|
||||
from modules.openstack import OpenStackService
|
||||
from modules.conf import CONF
|
||||
from common import util
|
||||
from common.util import LOG
|
||||
from common.singleton import Singleton
|
||||
|
||||
|
||||
@Singleton
|
||||
class Glance(OpenStackService):
|
||||
_name = "glance"
|
||||
_bundle = "openstack-image"
|
||||
_services = ["glance-api", "glance-registry"]
|
||||
_type = "image"
|
||||
_description = "OpenStack Image"
|
||||
_public_url = "http://{0}:9292".format(CONF['CONFIG_CONTROLLER_HOST'])
|
||||
|
||||
def sync_database(self):
|
||||
LOG.debug("syncing database")
|
||||
util.run_command("su -s /bin/sh -c"
|
||||
" \"glance-manage db_sync\" glance")
|
||||
|
||||
def create_image(self, name, format, url, public=False):
|
||||
LOG.debug("Creating image %s" % name)
|
||||
try:
|
||||
util.run_command("openstack image show %s" % name,
|
||||
environ=self._env)
|
||||
except:
|
||||
command = ("openstack image create --disk-format %s %s"
|
||||
% (format, name))
|
||||
if os.path.isfile(url):
|
||||
command += " --file %s" % url
|
||||
else:
|
||||
command += " --location %s" % url
|
||||
if public:
|
||||
command += " --public"
|
||||
util.run_command(command, environ=self._env)
|
||||
|
||||
def ceilometer_enable(self, configfile):
|
||||
self.config_rabbitmq(configfile)
|
||||
config = ("[DEFAULT]\n"
|
||||
"notification_driver = messagingv2\n")
|
||||
util.write_config(configfile, config)
|
||||
@@ -0,0 +1,73 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 configparser
|
||||
|
||||
from modules.openstack import OpenStackService
|
||||
from modules.conf import CONF
|
||||
from common import util
|
||||
from common.util import LOG
|
||||
from common.singleton import Singleton
|
||||
|
||||
|
||||
@Singleton
|
||||
class Heat(OpenStackService):
|
||||
_name = "heat"
|
||||
_bundle = "openstack-orchestration"
|
||||
_services = ["heat-api", "heat-api-cfn", "heat-engine"]
|
||||
_type = "orchestration"
|
||||
_description = "OpenStack Orchestration"
|
||||
_public_url = ("http://{0}:8004/v1/%\(tenant_id\)s"
|
||||
.format(CONF['CONFIG_CONTROLLER_HOST']))
|
||||
|
||||
domain_admin = CONF['CONFIG_HEAT_DOMAIN_ADMIN']
|
||||
domain_admin_pw = CONF['CONFIG_HEAT_DOMAIN_PASSWORD']
|
||||
domain_name = CONF['CONFIG_HEAT_DOMAIN']
|
||||
|
||||
def sync_database(self):
|
||||
LOG.debug("syncing database")
|
||||
util.run_command("su -s /bin/sh -c"
|
||||
" \"heat-manage db_sync\" heat")
|
||||
|
||||
def config_auth(self, configfile):
|
||||
OpenStackService.config_auth(self, configfile)
|
||||
config = configparser.RawConfigParser(allow_no_value=True)
|
||||
config.read(configfile)
|
||||
auth_uri = config['keystone_authtoken']['auth_uri']
|
||||
config['trustee'] = config['keystone_authtoken']
|
||||
if not config.has_section('clients_keystone'):
|
||||
config.add_section('clients_keystone')
|
||||
config['clients_keystone']['auth_uri'] = auth_uri
|
||||
if not config.has_section('ec2authtoken'):
|
||||
config.add_section('ec2authtoken')
|
||||
config['ec2authtoken']['auth_uri'] = auth_uri
|
||||
with open(configfile, 'w') as f:
|
||||
config.write(f)
|
||||
|
||||
def config_domain(self, configfile):
|
||||
config = ("[DEFAULT]\n"
|
||||
"heat_metadata_server_url = http://{0}:8000\n"
|
||||
"heat_waitcondition_server_url = "
|
||||
"http://{0}:8000/v1/waitcondition\n"
|
||||
"stack_domain_admin = {1}\n"
|
||||
"stack_domain_admin_password = {2}\n"
|
||||
"stack_user_domain_name = {3}\n"
|
||||
.format(self._controller, self.domain_admin,
|
||||
self.domain_admin_pw, self.domain_name))
|
||||
util.write_config(configfile, config)
|
||||
@@ -0,0 +1,39 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Obed Muñoz <obed.n.munoz@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 modules.openstack import OpenStackService
|
||||
from modules.conf import CONF
|
||||
from common.singleton import Singleton
|
||||
|
||||
|
||||
@Singleton
|
||||
class Horizon(OpenStackService):
|
||||
_name = "horizon"
|
||||
_bundle = "openstack-dashboard"
|
||||
if CONF['CONFIG_HTTP_SERVICE'] == 'nginx':
|
||||
_services = ["nginx", "uwsgi@horizon.socket"]
|
||||
elif CONF['CONFIG_HTTP_SERVICE'] == 'apache2':
|
||||
_services = ["httpd"]
|
||||
# These are needed by OpenStackService but not used by horizon
|
||||
_type = ""
|
||||
_public_url = ""
|
||||
_description = ""
|
||||
_password = True
|
||||
@@ -0,0 +1,72 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Obed Muñoz <obed.n.munoz@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 modules.openstack import OpenStackService
|
||||
from modules.conf import CONF
|
||||
from common import util
|
||||
from common.util import LOG
|
||||
from common.singleton import Singleton
|
||||
|
||||
|
||||
@Singleton
|
||||
class Keystone(OpenStackService):
|
||||
_name = "keystone"
|
||||
_bundle = "openstack-identity"
|
||||
if CONF['CONFIG_HTTP_SERVICE'] == 'nginx':
|
||||
_services = ["memcached", "nginx", "uwsgi@keystone-admin.socket",
|
||||
"uwsgi@keystone-public.socket"]
|
||||
elif CONF['CONFIG_HTTP_SERVICE'] == 'apache2':
|
||||
_services = ["memcached", "httpd"]
|
||||
else:
|
||||
_services = ["keystone"]
|
||||
_type = "identity"
|
||||
_description = "OpenStack Identity"
|
||||
_user = "admin"
|
||||
_password = CONF['CONFIG_KEYSTONE_ADMIN_PW']
|
||||
_public_url = "http://%s:5000/v3" % CONF['CONFIG_CONTROLLER_HOST']
|
||||
_internal_url = _public_url
|
||||
_admin_url = "http://%s:35357/v3" % CONF['CONFIG_CONTROLLER_HOST']
|
||||
_env = {"OS_TOKEN": CONF['CONFIG_KEYSTONE_ADMIN_TOKEN'],
|
||||
"OS_URL": "http://{0}:35357/v3"
|
||||
.format(CONF['CONFIG_CONTROLLER_HOST']),
|
||||
"OS_IDENTITY_API_VERSION": "3"}
|
||||
|
||||
def sync_database(self):
|
||||
LOG.debug("syncing database")
|
||||
util.run_command("su -s /bin/sh -c"
|
||||
" \"keystone-manage db_sync\" keystone")
|
||||
|
||||
def create_project(self, project, description):
|
||||
LOG.debug("setting up %s project" % project)
|
||||
try:
|
||||
""" test if project already exists """
|
||||
util.run_command("openstack project show %s" % project,
|
||||
environ=self._env)
|
||||
except:
|
||||
util.run_command("openstack project create --domain default"
|
||||
" --description \"%s\" %s"
|
||||
% (description, project), environ=self._env)
|
||||
|
||||
def config_admin_token(self, configfile):
|
||||
config = \
|
||||
"[DEFAULT]\n" + \
|
||||
"admin_token=%s\n" % CONF['CONFIG_KEYSTONE_ADMIN_TOKEN']
|
||||
util.write_config(configfile, config)
|
||||
@@ -0,0 +1,111 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Obed Muñoz <obed.n.munoz@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 sys
|
||||
import socket
|
||||
|
||||
from common import util
|
||||
from common.singleton import Singleton
|
||||
from common.swupd import Client as swupd_client
|
||||
from common.util import LOG
|
||||
from modules.conf import CONF
|
||||
|
||||
|
||||
@Singleton
|
||||
class MariaDB:
|
||||
def install(self):
|
||||
swupd_client.install("database-mariadb")
|
||||
|
||||
def start_server(self):
|
||||
LOG.debug("starting services")
|
||||
util.run_command("systemctl enable mariadb")
|
||||
util.run_command("systemctl restart mariadb")
|
||||
|
||||
def configure(self):
|
||||
config_file = "/etc/mariadb/openstack.cnf"
|
||||
config = """
|
||||
[mysqld]
|
||||
default-storage-engine = innodb
|
||||
innodb_file_per_table
|
||||
collation-server = utf8_general_ci
|
||||
init-connect = 'SET NAMES utf8'
|
||||
character-set-server = utf8
|
||||
bind-address = 0.0.0.0
|
||||
"""
|
||||
util.write_config(config_file, config)
|
||||
|
||||
def secure_installation(self, user, password):
|
||||
LOG.debug("secure installation mariadb")
|
||||
try:
|
||||
""" test if mysql has a password """
|
||||
util.run_command("mysql -u{0} -e \"\"".format(user), debug=False)
|
||||
""" Secure the database service """
|
||||
util.run_command('mysqladmin -u root password "{0}"'
|
||||
.format(password, debug=False))
|
||||
util.run_command('mysql -u root -p"{0}" -e "UPDATE mysql.user '
|
||||
'SET Password=PASSWORD(\'{0}\') '
|
||||
'WHERE User=\'root\'"'
|
||||
.format(password, debug=False))
|
||||
util.run_command('mysql -u root -p"{0}" -e "DELETE FROM '
|
||||
'mysql.user WHERE User=\'root\' AND Host '
|
||||
' NOT IN (\'localhost\', \'127.0.0.1\', '
|
||||
'\'::1\')"'
|
||||
.format(password, debug=False))
|
||||
util.run_command('mysql -u root -p"{0}" -e "DELETE FROM '
|
||||
'mysql.user WHERE User=\'\'"'
|
||||
.format(password, debug=False))
|
||||
util.run_command('mysql -u root -p"{0}" -e "DELETE FROM mysql.db '
|
||||
'WHERE Db=\'test\' OR Db=\'test\_%\'"'
|
||||
.format(password, debug=False))
|
||||
util.run_command('mysql -u root -p"{0}" -e '
|
||||
'"FLUSH PRIVILEGES"'
|
||||
.format(password, debug=False))
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
""" verify the password """
|
||||
util.run_command("mysql -u{0} -p{1} -e \"\""
|
||||
.format(user, password), debug=False)
|
||||
except:
|
||||
LOG.error("clearstack: cannot connect to mysql database,"
|
||||
" the password is incorrect")
|
||||
return sys.exit(1)
|
||||
|
||||
def setup_database(self, database, user, password, host):
|
||||
LOG.debug("setting up database")
|
||||
mariadb_host = socket.gethostbyaddr(CONF["CONFIG_MARIADB_HOST"])[0]
|
||||
mariadb_user = CONF["CONFIG_MARIADB_USER"]
|
||||
mariadb_pw = CONF["CONFIG_MARIADB_PW"]
|
||||
util.run_command("mysql -u{0} -p{1} -h{2} -e"
|
||||
" \"CREATE DATABASE if not exists {3};\""
|
||||
.format(mariadb_user, mariadb_pw, mariadb_host,
|
||||
database), debug=False)
|
||||
util.run_command("mysql -u{0} -p{1} -h{2} -e"
|
||||
" \"GRANT ALL PRIVILEGES ON {3}.* TO"
|
||||
" '{4}'@'localhost' IDENTIFIED BY '{5}';\""
|
||||
.format(mariadb_user, mariadb_pw, mariadb_host,
|
||||
database, user, password), debug=False)
|
||||
util.run_command("mysql -u{0} -p{1} -h{2} -e"
|
||||
" \"GRANT ALL PRIVILEGES ON {3}.* TO '{4}'@'{5}'"
|
||||
" IDENTIFIED BY '{6}';\""
|
||||
.format(mariadb_user, mariadb_pw, mariadb_host,
|
||||
database, user, host, password), debug=False)
|
||||
@@ -0,0 +1,56 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 common import util
|
||||
from common.singleton import Singleton
|
||||
from common.swupd import Client as swupd_client
|
||||
from common.util import LOG
|
||||
|
||||
|
||||
@Singleton
|
||||
class MongoDB:
|
||||
def install(self):
|
||||
swupd_client.install("database-mongodb")
|
||||
|
||||
def start_server(self):
|
||||
LOG.debug("starting services")
|
||||
util.run_command("systemctl enable mongodb")
|
||||
util.run_command("systemctl restart mongodb")
|
||||
count = 0
|
||||
while count < 10:
|
||||
try:
|
||||
util.run_command("mongo --host 127.0.0.1")
|
||||
return
|
||||
except:
|
||||
util.run_command("sleep 1")
|
||||
count += 1
|
||||
raise Exception("Failed to start mongodb service")
|
||||
|
||||
def configure(self):
|
||||
config_file = "/etc/mongodb/mongod.conf"
|
||||
config = {'bind_ip': '0.0.0.0'}
|
||||
util.write_properties(config_file, config)
|
||||
|
||||
def setup_database(self, database, user, password):
|
||||
cmd = ("mongo --host 127.0.0.1 --eval '"
|
||||
"db = db.getSiblingDB(\"%s\");"
|
||||
"db.createUser({user: \"%s\",pwd: \"%s\","
|
||||
"roles: [ \"readWrite\", \"dbAdmin\" ]})'"
|
||||
% (database, user, password))
|
||||
util.run_command(cmd)
|
||||
@@ -0,0 +1,254 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Obed Muñoz <obed.n.munoz@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 ipaddress import IPv4Network
|
||||
|
||||
from modules.keystone import Keystone
|
||||
from modules.nova import Nova
|
||||
from modules.openstack import OpenStackService
|
||||
from modules.conf import CONF
|
||||
from common import util
|
||||
from common.util import LOG
|
||||
from common.singleton import Singleton
|
||||
|
||||
|
||||
metadata_password = CONF['CONFIG_NEUTRON_METADATA_PW']
|
||||
tenant_network_types = CONF['CONFIG_NEUTRON_ML2_TENANT_NETWORK_TYPES']
|
||||
mechanism_drivers = CONF['CONFIG_NEUTRON_ML2_MECHANISM_DRIVERS']
|
||||
vni_ranges = CONF['CONFIG_NEUTRON_ML2_TUNNEL_ID_RANGES']
|
||||
type_drivers = CONF['CONFIG_NEUTRON_ML2_TYPE_DRIVERS']
|
||||
bridge_mappings = CONF['CONFIG_NEUTRON_LINUXBRIDGE_IFACES']
|
||||
flat_networks = CONF['CONFIG_NEUTRON_ML2_FLAT_NETWORKS']
|
||||
|
||||
|
||||
@Singleton
|
||||
class Neutron(OpenStackService):
|
||||
_name = "neutron"
|
||||
_bundle = "openstack-network"
|
||||
_services = ["neutron-server", "neutron-linuxbridge-agent",
|
||||
"neutron-dhcp-agent", "neutron-metadata-agent",
|
||||
"neutron-l3-agent"]
|
||||
_type = "network"
|
||||
_description = "OpenStack Networking"
|
||||
_public_url = ("http://{0}:9696"
|
||||
.format(CONF['CONFIG_CONTROLLER_HOST']))
|
||||
|
||||
def sync_database(self):
|
||||
LOG.debug("syncing database")
|
||||
util.run_command('su -s /bin/sh -c "neutron-db-manage '
|
||||
'--config-file /etc/neutron/neutron.conf '
|
||||
'--config-file /etc/neutron/plugins/ml2/ml2_conf.ini '
|
||||
'upgrade head" neutron')
|
||||
if util.str2bool(CONF['CONFIG_LBAAS_INSTALL']):
|
||||
util.run_command('su -s /bin/sh -c "neutron-db-manage '
|
||||
'--service lbaas upgrade head"')
|
||||
|
||||
def config_ml2_plugin(self):
|
||||
config = \
|
||||
"[DEFAULT]\n" + \
|
||||
"core_plugin = ml2\n" \
|
||||
"service_plugins = router\n" + \
|
||||
"allow_overlapping_ips = True\n"
|
||||
util.write_config("/etc/neutron/neutron.conf", config)
|
||||
config = \
|
||||
"[ml2]\n" + \
|
||||
"type_drivers = %s\n" % type_drivers + \
|
||||
"tenant_network_types = %s\n" % tenant_network_types + \
|
||||
"mechanism_drivers = %s\n" % mechanism_drivers + \
|
||||
"extension_drivers = port_security\n" + \
|
||||
"[ml2_type_flat]\n" + \
|
||||
"flat_networks = public\n" + \
|
||||
"[ml2_type_vxlan]\n" + \
|
||||
"vni_ranges = %s\n" % vni_ranges + \
|
||||
"[securitygroup]\n" + \
|
||||
"enable_ipset = True\n"
|
||||
util.write_config("/etc/neutron/plugins/ml2/ml2_conf.ini", config)
|
||||
util.link_file('/etc/neutron/plugins/ml2/ml2_conf.ini',
|
||||
'/etc/neutron/plugin.ini')
|
||||
|
||||
def config_linux_bridge_agent(self):
|
||||
config = \
|
||||
"[linux_bridge]\n" + \
|
||||
"physical_interface_mappings = %s\n" % bridge_mappings + \
|
||||
"[vxlan]\n" + \
|
||||
"enable_vxlan = True\n" + \
|
||||
"local_ip = %s\n" % util.get_ip() + \
|
||||
"l2_population = True\n" + \
|
||||
"[agent]\n" + \
|
||||
"prevent_arp_spoofing = True\n" + \
|
||||
"[securitygroup]\n" + \
|
||||
"enable_security_group = True\n" + \
|
||||
"firewall_driver = neutron.agent.linux.iptables_firewall." + \
|
||||
"IptablesFirewallDriver\n"
|
||||
util.write_config("/etc/neutron/plugins/ml2/linuxbridge_agent.ini",
|
||||
config)
|
||||
|
||||
def config_l3_agent(self, configfile):
|
||||
config = ("[DEFAULT]\n"
|
||||
"interface_driver = "
|
||||
"neutron.agent.linux.interface.BridgeInterfaceDriver\n"
|
||||
"external_network_bridge = \n")
|
||||
util.write_config(configfile, config)
|
||||
|
||||
def config_dhcp_agent(self, configfile):
|
||||
config = ("[DEFAULT]\n"
|
||||
"interface_driver = "
|
||||
"neutron.agent.linux.interface.BridgeInterfaceDriver\n"
|
||||
"dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq\n"
|
||||
"enable_isolated_metadata = True\n")
|
||||
util.write_config(configfile, config)
|
||||
|
||||
def config_metadata_agent(self, configfile):
|
||||
config = \
|
||||
"[DEFAULT]\n" + \
|
||||
"auth_uri = http://%s:5000\n" % self._controller + \
|
||||
"auth_url = http://%s:35357\n" % self._controller + \
|
||||
"auth_region = %s\n" % self._region + \
|
||||
"auth_plugin = password\n" + \
|
||||
"project_domain_id = default\n" + \
|
||||
"user_domain_id = default\n" + \
|
||||
"project_name = service\n" + \
|
||||
"username = %s\n" % self._name + \
|
||||
"password = %s\n" % self._password + \
|
||||
"nova_metadata_ip = %s\n" % self._controller + \
|
||||
"metadata_proxy_shared_secret = %s\n" % metadata_password
|
||||
util.write_config(configfile, config)
|
||||
|
||||
def config_nova(self, configfile):
|
||||
nova = Nova.get()
|
||||
config = ("[DEFAULT]\n"
|
||||
"notify_nova_on_port_status_changes = True\n"
|
||||
"notify_nova_on_port_data_changes = True\n"
|
||||
"nova_url = http://{0}:8774/v2\n"
|
||||
"[nova]\n"
|
||||
"auth_url = http://{0}:35357\n"
|
||||
"auth_plugin = password\n"
|
||||
"project_domain_id = default\n"
|
||||
"user_domain_id = default\n"
|
||||
"region_name = {1}\n"
|
||||
"project_name = service\n"
|
||||
"username = nova\n"
|
||||
"password = {2}\n"
|
||||
.format(self._controller, self._region, nova._password))
|
||||
util.write_config(configfile, config)
|
||||
|
||||
def config_neutron_on_nova(self, configfile):
|
||||
keystone = Keystone.get()
|
||||
config = \
|
||||
"[DEFAULT]\n" + \
|
||||
"network_api_class = nova.network.neutronv2.api.API\n" + \
|
||||
"security_group_api = neutron\n" + \
|
||||
"linuxnet_interface_driver = " + \
|
||||
"nova.network.linux_net.NeutronLinuxBridgeInterfaceDriver\n" + \
|
||||
"firewall_driver = nova.virt.firewall.NoopFirewallDriver\n" + \
|
||||
"[neutron]\n" + \
|
||||
"url = %s\n" % self._public_url + \
|
||||
"auth_url = %s\n" % keystone._admin_url + \
|
||||
"auth_plugin = password\n" + \
|
||||
"project_domain_id = default\n" + \
|
||||
"user_domain_id = default\n" + \
|
||||
"region_name = %s\n" % self._region + \
|
||||
"project_name = service\n" + \
|
||||
"username = neutron\n" + \
|
||||
"password = %s\n" % self._password + \
|
||||
"service_metadata_proxy = True\n" + \
|
||||
"metadata_proxy_shared_secret = %s\n" % metadata_password
|
||||
util.write_config(configfile, config)
|
||||
if CONF['CONFIG_HTTP_SERVICE'] == 'nginx':
|
||||
nova_api_services = ['uwsgi@nova-api.socket',
|
||||
'uwsgi@nova-metadata.socket']
|
||||
elif CONF['CONFIG_HTTP_SERVICE'] == 'apache2':
|
||||
nova_api_services = ['httpd']
|
||||
else:
|
||||
nova_api_services = ['nova-api']
|
||||
self.start_server(nova_api_services)
|
||||
|
||||
def add_service_plugin(self, plugin):
|
||||
plugins = util.get_option('/etc/neutron/neutron.conf',
|
||||
'DEFAULT', 'service_plugins').split(',')
|
||||
if plugin not in plugins:
|
||||
plugins.append(plugin)
|
||||
config = ('[DEFAULT]\n'
|
||||
"service_plugins = %s\n" % ','.join(plugins))
|
||||
util.write_config("/etc/neutron/neutron.conf", config)
|
||||
|
||||
def config_lbaas(self):
|
||||
self.add_service_plugin('lbaas')
|
||||
config = ("[DEFAULT]\n"
|
||||
"interface_driver = "
|
||||
"neutron.agent.linux.interface.BridgeInterfaceDriver\n")
|
||||
util.write_config("/etc/neutron/lbaas_agent.ini", config)
|
||||
self._services += ['neutron-lbaas-agent']
|
||||
|
||||
def config_vpnaas(self):
|
||||
self.add_service_plugin('vpnaas')
|
||||
driver = ("neutron_vpnaas.services.vpn.device_drivers.libreswan_ipsec"
|
||||
".LibreSwanDriver")
|
||||
config = "[vpnagent]\n" + \
|
||||
"vpn_device_driver = %s\n" % driver
|
||||
util.write_config("/etc/neutron/vpnaas_agent.ini", config)
|
||||
self._services += ['ipsec', 'neutron-vpn-agent']
|
||||
|
||||
def create_network(self, name, public=None):
|
||||
if public:
|
||||
cidr = IPv4Network(CONF['CONFIG_NOVA_NETWORK_FLOATRANGE'])
|
||||
else:
|
||||
cidr = IPv4Network(CONF['CONFIG_NOVA_NETWORK_FIXEDRANGE'])
|
||||
cidr_e = cidr.exploded
|
||||
cidr_gw = (cidr.network_address + 1).exploded
|
||||
cidr_start = (cidr.network_address + 2).exploded
|
||||
cidr_end = (cidr.broadcast_address - 1).exploded
|
||||
try:
|
||||
util.run_command("neutron net-show %s" % name,
|
||||
environ=self._env)
|
||||
except:
|
||||
cmd = "neutron net-create %s" % name
|
||||
if public:
|
||||
cmd += (" --provider:physical_network public"
|
||||
" --shared --provider:network_type flat")
|
||||
util.run_command(cmd, environ=self._env)
|
||||
cmd = ("neutron subnet-create %s %s --name %s"
|
||||
" --gateway %s" % (name, cidr_e, name, cidr_gw))
|
||||
if public:
|
||||
cmd += (" --allocation-pool start=%s,end=%s"
|
||||
% (cidr_start, cidr_end))
|
||||
util.run_command(cmd, environ=self._env)
|
||||
if public:
|
||||
util.run_command("neutron net-update %s --router:external"
|
||||
% name, environ=self._env)
|
||||
|
||||
def create_router(self, router, gw, interfaces):
|
||||
try:
|
||||
util.run_command("neutron router-show %s" % router,
|
||||
environ=self._env)
|
||||
except:
|
||||
util.run_command("neutron router-create %s" % router,
|
||||
environ=self._env)
|
||||
util.run_command("neutron router-gateway-set %s %s"
|
||||
% (router, gw), environ=self._env)
|
||||
for i in interfaces:
|
||||
util.run_command("neutron router-interface-add %s %s"
|
||||
% (router, i), environ=self._env)
|
||||
|
||||
def ceilometer_enable(self, configfile):
|
||||
self.config_rabbitmq(configfile)
|
||||
config = ("[DEFAULT]\n"
|
||||
"notification_driver = messagingv2\n")
|
||||
util.write_config(configfile, config)
|
||||
@@ -0,0 +1,95 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Obed Muñoz <obed.n.munoz@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 modules.openstack import OpenStackService
|
||||
from modules.ceilometer import Ceilometer
|
||||
from modules.conf import CONF
|
||||
from common import util
|
||||
from common.util import LOG
|
||||
from common.singleton import Singleton
|
||||
|
||||
|
||||
@Singleton
|
||||
class Nova(OpenStackService):
|
||||
_name = "nova"
|
||||
_bundle = "openstack-compute-controller"
|
||||
_services = ["nova-cert", "nova-consoleauth", "nova-scheduler",
|
||||
"nova-conductor", "nova-novncproxy"]
|
||||
if CONF['CONFIG_HTTP_SERVICE'] == 'nginx':
|
||||
_services.extend(["nginx", "uwsgi@nova-api.socket",
|
||||
"uwsgi@nova-metadata.socket"])
|
||||
elif CONF['CONFIG_HTTP_SERVICE'] == 'apache2':
|
||||
_services.append("httpd")
|
||||
else:
|
||||
_services.append("nova-api")
|
||||
_type = "compute"
|
||||
_description = "OpenStack Compute"
|
||||
_password = CONF['CONFIG_NOVA_KS_PW']
|
||||
_public_url = ("http://{0}:8774/v2/%\(tenant_id\)s"
|
||||
.format(CONF['CONFIG_CONTROLLER_HOST']))
|
||||
|
||||
def install_compute(self):
|
||||
self.install("openstack-compute")
|
||||
|
||||
def sync_database(self):
|
||||
LOG.debug("syncing database")
|
||||
util.run_command("su -s /bin/sh -c \"nova-manage db sync\" nova")
|
||||
|
||||
def create_network(self):
|
||||
LOG.debug("Creating network")
|
||||
command = ("nova-manage network create --bridge=br100"
|
||||
"--label=demo-net --fixed_range_v4=%s"
|
||||
% CONF['CONFIG_NOVA_NETWORK_FIXEDRANGE'])
|
||||
try:
|
||||
util.run_command("nova network-show demo-net", environ=self._env)
|
||||
except:
|
||||
command = ("nova-manage network create --bridge=br100 "
|
||||
"--label=demo-net --fixed_range_v4=%s"
|
||||
% CONF['CONFIG_NOVA_NETWORK_FIXEDRANGE'])
|
||||
if util.str2bool(CONF['CONFIG_NOVA_NETWORK_MULTIHOST']):
|
||||
command += " --multi_host=T"
|
||||
util.run_command(command, environ=self._env)
|
||||
|
||||
def create_floating_ips(self):
|
||||
LOG.debug("Creating floating ips")
|
||||
try:
|
||||
util.run_command("nova floating-ip-pool-list | grep nova")
|
||||
except:
|
||||
cmd = ("nova-manage floating create --pool nova "
|
||||
"--ip_range=%s" % CONF['CONFIG_NOVA_NETWORK_FLOATRANGE'])
|
||||
util.run_command(cmd, environ=self._env)
|
||||
|
||||
def ceilometer_enable(self, configfile):
|
||||
ceilometer = Ceilometer.get()
|
||||
ceilometer_cfg = "/etc/ceilometer/ceilometer.conf"
|
||||
|
||||
ceilometer.install()
|
||||
ceilometer.config_rabbitmq(ceilometer_cfg)
|
||||
ceilometer.config_auth(ceilometer_cfg)
|
||||
ceilometer.config_service_credentials(ceilometer_cfg)
|
||||
|
||||
config = ("[DEFAULT]\n"
|
||||
"instance_usage_audit = True\n"
|
||||
"instance_usage_audit_period = hour\n"
|
||||
"notify_on_state_change = vm_and_task_state\n"
|
||||
"notification_driver = messagingv2\n")
|
||||
util.write_config(configfile, config)
|
||||
self.start_server(['ceilometer-agent-compute.service'])
|
||||
@@ -0,0 +1,195 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Obed Muñoz <obed.n.munoz@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 socket
|
||||
|
||||
from common import util
|
||||
from common.swupd import Client as swupd_client
|
||||
from common.util import LOG
|
||||
from modules.conf import CONF
|
||||
from modules.conf import ENV
|
||||
|
||||
|
||||
class OpenStackService:
|
||||
_env = ""
|
||||
_internal_url = ""
|
||||
_admin_url = ""
|
||||
_region = ""
|
||||
_user = ""
|
||||
_controller = socket.gethostbyaddr(CONF["CONFIG_CONTROLLER_HOST"])[0]
|
||||
_password = ""
|
||||
|
||||
def __init__(self):
|
||||
if not self._env:
|
||||
self._env = ENV
|
||||
if not self._user:
|
||||
self._user = self._name
|
||||
if not self._password:
|
||||
self._password = CONF['CONFIG_%s_KS_PW' % self._name.upper()]
|
||||
if not self._internal_url:
|
||||
self._internal_url = self._public_url
|
||||
if not self._admin_url:
|
||||
self._admin_url = self._public_url
|
||||
if not self._region:
|
||||
self._region = CONF['CONFIG_KEYSTONE_REGION']
|
||||
|
||||
def install(self, bundle=None):
|
||||
bundle = bundle or self._bundle
|
||||
swupd_client.install(bundle)
|
||||
|
||||
def start_server(self, services=None):
|
||||
services = services or self._services
|
||||
LOG.debug("Starting services")
|
||||
util.run_command("systemctl enable %s" % " ".join(services))
|
||||
for service in services:
|
||||
if service.endswith(".socket"):
|
||||
util.run_command("systemctl stop %s" %
|
||||
service.replace(".socket", ".service"))
|
||||
util.run_command("systemctl restart %s" % service)
|
||||
|
||||
def create_service(self, name=None, description=None, type=None):
|
||||
name = name or self._name
|
||||
description = description or self._description
|
||||
type = type or self._type
|
||||
LOG.debug("setting up %s service" % name)
|
||||
try:
|
||||
""" test if service already exists """
|
||||
util.run_command("openstack service show %s" % name,
|
||||
environ=self._env)
|
||||
except:
|
||||
util.run_command("openstack service create %s"
|
||||
" --name %s --description \"%s\""
|
||||
% (type, name, description),
|
||||
environ=self._env)
|
||||
|
||||
def create_endpoint(self, publicurl=None,
|
||||
internalurl=None,
|
||||
adminurl=None,
|
||||
region=None,
|
||||
type=None):
|
||||
publicurl = publicurl or self._public_url
|
||||
internalurl = internalurl or self._internal_url
|
||||
adminurl = adminurl or self._admin_url
|
||||
region = region or self._region
|
||||
type = type or self._type
|
||||
|
||||
LOG.debug("creating endpoint")
|
||||
""" test if endpoint already exists """
|
||||
out, err = util.run_command("openstack endpoint list | grep %s"
|
||||
% self._name, environ=self._env)
|
||||
if not out:
|
||||
cmd = ("openstack endpoint create --region {0} {1}"
|
||||
.format(region, type))
|
||||
util.run_command(cmd + " public {0}".format(publicurl),
|
||||
environ=self._env)
|
||||
util.run_command(cmd + " internal {0}".format(internalurl),
|
||||
environ=self._env)
|
||||
util.run_command(cmd + " admin {0}".format(adminurl),
|
||||
environ=self._env)
|
||||
|
||||
def create_role(self, role):
|
||||
LOG.debug("setting up %s role" % role)
|
||||
try:
|
||||
util.run_command("openstack role show %s" % role,
|
||||
environ=self._env)
|
||||
except:
|
||||
util.run_command("openstack role create %s" % role,
|
||||
environ=self._env)
|
||||
|
||||
def add_role(self, user, role, project="service", domain="default"):
|
||||
# openstack role add: error: argument --project: not allowed with
|
||||
# argument --domain
|
||||
cmd = "openstack role add --user {0} {1}".format(user, role)
|
||||
if domain != "default":
|
||||
cmd += " --domain %s" % domain
|
||||
else:
|
||||
cmd += " --project %s" % project
|
||||
util.run_command(cmd, environ=self._env)
|
||||
|
||||
def create_user(self, user=None, password=None, domain="default",
|
||||
project="service", role="admin"):
|
||||
user = user or self._user
|
||||
password = password or self._password
|
||||
LOG.debug("setting up %s user" % user)
|
||||
try:
|
||||
""" test if user already exists """
|
||||
util.run_command("openstack user show %s" % user,
|
||||
environ=self._env)
|
||||
except:
|
||||
util.run_command("openstack user create --domain {0}"
|
||||
" --password={1}"
|
||||
" --email {2}@example.com {2}"
|
||||
.format(domain, password, user),
|
||||
environ=self._env, debug=False)
|
||||
self.add_role(user, role, project, domain)
|
||||
|
||||
def create_domain(self, domain, description):
|
||||
LOG.debug("setting up %s domain" % domain)
|
||||
try:
|
||||
""" test if domain already exists """
|
||||
util.run_command("openstack domain show %s" % domain,
|
||||
environ=self._env)
|
||||
except:
|
||||
util.run_command("openstack domain create --description \"%s\" %s"
|
||||
% (description, domain),
|
||||
environ=self._env, debug=False)
|
||||
|
||||
def config_debug(self, configfile):
|
||||
if util.str2bool(CONF['CONFIG_DEBUG_MODE']):
|
||||
config = "[DEFAULT]\n" + \
|
||||
"debug=True\n" + \
|
||||
"verbose=True\n"
|
||||
util.write_config(configfile, config)
|
||||
|
||||
def config_database(self, configfile):
|
||||
dbpass = CONF['CONFIG_%s_DB_PW' % self._name.upper()]
|
||||
dbhost = socket.gethostbyaddr(CONF['CONFIG_MARIADB_HOST'])[0]
|
||||
config = ("[database]\n"
|
||||
"connection=mysql://{0}:{1}@{2}/{0}"
|
||||
.format(self._name, dbpass, dbhost))
|
||||
util.write_config(configfile, config)
|
||||
|
||||
def config_rabbitmq(self, configfile):
|
||||
rabbit_host = socket.gethostbyaddr(CONF['CONFIG_AMQP_HOST'])[0]
|
||||
rabbit_password = CONF['CONFIG_AMQP_AUTH_PASSWORD']
|
||||
rabbit_user = CONF['CONFIG_AMQP_AUTH_USER']
|
||||
config = \
|
||||
"[DEFAULT]\n" + \
|
||||
"rpc_backend=rabbit\n" + \
|
||||
"[oslo_messaging_rabbit]\n" + \
|
||||
"rabbit_host=%s\n" % rabbit_host + \
|
||||
"rabbit_userid=%s\n" % rabbit_user + \
|
||||
"rabbit_password=%s\n" % rabbit_password + \
|
||||
"send_single_reply=True"
|
||||
util.write_config(configfile, config)
|
||||
|
||||
def config_auth(self, configfile, section='keystone_authtoken'):
|
||||
config = ("[{0}]\n"
|
||||
"auth_uri=http://{1}:5000\n"
|
||||
"auth_url=http://{1}:35357\n"
|
||||
"auth_plugin=password\n"
|
||||
"project_domain_id=default\n"
|
||||
"user_domain_id=default\n"
|
||||
"project_name=service\n"
|
||||
"username={2}\n"
|
||||
"password={3}"
|
||||
.format(section, self._controller, self._name,
|
||||
self._password))
|
||||
util.write_config(configfile, config)
|
||||
@@ -0,0 +1,71 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 common import util
|
||||
from common.singleton import Singleton
|
||||
from common.swupd import Client as swupd_client
|
||||
from common.util import LOG
|
||||
|
||||
|
||||
@Singleton
|
||||
class Rabbitmq:
|
||||
def __init__(self):
|
||||
hostname, stderr = util.run_command("hostname")
|
||||
util.write_in_file_ine("/etc/hosts", "127.0.0.1 {0}"
|
||||
.format(str(hostname.decode("utf-8")[:-1])))
|
||||
|
||||
def user_exists(self, user):
|
||||
stdout = None
|
||||
stderr = None
|
||||
try:
|
||||
stdout, stderr = util.run_command("rabbitmqctl list_users"
|
||||
" | grep {0}".format(user))
|
||||
except:
|
||||
pass
|
||||
|
||||
if not stdout:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def install(self):
|
||||
swupd_client.install("message-broker-rabbitmq")
|
||||
|
||||
def start_server(self):
|
||||
LOG.debug("starting services")
|
||||
util.run_command("systemctl enable rabbitmq-server")
|
||||
util.run_command("systemctl restart rabbitmq-server")
|
||||
|
||||
def add_user(self, auth_user, auth_pw):
|
||||
""" todo: what we do with guest """
|
||||
LOG.debug("adding user")
|
||||
if not self.user_exists(auth_user):
|
||||
util.run_command("rabbitmqctl add_user {0} {1}"
|
||||
.format(auth_user, auth_pw), debug=False)
|
||||
|
||||
def delete_user(self, user):
|
||||
LOG.debug("deleting user")
|
||||
util.run_command("rabbitmqctl delete_user {1}"
|
||||
.format(user))
|
||||
|
||||
def set_permissions(self, auth_user, permissions):
|
||||
LOG.debug("setting permissions")
|
||||
util.run_command("rabbitmqctl set_permissions {0} {1}"
|
||||
.format(auth_user, permissions))
|
||||
@@ -0,0 +1,202 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 os
|
||||
import shutil
|
||||
|
||||
from common import util
|
||||
from modules.openstack import OpenStackService
|
||||
from modules.conf import CONF
|
||||
from common.singleton import Singleton
|
||||
|
||||
|
||||
@Singleton
|
||||
class Swift(OpenStackService):
|
||||
_name = "swift"
|
||||
_bundle = "openstack-object-storage"
|
||||
_services = ["swift-proxy", "memcached"]
|
||||
_type = "object-store"
|
||||
_description = "OpenStack Object Storage"
|
||||
_public_url = ("http://{0}:8080/v1/AUTH_%\(tenant_id\)s"
|
||||
.format(CONF['CONFIG_CONTROLLER_HOST']))
|
||||
_admin_url = "http://{0}:8080/v1".format(CONF['CONFIG_CONTROLLER_HOST'])
|
||||
|
||||
_devices = []
|
||||
|
||||
def ceilometer_enable(self, configfile):
|
||||
pass
|
||||
|
||||
def config_auth(self, configfile):
|
||||
confdir = os.path.dirname(configfile)
|
||||
if not os.path.isdir(confdir):
|
||||
os.makedirs(confdir)
|
||||
shutil.copy('/usr/share/defaults/swift/proxy-server.conf', confdir)
|
||||
OpenStackService.config_auth(self, configfile,
|
||||
section='filter:authtoken')
|
||||
config = ("[pipeline:main]\n"
|
||||
"pipeline = catch_errors gatekeeper healthcheck "
|
||||
"proxy-logging cache container_sync bulk ratelimit "
|
||||
"authtoken keystoneauth container-quotas account-quotas "
|
||||
"slo dlo versioned_writes proxy-logging proxy-server\n"
|
||||
"[filter:authtoken]\n"
|
||||
"paste.filter_factory = "
|
||||
"keystonemiddleware.auth_token:filter_factory\n"
|
||||
"delay_auth_decision = True\n"
|
||||
"[app:proxy-server]\n"
|
||||
"use = egg:swift#proxy\n"
|
||||
"account_autocreate = True\n"
|
||||
"[filter:keystoneauth]\n"
|
||||
"use = egg:swift#keystoneauth\n"
|
||||
"operator_roles = admin,user\n")
|
||||
util.write_config(configfile, config)
|
||||
|
||||
def config_memcache(self, configfile):
|
||||
config = ("[filter:cache]\n"
|
||||
"use = egg:swift#memcache\n"
|
||||
"memcache_servers = 127.0.0.1:11211")
|
||||
util.write_config(configfile, config)
|
||||
|
||||
def config_hash(self, configfile):
|
||||
suffix = CONF['CONFIG_SWIFT_HASH']
|
||||
config = ("[swift-hash]\n"
|
||||
"swift_hash_path_suffix = {0}").format(suffix)
|
||||
util.write_config(configfile, config)
|
||||
|
||||
def parse_devices(self):
|
||||
|
||||
def create_loopback(name, size):
|
||||
# Remove the file if exists
|
||||
if os.path.isfile(name):
|
||||
os.remove(name)
|
||||
# Create an empty file
|
||||
with open(name, 'wb') as f:
|
||||
f.seek(1024 * 1024 * 1024 * size - 1)
|
||||
f.write(b"\0")
|
||||
util.run_command("mkfs.xfs %s" % name)
|
||||
|
||||
devs = CONF['CONFIG_SWIFT_STORAGES']
|
||||
if devs:
|
||||
devs = devs.split(',')
|
||||
devs = [x.strip() for x in devs]
|
||||
device_number = 0
|
||||
num_zones = int(CONF["CONFIG_SWIFT_STORAGE_ZONES"])
|
||||
for dev in devs:
|
||||
device_number += 1
|
||||
zone = (device_number % num_zones) + 1
|
||||
self._devices.append({'device': dev, 'zone': zone,
|
||||
'name': 'device%s' % device_number})
|
||||
else:
|
||||
# Setup loopdevice
|
||||
filename = '/srv/loopback-device'
|
||||
filesize = int(CONF['CONFIG_SWIFT_STORAGE_SIZE'])
|
||||
create_loopback(filename, filesize)
|
||||
self._devices.append({'device': filename, 'zone': 1,
|
||||
'name': 'loopback'})
|
||||
|
||||
def prepare_devices(self):
|
||||
# Avoid adding duplicate entries in fstab
|
||||
mounted_devices = []
|
||||
if os.path.isfile('/etc/fstab'):
|
||||
with open('/etc/fstab', 'r') as f:
|
||||
for l in f:
|
||||
mounted_devices.append(l.split()[0].strip())
|
||||
|
||||
# Add each device to fstab if not already added
|
||||
fstab = ""
|
||||
for device in self._devices:
|
||||
# Format the device with xfs filesystem
|
||||
util.ensure_directory('/srv/node/%s' % device['name'])
|
||||
|
||||
# Ensure the device is mounted
|
||||
if device['device'] not in mounted_devices:
|
||||
fstab += ("{0} /srv/node/{1} xfs noatime,nodiratime,nobarrier,"
|
||||
"logbufs=8 0 2\n").format(device['device'],
|
||||
device['name'])
|
||||
with open('/etc/fstab', 'a') as f:
|
||||
f.write(fstab)
|
||||
|
||||
util.run_command('mount -a')
|
||||
# Change ownership of /srv to swift
|
||||
util.run_command("chown -R swift:swift /srv")
|
||||
|
||||
def create_rings(self):
|
||||
replicas = CONF['CONFIG_SWIFT_STORAGE_REPLICAS']
|
||||
ip = util.get_ip()
|
||||
for ringtype, port in [('object', '6000'),
|
||||
('container', '6001'),
|
||||
('account', 6002)]:
|
||||
cmd = ("swift-ring-builder {0}.builder create 10 {1} 1"
|
||||
.format(ringtype, replicas))
|
||||
util.run_command(cmd)
|
||||
for device in self._devices:
|
||||
cmd = ("swift-ring-builder %s.builder add --region 1 "
|
||||
"--zone %s --ip %s --port %s --device %s --weight 100"
|
||||
% (ringtype, device['zone'], ip, port, device['name']))
|
||||
util.run_command(cmd)
|
||||
cmd = "swift-ring-builder {0}.builder rebalance".format(ringtype)
|
||||
util.run_command(cmd)
|
||||
if os.path.isfile("/etc/swift/%s.ring.gz" % ringtype):
|
||||
os.remove("/etc/swift/%s.ring.gz" % ringtype)
|
||||
shutil.move("%s.ring.gz" % ringtype, "/etc/swift")
|
||||
|
||||
def config_storage_services(self):
|
||||
confdir = '/etc/swift/'
|
||||
shutil.copy('/usr/share/defaults/swift/account-server.conf', confdir)
|
||||
shutil.copy('/usr/share/defaults/swift/container-server.conf', confdir)
|
||||
shutil.copy('/usr/share/defaults/swift/object-server.conf', confdir)
|
||||
shutil.copy('/usr/share/defaults/swift/container-reconciler.conf',
|
||||
confdir)
|
||||
shutil.copy('/usr/share/defaults/swift/object-expirer.conf', confdir)
|
||||
for type in ['account', 'container', 'object']:
|
||||
conf = ("[DEFAULT]\n"
|
||||
"bind_ip = 0.0.0.0\n"
|
||||
"devices = /srv/node\n"
|
||||
"[pipeline:main]\n"
|
||||
"pipeline = healthcheck recon {0}-server\n"
|
||||
"[filter:recon]\n"
|
||||
"recon_cache_path = /var/cache/swift\n").format(type)
|
||||
util.write_config('/etc/swift/%s-server.conf' % type, conf)
|
||||
|
||||
def config_rsync(self):
|
||||
config = """
|
||||
uid = swift
|
||||
gid = swift
|
||||
log file = /var/log/rsyncd.log
|
||||
pid file = /var/run/rsyncd.pid
|
||||
address = {0}
|
||||
|
||||
[account]
|
||||
max connections = 2
|
||||
path = /srv/node/
|
||||
read only = false
|
||||
lock file = /var/lock/account.lock
|
||||
|
||||
[container]
|
||||
max connections = 2
|
||||
path = /srv/node/
|
||||
read only = false
|
||||
lock file = /var/lock/container.lock
|
||||
|
||||
[object]
|
||||
max connections = 2
|
||||
path = /srv/node/
|
||||
read only = false
|
||||
lock file = /var/lock/object.lock
|
||||
""".format(util.get_ip())
|
||||
with open('/etc/rsyncd.conf', 'w') as f:
|
||||
f.write(config)
|
||||
@@ -0,0 +1,59 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 clearstack import utils
|
||||
from clearstack import validators
|
||||
from clearstack.argument import Argument
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
def init_config():
|
||||
conf = {
|
||||
"AMQP": [
|
||||
Argument("amqp-auth-user",
|
||||
"User for amqp authentication",
|
||||
"CONFIG_AMQP_AUTH_USER",
|
||||
"amqp_user",
|
||||
validators=[validators.not_empty]),
|
||||
Argument("amqp-auth-pw",
|
||||
"Password for amqp user authentication",
|
||||
"CONFIG_AMQP_AUTH_PASSWORD",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("amqp-host",
|
||||
"The IP address or hostname of the server on which"
|
||||
" to install the AMQP service",
|
||||
"CONFIG_AMQP_HOST",
|
||||
util.get_ip(),
|
||||
validators=[validators.ip_or_hostname])
|
||||
]
|
||||
}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
def init_sequences():
|
||||
Controller.get().add_sequence("Setting up rabbit", setup_rabbit)
|
||||
|
||||
|
||||
def setup_rabbit():
|
||||
conf = Controller.get().CONF
|
||||
recipe = utils.get_template("rabbitmq")
|
||||
return utils.run_recipe("rabbitmq.py", recipe, [conf["CONFIG_AMQP_HOST"]])
|
||||
@@ -0,0 +1,58 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 clearstack import utils
|
||||
from clearstack import validators
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.argument import Argument
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
def init_config():
|
||||
conf = {
|
||||
"CEILOMETER": [
|
||||
Argument("ceilometer-db-pw",
|
||||
"Password for ceilometer to access DB",
|
||||
"CONFIG_CEILOMETER_DB_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("ceilometer-ks-pw",
|
||||
"Password to use for Ceilometer to"
|
||||
" authenticate with Keystone",
|
||||
"CONFIG_CEILOMETER_KS_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty])
|
||||
]
|
||||
}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
def init_sequences():
|
||||
controller = Controller.get()
|
||||
conf = controller.CONF
|
||||
if util.str2bool(conf['CONFIG_CEILOMETER_INSTALL']):
|
||||
controller.add_sequence("Setting up ceilometer", setup_ceilometer)
|
||||
|
||||
|
||||
def setup_ceilometer():
|
||||
conf = Controller.get().CONF
|
||||
recipe = utils.get_template("ceilometer")
|
||||
return utils.run_recipe("ceilometer.py", recipe,
|
||||
[conf["CONFIG_CONTROLLER_HOST"]])
|
||||
@@ -0,0 +1,59 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 clearstack import utils
|
||||
from clearstack import validators
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.argument import Argument
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
def init_config():
|
||||
conf = {
|
||||
"GLANCE": [
|
||||
Argument("glance-db-pw",
|
||||
"Password for glance to access DB",
|
||||
"CONFIG_GLANCE_DB_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("glance-ks-pw",
|
||||
"Password to use for Glance to"
|
||||
" authenticate with Keystone",
|
||||
"CONFIG_GLANCE_KS_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty])
|
||||
]
|
||||
}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
def init_sequences():
|
||||
controller = Controller.get()
|
||||
conf = controller.CONF
|
||||
if util.str2bool(conf['CONFIG_GLANCE_INSTALL']):
|
||||
controller.add_sequence("Setting up glance", setup_glance)
|
||||
|
||||
|
||||
def setup_glance():
|
||||
conf = Controller.get().CONF
|
||||
recipe = utils.get_template("glance")
|
||||
return utils.run_recipe("glance.py", recipe,
|
||||
[conf["CONFIG_CONTROLLER_HOST"]])
|
||||
@@ -0,0 +1,75 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 clearstack import utils
|
||||
from clearstack import validators
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.argument import Argument
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
def init_config():
|
||||
conf = {
|
||||
"HEAT": [
|
||||
Argument("heat-db-pw",
|
||||
"Password for heat to access DB",
|
||||
"CONFIG_HEAT_DB_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("heat-ks-pw",
|
||||
"Password to use for Heat to"
|
||||
" authenticate with Keystone",
|
||||
"CONFIG_HEAT_KS_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("heat-domain",
|
||||
"Name of the Identity domain for Orchestration.",
|
||||
"CONFIG_HEAT_DOMAIN",
|
||||
"heat",
|
||||
validators=[validators.not_empty]),
|
||||
Argument("heat-domain-admin",
|
||||
"Name of the Identity domain administrative user for "
|
||||
"Orchestration.",
|
||||
"CONFIG_HEAT_DOMAIN_ADMIN",
|
||||
"heat_domain_admin",
|
||||
validators=[validators.not_empty]),
|
||||
Argument("heat-domain-password",
|
||||
"Password for the Identity domain administrative user "
|
||||
"for Orchestration",
|
||||
"CONFIG_HEAT_DOMAIN_PASSWORD",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty])
|
||||
]
|
||||
}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
def init_sequences():
|
||||
controller = Controller.get()
|
||||
conf = controller.CONF
|
||||
if util.str2bool(conf['CONFIG_HEAT_INSTALL']):
|
||||
controller.add_sequence("Setting up heat", setup_heat)
|
||||
|
||||
|
||||
def setup_heat():
|
||||
conf = Controller.get().CONF
|
||||
recipe = utils.get_template("heat")
|
||||
return utils.run_recipe("heat.py", recipe,
|
||||
[conf["CONFIG_CONTROLLER_HOST"]])
|
||||
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 clearstack import utils
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
def init_config():
|
||||
conf = {}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
def init_sequences():
|
||||
controller = Controller.get()
|
||||
conf = controller.CONF
|
||||
if util.str2bool(conf['CONFIG_HORIZON_INSTALL']):
|
||||
controller.add_sequence("Setting up horizon", setup_horizon)
|
||||
|
||||
|
||||
def setup_horizon():
|
||||
template = "horizon"
|
||||
conf = Controller.get().CONF
|
||||
recipe = utils.get_template(template)
|
||||
return utils.run_recipe("{0}.py".format(template), recipe,
|
||||
[conf["CONFIG_CONTROLLER_HOST"]])
|
||||
@@ -0,0 +1,71 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 uuid
|
||||
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.argument import Argument
|
||||
from clearstack import utils
|
||||
from clearstack import validators
|
||||
|
||||
|
||||
def init_config():
|
||||
conf = {
|
||||
"KEYSTONE": [
|
||||
Argument("keystone-db-pw",
|
||||
"Password for keystone to access DB",
|
||||
"CONFIG_KEYSTONE_DB_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("keystone-admin-token",
|
||||
"The token to use for the Keystone service api",
|
||||
"CONFIG_KEYSTONE_ADMIN_TOKEN",
|
||||
uuid.uuid4().hex,
|
||||
validators=[validators.not_empty]),
|
||||
Argument("keystone-admin-pw",
|
||||
"The password to use for the Keystone admin user",
|
||||
"CONFIG_KEYSTONE_ADMIN_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("keystone-demo-pw",
|
||||
"The password to use for the Keystone demo user",
|
||||
"CONFIG_KEYSTONE_DEMO_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("keystone-region",
|
||||
"Region name",
|
||||
"CONFIG_KEYSTONE_REGION",
|
||||
"RegionOne",
|
||||
validators=[validators.not_empty])
|
||||
]
|
||||
}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
def init_sequences():
|
||||
Controller.get().add_sequence("Setting up keystone", setup_keystone)
|
||||
|
||||
|
||||
def setup_keystone():
|
||||
conf = Controller.get().CONF
|
||||
recipe = utils.get_template('keystone')
|
||||
return utils.run_recipe("keystone.py", recipe,
|
||||
[conf["CONFIG_CONTROLLER_HOST"]])
|
||||
@@ -0,0 +1,62 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 clearstack.controller import Controller
|
||||
from clearstack.argument import Argument
|
||||
from clearstack import utils
|
||||
from clearstack import validators
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
def init_config():
|
||||
conf = {
|
||||
"MARIADB": [
|
||||
Argument("mariadb-host",
|
||||
"The IP address or hostname of the MariaDB server",
|
||||
"CONFIG_MARIADB_HOST",
|
||||
util.get_ip(),
|
||||
validators=[validators.ip_or_hostname]),
|
||||
Argument("mariadb-user",
|
||||
"User for mariadb authentication",
|
||||
"CONFIG_MARIADB_USER",
|
||||
"root",
|
||||
validators=[validators.not_empty]),
|
||||
Argument("mariadb-pw",
|
||||
"Password for mariadb user",
|
||||
"CONFIG_MARIADB_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty])
|
||||
]
|
||||
}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
def init_sequences():
|
||||
controller = Controller.get()
|
||||
controller.add_sequence("Setting up mariadb",
|
||||
setup_mariadb, args=['mariadb'])
|
||||
|
||||
|
||||
def setup_mariadb(template):
|
||||
conf = Controller.get().CONF
|
||||
recipe = utils.get_template(template)
|
||||
return utils.run_recipe("{0}.py".format(template), recipe,
|
||||
[conf["CONFIG_MARIADB_HOST"]])
|
||||
@@ -0,0 +1,52 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 clearstack.controller import Controller
|
||||
from clearstack.argument import Argument
|
||||
from clearstack import utils
|
||||
from clearstack import validators
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
def init_config():
|
||||
conf = {
|
||||
"MONGODB": [
|
||||
Argument("mongodb-host",
|
||||
"The IP address or hostname of the MongoDB server",
|
||||
"CONFIG_MONGODB_HOST",
|
||||
util.get_ip(),
|
||||
validators=[validators.ip_or_hostname])
|
||||
]
|
||||
}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
def init_sequences():
|
||||
controller = Controller.get()
|
||||
conf = controller.CONF
|
||||
if util.str2bool(conf['CONFIG_CEILOMETER_INSTALL']):
|
||||
controller.add_sequence("Setting up MongoDB", setup_mongodb)
|
||||
|
||||
|
||||
def setup_mongodb():
|
||||
conf = Controller.get().CONF
|
||||
recipe = utils.get_template('mongodb')
|
||||
return utils.run_recipe("mongodb.py", recipe,
|
||||
[conf["CONFIG_MONGODB_HOST"]])
|
||||
@@ -0,0 +1,159 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 clearstack import utils
|
||||
from clearstack import validators
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.argument import Argument
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
def init_config():
|
||||
conf = {
|
||||
"NEUTRON": [
|
||||
Argument("neutron-ks-pw",
|
||||
"Password to use for OpenStack Networking (neutron) to"
|
||||
" authenticate with the Identity service.",
|
||||
"CONFIG_NEUTRON_KS_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("neutron-db-pw",
|
||||
"The password to use for OpenStack Networking to access "
|
||||
"the database.",
|
||||
"CONFIG_NEUTRON_DB_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
# Argument('neutron-l3-ext-bridge',
|
||||
# 'The name of the Open vSwitch bridge (or empty for '
|
||||
# 'linuxbridge) for the OpenStack Networking L3 agent to '
|
||||
# 'use for external traffic',
|
||||
# 'CONFIG_NEUTRON_L3_EXT_BRIDGE',
|
||||
# 'br-ex',
|
||||
# validators=[validators.not_empty]),
|
||||
Argument('neutron-metadata-pw',
|
||||
'Password for the OpenStack Networking metadata agent',
|
||||
'CONFIG_NEUTRON_METADATA_PW',
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument('neutron-lbaas-install',
|
||||
"Specify 'y' to install OpenStack Networking's "
|
||||
"Load-Balancing-as-a-Service (LBaaS)",
|
||||
"CONFIG_LBAAS_INSTALL",
|
||||
'n',
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n]),
|
||||
Argument('neutron-vpnass-install',
|
||||
"Specify 'y' to install OpenStack Networking's "
|
||||
"VPN-as-a-Service (VPNaaS)",
|
||||
"CONFIG_VPNAAS_INSTALL",
|
||||
'n',
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n])
|
||||
],
|
||||
# "NEUTRON_OVS_AGENT": [
|
||||
# Argument("neutron-ovs-bridge-mappings",
|
||||
# "Comma-separated list of bridge mappings for the "
|
||||
# "OpenStack Networking Open vSwitch plugin. Each tuple "
|
||||
# "in the list must be in he format "
|
||||
# " <physical_network>:<ovs_bridge>",
|
||||
# "CONFIG_NEUTRON_OVS_BRIDGE_MAPPINGS",
|
||||
# "external:br-ex"),
|
||||
# Argument("neutron-ovs-bridge-interfaces",
|
||||
# "Comma-separated list of colon-separated Open vSwitch"
|
||||
# " <bridge>:<interface> pairs.",
|
||||
# "CONFIG_NEUTRON_OVS_BRIDGE_IFACES",
|
||||
# "br-ex:%s" % util.get_net_interface())
|
||||
# ],
|
||||
"NEUTRON_LINUXBRIDGE_AGENT": [
|
||||
Argument("neutron-linuxbridge-physical-interface-mappings",
|
||||
"Colon separated linuxbridge <bridge>:<interface> pairs",
|
||||
"CONFIG_NEUTRON_LINUXBRIDGE_IFACES",
|
||||
"public:%s" % util.get_net_interface())
|
||||
],
|
||||
"NEUTRON_ML2_PLUGIN": [
|
||||
Argument("neutron-ml2-type-drivers",
|
||||
"Comma-separated list of network-type driver entry "
|
||||
"points to be loaded from the neutron.ml2.type_drivers "
|
||||
"namespace",
|
||||
"CONFIG_NEUTRON_ML2_TYPE_DRIVERS",
|
||||
"flat,vlan,vxlan",
|
||||
options=['local', 'flat', 'vlan', 'gre', 'vxlan'],
|
||||
validators=[validators.not_empty]),
|
||||
Argument("neutron-ml2-tenant-network-types",
|
||||
"Comma-separated, ordered list of network types to "
|
||||
"allocate as tenant networks",
|
||||
"CONFIG_NEUTRON_ML2_TENANT_NETWORK_TYPES",
|
||||
"vxlan",
|
||||
options=['local', 'vlan', 'gre', 'vxlan'],
|
||||
validators=[validators.not_empty]),
|
||||
Argument("neutron-ml2-mechanism-drivers",
|
||||
"Comma-separated, ordered list of network types to "
|
||||
"allocate as tenant networks",
|
||||
"CONFIG_NEUTRON_ML2_MECHANISM_DRIVERS",
|
||||
"linuxbridge,l2population",
|
||||
options=['openvswitch', 'linuxbridge'],
|
||||
validators=[validators.not_empty]),
|
||||
Argument("neutron-ml2-flat-networks",
|
||||
"Comma-separated list of physical_network names with "
|
||||
"wich flat networks can be created.",
|
||||
"CONFIG_NEUTRON_ML2_FLAT_NETWORKS",
|
||||
"public",
|
||||
validators=[validators.not_empty]),
|
||||
Argument("neutron-ml2-tunnel-id-ranges",
|
||||
"Comma-separated list of <tun_min>:<tun_max> tuples "
|
||||
"enumerating ranges of GRE tunnel IDs that are available "
|
||||
"for tenant-network allocation.",
|
||||
"CONFIG_NEUTRON_ML2_TUNNEL_ID_RANGES",
|
||||
"1:1000",
|
||||
validators=[validators.not_empty]),
|
||||
Argument("neutron-l2-agent",
|
||||
"Name of the L2 agent to be used with OpenStack "
|
||||
"Networking",
|
||||
"CONFIG_NEUTRON_L2_AGENT",
|
||||
"linuxbridge",
|
||||
options=['openvswitch', 'linuxbridge'],
|
||||
validators=[validators.not_empty])
|
||||
]
|
||||
}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
def init_sequences():
|
||||
controller = Controller.get()
|
||||
conf = controller.CONF
|
||||
if util.str2bool(conf['CONFIG_NEUTRON_INSTALL']):
|
||||
controller.add_sequence("Setting up neutron controller",
|
||||
setup_controller)
|
||||
controller.add_sequence("Setting up neutron on computes nodes",
|
||||
setup_compute_nodes)
|
||||
|
||||
|
||||
def setup_controller():
|
||||
conf = Controller.get().CONF
|
||||
recipe = utils.get_template('neutron')
|
||||
return utils.run_recipe("neutron.py", recipe,
|
||||
[conf["CONFIG_CONTROLLER_HOST"]])
|
||||
|
||||
|
||||
def setup_compute_nodes():
|
||||
conf = Controller.get().CONF
|
||||
recipe = utils.get_template('neutron_compute')
|
||||
return utils.run_recipe("neutron_compute.py", recipe,
|
||||
conf["CONFIG_COMPUTE_HOSTS"].split(','))
|
||||
@@ -0,0 +1,114 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 clearstack import utils
|
||||
from clearstack import validators
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.argument import Argument
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
def init_config():
|
||||
conf = {
|
||||
"NOVA": [
|
||||
Argument("nova-db-pw",
|
||||
"Password for nova to access DB",
|
||||
"CONFIG_NOVA_DB_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("nova-ks-pw",
|
||||
"Password to use for the Nova to"
|
||||
" authenticate with Keystone",
|
||||
"CONFIG_NOVA_KS_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty])
|
||||
],
|
||||
"NOVA_NETWORK": [
|
||||
Argument("nova-compute-privif",
|
||||
"Private interface for Flat DHCP on"
|
||||
" the Nova compute servers",
|
||||
"CONFIG_NOVA_COMPUTE_PRIVIF",
|
||||
util.get_net_interface(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("nova-network-manager",
|
||||
"Nova network manager",
|
||||
"CONFIG_NOVA_NETWORK_MANAGER",
|
||||
"nova.network.manager.FlatDHCPManager",
|
||||
validators=[validators.not_empty]),
|
||||
Argument("nova-network-pubif",
|
||||
"Public interface on the Nova network server",
|
||||
"CONFIG_NOVA_NETWORK_PUBIF",
|
||||
util.get_net_interface(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("nova-network-fixed-range",
|
||||
"IP Range for flat DHCP.",
|
||||
"CONFIG_NOVA_NETWORK_FIXEDRANGE",
|
||||
"192.168.32.0/22",
|
||||
validators=[validators.cidr]),
|
||||
Argument("nova-network-floating-range",
|
||||
"IP Range for floating IP addresses.",
|
||||
"CONFIG_NOVA_NETWORK_FLOATRANGE",
|
||||
"10.3.4.0/22",
|
||||
validators=[validators.cidr]),
|
||||
Argument("nova-network-auto-assign-floating-ip",
|
||||
"Specify 'y' to automatically assign a floating IP to "
|
||||
"new instances ['y', 'n']",
|
||||
"CONFIG_NOVA_NETWORK_AUTOASSIGNFLOATINGIP",
|
||||
"n",
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n]),
|
||||
Argument("nova-network-size",
|
||||
"Number of addresses in each private subnet",
|
||||
"CONFIG_NOVA_NETWORK_SIZE",
|
||||
"255",
|
||||
validators=[validators.digit]),
|
||||
Argument("nova-network-multihost",
|
||||
"Nova network multihost",
|
||||
"CONFIG_NOVA_NETWORK_MULTIHOST",
|
||||
"True",
|
||||
validators=[validators.true_or_false])
|
||||
]
|
||||
}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
def init_sequences():
|
||||
controller = Controller.get()
|
||||
conf = controller.CONF
|
||||
if util.str2bool(conf['CONFIG_NOVA_INSTALL']):
|
||||
controller.add_sequence("Setting up nova controller",
|
||||
setup_controller)
|
||||
controller.add_sequence("Setting up nova computes",
|
||||
setup_computes)
|
||||
|
||||
|
||||
def setup_controller():
|
||||
conf = Controller.get().CONF
|
||||
recipe = utils.get_template('nova')
|
||||
return utils.run_recipe("nova.py", recipe,
|
||||
[conf["CONFIG_CONTROLLER_HOST"]])
|
||||
|
||||
|
||||
def setup_computes():
|
||||
conf = Controller.get().CONF
|
||||
recipe = utils.get_template('nova_compute')
|
||||
return utils.run_recipe("nova_compute.py", recipe,
|
||||
conf["CONFIG_COMPUTE_HOSTS"].split(','))
|
||||
@@ -0,0 +1,191 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Obed Muñoz <obed.n.munoz@intel.com>
|
||||
#
|
||||
# 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 os
|
||||
|
||||
from clearstack.argument import Argument
|
||||
from clearstack.controller import Controller
|
||||
from clearstack import validators
|
||||
from clearstack import utils
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
def validate_ssh_key(ssh_key):
|
||||
hosts = utils.get_all_hosts()
|
||||
util.remove_localhost(hosts)
|
||||
if len(hosts) != 0:
|
||||
validators.file(ssh_key)
|
||||
|
||||
|
||||
def init_config():
|
||||
home = os.getenv('HOME')
|
||||
if home is None:
|
||||
home = "/root"
|
||||
conf = {
|
||||
"GENERAL": [
|
||||
Argument("debug-mode",
|
||||
"Set to 'y' if you want to run"
|
||||
" OpenStack services in debug mode",
|
||||
"CONFIG_DEBUG_MODE",
|
||||
"n",
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n]),
|
||||
Argument("ssh-private-key",
|
||||
"Path to the private SSH key file",
|
||||
"CONFIG_PRIVATE_SSH_KEY",
|
||||
"",
|
||||
validators=[validate_ssh_key]),
|
||||
Argument("controller-host",
|
||||
"IP address or hostname of the server on which "
|
||||
" to install OpenStack services specific to"
|
||||
" controller role such as API servers",
|
||||
"CONFIG_CONTROLLER_HOST",
|
||||
util.get_ip(),
|
||||
validators=[validators.ip_or_hostname]),
|
||||
Argument("clean-controller-host",
|
||||
"Set 'y' if you would like Clearstack to "
|
||||
"clean up controller host",
|
||||
"CONFIG_CLEAN_CONTROLLER_HOST",
|
||||
"y",
|
||||
validators=[validators.y_or_n]),
|
||||
Argument("compute-hosts",
|
||||
"List of IP addresses or hostnames of the server on which"
|
||||
" to install the Nova compute service",
|
||||
"CONFIG_COMPUTE_HOSTS",
|
||||
util.get_ip(),
|
||||
validators=[validators.ip_or_hostname]),
|
||||
Argument("clean-compute-hosts",
|
||||
"Set 'y' if you would like Clearstack to "
|
||||
"clean up compute hosts",
|
||||
"CONFIG_CLEAN_COMPUTE_HOSTS",
|
||||
"y",
|
||||
validators=[validators.y_or_n]),
|
||||
Argument("mariadb-install",
|
||||
"Set 'y' if you would like Clearstack to install MariaDB",
|
||||
"CONFIG_MARIADB_INSTALL",
|
||||
"y",
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n]),
|
||||
Argument("mongodb-install",
|
||||
"Set 'y' if you would like Clearstack to install MongoDB",
|
||||
"CONFIG_MONGODB_INSTALL",
|
||||
"y",
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n]),
|
||||
Argument("http-service",
|
||||
"Set 'apache2' or 'nginx' as HTTP Service for Horizon, "
|
||||
"Keystone and Nova API web services",
|
||||
"CONFIG_HTTP_SERVICE",
|
||||
"nginx",
|
||||
options=['nginx', 'apache2'],
|
||||
validators=[validators.not_empty]),
|
||||
Argument("glance-install ",
|
||||
"Set 'y' if you would like Clearstack to install"
|
||||
" Openstack image (glance)",
|
||||
"CONFIG_GLANCE_INSTALL",
|
||||
"y",
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n]),
|
||||
Argument("nova-install ",
|
||||
"Set 'y' if you would like Clearstack to install"
|
||||
" Openstack compute (nova)",
|
||||
"CONFIG_NOVA_INSTALL",
|
||||
"y",
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n]),
|
||||
Argument("horizon-install",
|
||||
"Set 'y' if you would like Clearstack to install"
|
||||
" OpenStack dashboard (horizon)",
|
||||
"CONFIG_HORIZON_INSTALL",
|
||||
"y",
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n]),
|
||||
Argument("neutron-install",
|
||||
"Set 'y' if you would like Clearstack to install"
|
||||
" OpenStack Networking (neutron)",
|
||||
"CONFIG_NEUTRON_INSTALL",
|
||||
"y",
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n]),
|
||||
Argument("ceilometer-install",
|
||||
"Set 'y' if you would like Clearstack to install"
|
||||
" OpenStack Telemetry (ceilometer)",
|
||||
"CONFIG_CEILOMETER_INSTALL",
|
||||
"y",
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n]),
|
||||
Argument("heat-install",
|
||||
"Set 'y' if you would like Clearstack to install"
|
||||
" OpenStack Orchestration (heat)",
|
||||
"CONFIG_HEAT_INSTALL",
|
||||
"n",
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n]),
|
||||
Argument("swift-install",
|
||||
"Set 'y' if you would like Clearstack to install"
|
||||
" OpenStack Object Storage (swift)",
|
||||
"CONFIG_SWIFT_INSTALL",
|
||||
"n",
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n])
|
||||
]
|
||||
}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
def init_sequences():
|
||||
Controller.get().add_sequence("Setting up controller host",
|
||||
setup_controller)
|
||||
Controller.get().add_sequence("Setting up compute hosts",
|
||||
setup_computes)
|
||||
|
||||
|
||||
def setup_controller():
|
||||
conf = Controller.get().CONF
|
||||
if util.str2bool(conf['CONFIG_CLEAN_CONTROLLER_HOST']):
|
||||
try:
|
||||
utils.run_recipe("{0}".format("controller_cleanup.sh"),
|
||||
utils.get_template("controller_cleanup.sh"),
|
||||
[conf["CONFIG_CONTROLLER_HOST"]])
|
||||
except:
|
||||
pass
|
||||
|
||||
template = "pre_controller.sh"
|
||||
recipe = utils.get_template(template)
|
||||
return utils.run_recipe("{0}".format(template), recipe,
|
||||
[conf["CONFIG_CONTROLLER_HOST"]])
|
||||
|
||||
|
||||
def setup_computes():
|
||||
conf = Controller.get().CONF
|
||||
if util.str2bool(conf['CONFIG_CLEAN_COMPUTE_HOSTS']):
|
||||
try:
|
||||
utils.run_recipe("{0}".format("compute_cleanup.sh"),
|
||||
utils.get_template("compute_cleanup.sh"),
|
||||
conf["CONFIG_COMPUTE_HOSTS"].split(','))
|
||||
except:
|
||||
pass
|
||||
|
||||
template = "pre_compute.sh"
|
||||
recipe = utils.get_template(template)
|
||||
return utils.run_recipe("{0}".format(template), recipe,
|
||||
conf["CONFIG_COMPUTE_HOSTS"].split(','))
|
||||
@@ -0,0 +1,86 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 clearstack import utils
|
||||
from clearstack import validators
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.argument import Argument
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
def init_config():
|
||||
conf = {
|
||||
"PROVISION_INIT": [
|
||||
Argument("provision-demo",
|
||||
"Specify 'y' to provision for demo usage and testing."
|
||||
" ['y', 'n']",
|
||||
"CONFIG_PROVISION_DEMO",
|
||||
"n",
|
||||
options=['y', 'n'],
|
||||
validators=[validators.y_or_n])
|
||||
],
|
||||
"PROVISION_DEMO": [
|
||||
Argument("provision-demo-floatrange",
|
||||
"CIDR network address for the floating IP subnet.",
|
||||
"CONFIG_PROVISION_DEMO_FLOATRANGE",
|
||||
"172.24.4.224/28",
|
||||
validators=[validators.cidr]),
|
||||
Argument("privision-image-format",
|
||||
'Format for the demo image (default "qcow2").',
|
||||
"CONFIG_PROVISION_IMAGE_FORMAT",
|
||||
"qcow2",
|
||||
validators=[validators.not_empty]),
|
||||
Argument("provision-image-name",
|
||||
'The name to be assigned to the demo image in Glance '
|
||||
'(default "cirros")',
|
||||
"CONFIG_PROVISION_IMAGE_NAME",
|
||||
"cirros",
|
||||
validators=[validators.not_empty]),
|
||||
Argument("provision-image-url",
|
||||
'A URL or local file location for an image to download'
|
||||
'and provision in Glance (defaults to a URL for a '
|
||||
'recent "cirros" image).',
|
||||
"CONFIG_PROVISION_IMAGE_URL",
|
||||
'http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-'
|
||||
'x86_64-disk.img',
|
||||
validators=[validators.not_empty])
|
||||
]
|
||||
}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
def init_sequences():
|
||||
controller = Controller.get()
|
||||
conf = controller.CONF
|
||||
if util.str2bool(conf['CONFIG_PROVISION_DEMO']):
|
||||
controller.add_sequence("Running provisioning",
|
||||
setup_controller)
|
||||
|
||||
|
||||
def setup_controller():
|
||||
conf = Controller.get().CONF
|
||||
templates = ['provision']
|
||||
recipe = ""
|
||||
for template in templates:
|
||||
recipe += utils.get_template(template)
|
||||
|
||||
return utils.run_recipe("provision.py", recipe,
|
||||
[conf["CONFIG_CONTROLLER_HOST"]])
|
||||
@@ -0,0 +1,101 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 os
|
||||
import stat
|
||||
|
||||
from clearstack import utils
|
||||
from clearstack import validators
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.argument import Argument
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
def init_config():
|
||||
conf = {
|
||||
"SWIFT": [
|
||||
Argument("swift-ks-pw",
|
||||
"Password to use for the Object Storage service to "
|
||||
" authenticate with with the Identity service",
|
||||
"CONFIG_SWIFT_KS_PW",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("swift-storages",
|
||||
"Comma-separated list of devices to use as storage device"
|
||||
" for Object Storage. e.g. /path/to/dev1,/path/to/dev2."
|
||||
" Clearstack DOES NOT creare the file system, you must "
|
||||
"format it with xfs. Leave blank to use a loop device",
|
||||
"CONFIG_SWIFT_STORAGES",
|
||||
'',
|
||||
validators=[validate_storage]),
|
||||
Argument("swift-storage-zones",
|
||||
"Number of Object Storage storage zones; this number "
|
||||
"MUST be no larger than the number of configured "
|
||||
"storage devices.",
|
||||
"CONFIG_SWIFT_STORAGE_ZONES",
|
||||
'1',
|
||||
validators=[validators.digit]),
|
||||
Argument("swift-storage-replicas",
|
||||
"Number of Object Storage storage replicas; this number "
|
||||
"MUST be no larger than the number of configured "
|
||||
"storage zones.",
|
||||
"CONFIG_SWIFT_STORAGE_REPLICAS",
|
||||
'1',
|
||||
validators=[validators.digit]),
|
||||
Argument("swift-hash",
|
||||
"Custom seed number to use for swift_hash_path_suffix in"
|
||||
" /etc/swift/swift.conf. If you do not provide a value, "
|
||||
"a seed number is automatically generated.",
|
||||
"CONFIG_SWIFT_HASH",
|
||||
utils.generate_random_pw(),
|
||||
validators=[validators.not_empty]),
|
||||
Argument("swift-storage-size",
|
||||
"Size of the Object Storage loopback file storage "
|
||||
"device in GB",
|
||||
"CONFIG_SWIFT_STORAGE_SIZE",
|
||||
"2",
|
||||
validators=[validators.digit]),
|
||||
]
|
||||
}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
def init_sequences():
|
||||
controller = Controller.get()
|
||||
conf = controller.CONF
|
||||
if util.str2bool(conf['CONFIG_SWIFT_INSTALL']):
|
||||
controller.add_sequence("Setting up swift", setup_swift)
|
||||
|
||||
|
||||
def setup_swift():
|
||||
conf = Controller.get().CONF
|
||||
recipe = utils.get_template("swift")
|
||||
return utils.run_recipe("swift.py", recipe,
|
||||
[conf["CONFIG_CONTROLLER_HOST"]])
|
||||
|
||||
|
||||
def validate_storage(value):
|
||||
if not value:
|
||||
return
|
||||
devices = value.split(',')
|
||||
for device in devices:
|
||||
mode = os.stat(device).st_mode
|
||||
if not stat.S_ISBLK(mode):
|
||||
raise ValueError("%s is not a block device" % device)
|
||||
@@ -0,0 +1,110 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 re
|
||||
import os
|
||||
|
||||
from importlib import import_module
|
||||
|
||||
from clearstack import utils
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.common.util import LOG
|
||||
|
||||
|
||||
def load_plugins():
|
||||
""" return if plugins already are loaded """
|
||||
if Controller.get().get_all_plugins():
|
||||
return
|
||||
|
||||
path = "plugins"
|
||||
base_module = "clearstack.{0}".format(path)
|
||||
directory = "{0}/{1}".format(os.path.dirname(
|
||||
os.path.realpath(__file__)), path)
|
||||
rx_val = r'^[a-zA-Z]+_[0-9]{3}\.py$'
|
||||
files = [fd for fd in os.listdir(directory) if re.match(rx_val, fd)]
|
||||
for fd in sorted(files, key=_get_weight):
|
||||
plugin = import_module("{0}.{1}".format(base_module, fd.split(".")[0]))
|
||||
Controller.get().add_plugin(plugin)
|
||||
try:
|
||||
getattr(plugin, "init_config")()
|
||||
except AttributeError:
|
||||
LOG.debug("missing attribute: init_config in %s",
|
||||
plugin.__file__)
|
||||
|
||||
|
||||
def add_arguments(parser):
|
||||
load_plugins()
|
||||
for group in Controller.get().get_all_groups():
|
||||
for argument in group.get_all_arguments():
|
||||
parser.add_argument("--{0}".format(argument.cmd_option),
|
||||
action="store",
|
||||
dest=argument.conf_name,
|
||||
help=argument.description,
|
||||
choices=argument.option_list)
|
||||
|
||||
|
||||
def load_sequences():
|
||||
load_plugins()
|
||||
for plugin in Controller.get().get_all_plugins():
|
||||
try:
|
||||
getattr(plugin, "init_sequences")()
|
||||
except AttributeError:
|
||||
LOG.debug("missing attribute: init_sequences in %s",
|
||||
plugin.__file__)
|
||||
|
||||
|
||||
def run_all_sequences():
|
||||
load_sequences()
|
||||
|
||||
try:
|
||||
utils.copy_resources()
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
try:
|
||||
Controller.get().run_all_sequences()
|
||||
except Exception as e:
|
||||
raise e
|
||||
finally:
|
||||
utils.get_logs()
|
||||
|
||||
|
||||
def generate_admin_openrc():
|
||||
conf = Controller.get().CONF
|
||||
home = os.getenv('HOME')
|
||||
with open("{0}/admin-openrc.sh".format(home), "w") as f:
|
||||
f.write('export OS_PROJECT_DOMAIN_ID=default\n')
|
||||
f.write('export OS_USER_DOMAIN_ID=default\n')
|
||||
f.write('export OS_PROJECT_NAME=admin\n')
|
||||
f.write('export OS_USERNAME="admin"\n')
|
||||
f.write('export OS_TENANT_NAME="admin"\n')
|
||||
f.write('export OS_AUTH_URL=http://{0}:35357/v3\n'
|
||||
.format(conf['CONFIG_CONTROLLER_HOST']))
|
||||
f.write('export OS_REGION_NAME="{0}"\n'
|
||||
.format(conf['CONFIG_KEYSTONE_REGION']))
|
||||
f.write('export OS_PASSWORD={0}\n'
|
||||
.format(conf['CONFIG_KEYSTONE_ADMIN_PW']))
|
||||
f.write('export OS_IDENTITY_API_VERSION=3\n')
|
||||
|
||||
|
||||
def _get_weight(item):
|
||||
tmp = item.split('_')[-1]
|
||||
tmp = tmp.split('.')[0]
|
||||
return tmp
|
||||
@@ -0,0 +1,39 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 clearstack.common.util import LOG
|
||||
|
||||
|
||||
class Sequence:
|
||||
def __init__(self, desc, function, args=None):
|
||||
self.description = desc
|
||||
self.function = function
|
||||
self.function_args = args
|
||||
|
||||
def run(self):
|
||||
LOG.info(self.description)
|
||||
if self.function_args:
|
||||
if not self.function(*self.function_args):
|
||||
raise Exception("error running {0}({1})"
|
||||
.format(self.function.__name__,
|
||||
self.function_args))
|
||||
else:
|
||||
if not self.function():
|
||||
raise Exception("error running {0}"
|
||||
.format(self.function.__name__))
|
||||
@@ -0,0 +1,143 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
"""Command-line interface to configure Clearstack."""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
import clearstack
|
||||
from clearstack.answer_file import AnswerFile
|
||||
from clearstack import run_setup
|
||||
from clearstack import utils
|
||||
from clearstack.common.util import LOG
|
||||
|
||||
|
||||
class ClearstackConfiguratorShell(object):
|
||||
|
||||
def __init__(self, parser_class=argparse.ArgumentParser):
|
||||
self.parser_class = parser_class
|
||||
|
||||
def get_base_parser(self):
|
||||
parser = self.parser_class(
|
||||
prog='clearstack',
|
||||
description=__doc__.strip(),
|
||||
epilog='See "clearstack help COMMAND" '
|
||||
'for help on a specific command.',
|
||||
add_help=False,
|
||||
formatter_class=argparse.HelpFormatter,
|
||||
)
|
||||
|
||||
# Global arguments
|
||||
parser.add_argument('-h',
|
||||
'--help',
|
||||
action='store_true',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--version',
|
||||
action='version',
|
||||
version=clearstack.__version__,
|
||||
help="Shows the client version and exits.")
|
||||
|
||||
parser.add_argument('-d',
|
||||
'--debug',
|
||||
action='store_true',
|
||||
help="Enable debug mode in clearstack")
|
||||
|
||||
parser.add_argument('--gen-answer-file',
|
||||
action='store',
|
||||
dest='gen_answer_file',
|
||||
help='Generate an answer file')
|
||||
|
||||
parser.add_argument('--answer-file',
|
||||
action='store',
|
||||
dest='answer_file',
|
||||
help='Read answer file')
|
||||
|
||||
parser.add_argument('--gen-keys',
|
||||
action='store',
|
||||
dest='gen_keys',
|
||||
help='Generate ssh keys')
|
||||
|
||||
return parser
|
||||
|
||||
def main(self, argv):
|
||||
self.parser = self.get_base_parser()
|
||||
run_setup.add_arguments(self.parser)
|
||||
(options, args) = self.parser.parse_known_args(argv)
|
||||
utils.setup_debugging(options.debug)
|
||||
|
||||
LOG.debug('Starting clearstack')
|
||||
|
||||
if not argv or options.help:
|
||||
self.do_help(options)
|
||||
return 0
|
||||
|
||||
if options.gen_keys:
|
||||
LOG.debug('generating ssh keys')
|
||||
utils.generate_ssh_keys(options.gen_keys)
|
||||
|
||||
# todo: fix
|
||||
# if options.allinone:
|
||||
# LOG.debug('testing root access')
|
||||
# if os.geteuid() != 0:
|
||||
# LOG.error("clearstack: error: you need to have root access")
|
||||
# sys.exit(1)
|
||||
|
||||
""" Save user's variables, used to read/write answerfile """
|
||||
variables_cmd = {k: v for (k, v) in options.__dict__.items()
|
||||
if v is not None and k.startswith("CONFIG_")}
|
||||
|
||||
ansfile = AnswerFile.get()
|
||||
if options.gen_answer_file:
|
||||
LOG.debug('generating answer file')
|
||||
ansfile.generate(options.gen_answer_file, variables_cmd)
|
||||
|
||||
if options.answer_file:
|
||||
try:
|
||||
LOG.debug('Reading answer file')
|
||||
ansfile.read(options.answer_file, variables_cmd)
|
||||
LOG.debug('Running all sequences')
|
||||
run_setup.run_all_sequences()
|
||||
except Exception as e:
|
||||
LOG.error("clearstack: {0}".format(str(e)))
|
||||
sys.exit(1)
|
||||
LOG.debug('Generating admin-openrc')
|
||||
run_setup.generate_admin_openrc()
|
||||
|
||||
@utils.arg('command', metavar='<subcommand>', nargs='?',
|
||||
help='Display help for <subcommand>.')
|
||||
def do_help(self, args):
|
||||
self.parser.print_help()
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
ClearstackConfiguratorShell().main(sys.argv[1:])
|
||||
except KeyboardInterrupt:
|
||||
print("... terminating clearstack", file=sys.stderr)
|
||||
sys.exit(130)
|
||||
except Exception as e:
|
||||
print(str(e), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,166 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Obed Muñoz <obed.n.munoz@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 os
|
||||
|
||||
import paramiko
|
||||
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.common import util
|
||||
from clearstack.common.util import LOG
|
||||
from clearstack.common.singleton import Singleton
|
||||
|
||||
|
||||
@Singleton
|
||||
class SshHandler(object):
|
||||
def __init__(self):
|
||||
conf = Controller.get().CONF
|
||||
path = os.path.expanduser(
|
||||
conf['CONFIG_PRIVATE_SSH_KEY'])
|
||||
path = os.path.realpath(path)
|
||||
self.ssh_private_key = path
|
||||
self.ssh_user = "root"
|
||||
|
||||
def connect(self, user, key_file, host):
|
||||
''' Creates a connection to the host using SSH key '''
|
||||
private_key = paramiko.RSAKey.from_private_key_file(key_file)
|
||||
connection = paramiko.SSHClient()
|
||||
connection.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
connection.connect(hostname=host, username=user, pkey=private_key,
|
||||
timeout=1000)
|
||||
return connection
|
||||
|
||||
def run_command(self, connection, command):
|
||||
try:
|
||||
stdin, stdout, stderr = connection.exec_command(command)
|
||||
while not stdout.channel.exit_status_ready():
|
||||
pass
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
''' if stderr is not empty then something fail '''
|
||||
error = stderr.read()
|
||||
if error:
|
||||
raise Exception(error.decode('utf-8'))
|
||||
|
||||
return stdin, stdout, stderr
|
||||
|
||||
def transfer_file(self, file, dest_path, ip):
|
||||
try:
|
||||
connection = self.connect(self.ssh_user, self.ssh_private_key, ip)
|
||||
sftp = connection.open_sftp()
|
||||
except paramiko.ssh_exception.SSHException:
|
||||
raise Exception("cannot send {0} to {1}, please check"
|
||||
" your ssh connection".format(file, ip))
|
||||
|
||||
if os.path.isdir(file):
|
||||
parent_dir = "/".join(file.split('/')[:-1])
|
||||
try:
|
||||
sftp.mkdir(dest_path)
|
||||
except IOError:
|
||||
pass
|
||||
for dirpath, dirnames, filenames in os.walk(file):
|
||||
remote_path = dest_path + dirpath.split(parent_dir)[1]
|
||||
try:
|
||||
sftp.mkdir(remote_path)
|
||||
except:
|
||||
LOG.info("clearstack: Directory {0} is already created"
|
||||
"in remote host".format(remote_path))
|
||||
for filename in filenames:
|
||||
local_path = os.path.join(dirpath, filename)
|
||||
remote_filepath = os.path.join(remote_path, filename)
|
||||
sftp.put(local_path, remote_filepath)
|
||||
else:
|
||||
filename = file.split('/')[-1]
|
||||
sftp.put(file, "{0}/{1}".format(dest_path, filename))
|
||||
|
||||
connection.close()
|
||||
|
||||
def test_python_in_host(self, host, connection):
|
||||
try:
|
||||
stdin, stdout, stderr = self.run_command(connection,
|
||||
'python3 --version')
|
||||
except:
|
||||
raise Exception("cannot run python3 in {0},"
|
||||
" please install python3".format(host))
|
||||
|
||||
def test_hosts(self, _hosts):
|
||||
hosts = set(_hosts)
|
||||
connection = None
|
||||
conf = Controller.get().CONF
|
||||
|
||||
util.remove_localhost(hosts)
|
||||
|
||||
if not conf['CONFIG_PRIVATE_SSH_KEY'] and hosts:
|
||||
raise Exception("CONFIG_PRIVATE_SSH_KEY: missing private key")
|
||||
|
||||
for host in hosts:
|
||||
try:
|
||||
connection = self.connect(self.ssh_user, self.ssh_private_key,
|
||||
host)
|
||||
self.test_python_in_host(host, connection)
|
||||
except Exception as e:
|
||||
raise Exception("host {0}: {1}".format(host, str(e)))
|
||||
finally:
|
||||
if connection:
|
||||
connection.close()
|
||||
|
||||
def run_recipe(self, recipe_file, host):
|
||||
connection = None
|
||||
interpreter = "python3"
|
||||
if recipe_file.endswith('.sh'):
|
||||
interpreter = "bash -f"
|
||||
|
||||
try:
|
||||
connection = self.connect(self.ssh_user, self.ssh_private_key,
|
||||
host)
|
||||
cmd = "source /root/.bashrc 2> /dev/null;" \
|
||||
"source /usr/share/defaults/etc/profile 2> /dev/null;" \
|
||||
"{0} {1}".format(interpreter, recipe_file)
|
||||
stdin, stdout, stderr = self.run_command(connection, cmd)
|
||||
except Exception as e:
|
||||
LOG.error("clearstack: an error has occurred in {0},"
|
||||
" please check logs for more information"
|
||||
.format(host))
|
||||
raise e
|
||||
finally:
|
||||
if connection:
|
||||
connection.close()
|
||||
|
||||
def get_logs(self, _hosts):
|
||||
hosts = set(_hosts)
|
||||
basename = os.path.splitext(util.LOG_FILE)[0]
|
||||
connection = None
|
||||
|
||||
util.remove_localhost(hosts)
|
||||
|
||||
for host in hosts:
|
||||
new_name = "{0}-{1}.log".format(basename, host)
|
||||
try:
|
||||
connection = self.connect(self.ssh_user, self.ssh_private_key,
|
||||
host)
|
||||
sftp = connection.open_sftp()
|
||||
sftp.get(util.HOST_LOG_FILE, new_name)
|
||||
except:
|
||||
LOG.warning("clearstack: cannot get log file from {0}".format(
|
||||
host))
|
||||
finally:
|
||||
if connection:
|
||||
connection.close()
|
||||
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 modules.ceilometer import Ceilometer
|
||||
from common import util
|
||||
|
||||
|
||||
ceilometer = Ceilometer.get()
|
||||
config_file = "/etc/ceilometer/ceilometer.conf"
|
||||
|
||||
ceilometer.install()
|
||||
ceilometer.create_user()
|
||||
ceilometer.create_service()
|
||||
ceilometer.create_endpoint()
|
||||
|
||||
ceilometer.config_debug(config_file)
|
||||
ceilometer.config_database(config_file)
|
||||
ceilometer.config_rabbitmq(config_file)
|
||||
ceilometer.config_auth(config_file)
|
||||
ceilometer.config_service_credentials(config_file)
|
||||
|
||||
util.run_command("systemctl restart update-triggers.target")
|
||||
ceilometer.start_server()
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
|
||||
# reset neutron services
|
||||
neutron_services="neutron-server neutron-linuxbridge-agent \
|
||||
neutron-dhcp-agent neutron-metadata-agent neutron-l3-agent"
|
||||
systemctl stop $neutron_services
|
||||
systemctl disable $neutron_services
|
||||
|
||||
# Reset compute services
|
||||
systemctl disable libvirtd.socket libvirtd.service nova-compute.service \
|
||||
nova-network.service nova-metadata.{socket,service}
|
||||
systemctl stop libvirtd.socket libvirtd.service nova-compute.service \
|
||||
nova-network.service nova-metadata.{socket,service}
|
||||
|
||||
# Delete nova config file
|
||||
rm -rf /etc/nova
|
||||
|
||||
# Update /etc/nova permissions
|
||||
systemctl restart update-triggers.target
|
||||
|
||||
# Clean Bridges
|
||||
ip link set br100 down
|
||||
brctl delbr br100
|
||||
|
||||
# Restart network service
|
||||
systemctl restart systemd-networkd
|
||||
|
||||
# Clean Nova data
|
||||
rm -rf /var/lib/nova/CA/*
|
||||
rm -rf /var/lib/nova/instances/*
|
||||
rm -rf /var/lib/nova/keys/*
|
||||
rm -rf /var/lib/nova/networks/*
|
||||
|
||||
# Clean Libvirt data
|
||||
rm -rf /var/lib/libvirt/qemu/*.monitor
|
||||
rm -rf /etc/libvirt/nwfilter/*
|
||||
rm -rf /etc/libvirt/qemu/*
|
||||
|
||||
# Kill reamining qemu VMs
|
||||
ps aux | grep qemu | grep -v grep | awk '{print $2}' | xargs kill -9
|
||||
|
||||
# Kill all about dnsmasq
|
||||
ps aux | grep dnsmasq | grep -v grep | awk '{print $2}' | xargs kill -9
|
||||
|
||||
# Clean Logs
|
||||
rm -rf /var/log/nova/*
|
||||
rm -rf /var/log/libvirt/qemu/*
|
||||
rm -rf /var/log/swupd/*
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
|
||||
# reset neutron services
|
||||
neutron_services="neutron-server neutron-linuxbridge-agent \
|
||||
neutron-dhcp-agent neutron-metadata-agent neutron-l3-agent"
|
||||
systemctl stop $neutron_services
|
||||
systemctl disable $neutron_services
|
||||
|
||||
# reset nova services
|
||||
systemctl stop memcached uwsgi@nova-{api,metadata}.{service,socket} nova-cert \
|
||||
nova-consoleauth nova-scheduler \
|
||||
nova-conductor nova-novncproxy
|
||||
systemctl disable memcached uwsgi@nova-{api,metadata}.{service,socket} nova-cert \
|
||||
nova-consoleauth nova-scheduler \
|
||||
nova-conductor nova-novncproxy
|
||||
rm -rf /etc/nova
|
||||
|
||||
# reset glance services
|
||||
systemctl stop glance-api glance-registry
|
||||
systemctl disable glance-api glance-registry
|
||||
rm -rf /etc/glance
|
||||
rm -rf /var/lib/glance/images/*
|
||||
|
||||
# reset keystone services
|
||||
systemctl stop httpd nginx uwsgi@keystone{admin,public}.{socket,service}
|
||||
systemctl disable httpd nginx
|
||||
rm -rf /etc/keystone
|
||||
rm /etc/httpd/conf.d/wsgi-keystone.conf
|
||||
|
||||
# reset horizon
|
||||
systemctl stop httpd nginx uwsgi@horizon.{socket,service}
|
||||
|
||||
# reset owners and permissions
|
||||
systemctl restart update-triggers.target
|
||||
|
||||
# reset rabbitmq
|
||||
systemctl stop rabbitmq-server
|
||||
systemctl disable rabbitmq-server
|
||||
rm -rf /etc/rabbitmq/rabbitmq.config
|
||||
rm -rf /var/lib/rabbitmq/*
|
||||
rm -rf /etc/hosts
|
||||
|
||||
# reset mariadb
|
||||
systemctl stop mariadb
|
||||
systemctl disable mariadb
|
||||
rm -rf /etc/mariadb
|
||||
rm -rf /var/lib/mysql
|
||||
|
||||
# Clean Logs
|
||||
rm -rf /var/log/nova/*
|
||||
rm -rf /var/log/keystone/*
|
||||
rm -rf /var/log/glance/*
|
||||
rm -rf /var/log/rabbitmq/*
|
||||
rm -rf /var/log/httpd/*
|
||||
rm -rf /var/log/swupd/*
|
||||
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 common import util
|
||||
from modules.conf import CONF
|
||||
from modules.glance import Glance
|
||||
|
||||
|
||||
glance = Glance.get()
|
||||
config_files = ["/etc/glance/glance-api.conf"]
|
||||
config_files.append("/etc/glance/glance-registry.conf")
|
||||
|
||||
glance.install()
|
||||
glance.create_user()
|
||||
glance.create_service()
|
||||
glance.create_endpoint()
|
||||
|
||||
for config_file in config_files:
|
||||
glance.config_debug(config_file)
|
||||
glance.config_database(config_file)
|
||||
glance.config_auth(config_file)
|
||||
if util.str2bool(CONF['CONFIG_CEILOMETER_INSTALL']):
|
||||
glance.ceilometer_enable(config_file)
|
||||
|
||||
util.run_command("systemctl restart update-triggers.target")
|
||||
glance.sync_database()
|
||||
glance.start_server()
|
||||
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 common import util
|
||||
from modules.heat import Heat
|
||||
|
||||
|
||||
heat = Heat.get()
|
||||
config_file = "/etc/heat/heat.conf"
|
||||
|
||||
heat.install()
|
||||
heat.create_user()
|
||||
heat.create_service(name='heat', description='OpenStack Orchestration',
|
||||
type='orchestration')
|
||||
heat.create_service(name='heat-cfn', description='OpenStack Orchestration',
|
||||
type='cloudformation')
|
||||
heat.create_endpoint()
|
||||
publicurl = "http://%s:8000/v1" % heat._controller
|
||||
heat.create_endpoint(publicurl=publicurl, internalurl=publicurl,
|
||||
adminurl=publicurl, type='cloudformation')
|
||||
heat.create_domain(heat.domain_name, 'Stack projects and users')
|
||||
heat.create_user(user=heat.domain_admin, password=heat.domain_admin_pw,
|
||||
domain=heat.domain_name)
|
||||
heat.create_role('heat_stack_owner')
|
||||
heat.create_role('heat_stack_user')
|
||||
|
||||
heat.config_database(config_file)
|
||||
heat.config_rabbitmq(config_file)
|
||||
heat.config_auth(config_file)
|
||||
heat.config_domain(config_file)
|
||||
|
||||
util.run_command("systemctl restart update-triggers.target")
|
||||
heat.sync_database()
|
||||
heat.start_server()
|
||||
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 modules.horizon import Horizon
|
||||
|
||||
|
||||
horizon = Horizon.get()
|
||||
horizon.install()
|
||||
horizon.start_server()
|
||||
@@ -0,0 +1,47 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 modules.conf import CONF
|
||||
from modules.keystone import Keystone
|
||||
from common import util
|
||||
|
||||
keystone = Keystone.get()
|
||||
config_file = "/etc/keystone/keystone.conf"
|
||||
|
||||
keystone.install()
|
||||
keystone.config_debug(config_file)
|
||||
keystone.config_database(config_file)
|
||||
keystone.config_admin_token(config_file)
|
||||
|
||||
util.run_command("systemctl restart update-triggers.target")
|
||||
keystone.sync_database()
|
||||
keystone.start_server()
|
||||
|
||||
keystone.create_service()
|
||||
keystone.create_endpoint()
|
||||
keystone.create_project("admin", "Admin Project")
|
||||
keystone.create_role("admin")
|
||||
keystone.create_user(user="admin", project="admin", role="admin")
|
||||
keystone.create_project("service", "Service Project")
|
||||
keystone.create_project("demo", "Demo Project")
|
||||
keystone.create_role("user")
|
||||
keystone.create_user(user="demo", project="demo", role="user",
|
||||
password=CONF['CONFIG_KEYSTONE_DEMO_PW'])
|
||||
util.delete_option(config_file, "DEFAULT", "admin_token")
|
||||
keystone.start_server()
|
||||
@@ -0,0 +1,46 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 socket
|
||||
|
||||
from common.util import LOG
|
||||
from common import util
|
||||
from modules.conf import CONF
|
||||
from modules.mariadb import MariaDB
|
||||
|
||||
conf = CONF
|
||||
mariadb = MariaDB.get()
|
||||
mariadb_user = CONF["CONFIG_MARIADB_USER"]
|
||||
mariadb_pw = CONF["CONFIG_MARIADB_PW"]
|
||||
controller = socket.gethostbyaddr(CONF["CONFIG_CONTROLLER_HOST"])[0]
|
||||
|
||||
if util.str2bool(conf['CONFIG_MARIADB_INSTALL']):
|
||||
mariadb.install()
|
||||
mariadb.configure()
|
||||
mariadb.start_server()
|
||||
mariadb.secure_installation(mariadb_user, mariadb_pw)
|
||||
|
||||
databases = ['keystone', 'glance', 'nova', 'neutron', 'heat']
|
||||
|
||||
for database in databases:
|
||||
if database == 'keystone' or util.str2bool(conf['CONFIG_%s_INSTALL'
|
||||
% database.upper()]):
|
||||
LOG.info("Setting up mariadb for %s" % database)
|
||||
password = CONF['CONFIG_%s_DB_PW' % database.upper()]
|
||||
mariadb.setup_database(database, database, password, controller)
|
||||
@@ -0,0 +1,31 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 common import util
|
||||
from modules.conf import CONF
|
||||
from modules.mongodb import MongoDB
|
||||
|
||||
mongo = MongoDB.get()
|
||||
|
||||
if util.str2bool(CONF['CONFIG_MONGODB_INSTALL']):
|
||||
mongo.install()
|
||||
mongo.configure()
|
||||
mongo.start_server()
|
||||
|
||||
mongo.setup_database('ceilometer', 'ceilometer',
|
||||
CONF['CONFIG_CEILOMETER_DB_PW'])
|
||||
@@ -0,0 +1,60 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 modules.conf import CONF
|
||||
from modules.neutron import Neutron
|
||||
from common import util
|
||||
|
||||
|
||||
neutron = Neutron.get()
|
||||
config_file = "/etc/neutron/neutron.conf"
|
||||
|
||||
# Install neutron controller
|
||||
neutron.install()
|
||||
neutron.create_user()
|
||||
neutron.create_service()
|
||||
neutron.create_endpoint()
|
||||
|
||||
# Configure neutron controller
|
||||
neutron.config_debug(config_file)
|
||||
neutron.config_database(config_file)
|
||||
neutron.config_rabbitmq(config_file)
|
||||
neutron.config_auth(config_file)
|
||||
|
||||
neutron.config_nova(config_file)
|
||||
neutron.config_ml2_plugin()
|
||||
neutron.config_linux_bridge_agent()
|
||||
neutron.config_l3_agent("/etc/neutron/l3_agent.ini")
|
||||
neutron.config_dhcp_agent("/etc/neutron/dhcp_agent.ini")
|
||||
neutron.config_metadata_agent("/etc/neutron/metadata_agent.ini")
|
||||
neutron.config_neutron_on_nova("/etc/nova/nova.conf")
|
||||
|
||||
if util.str2bool(CONF['CONFIG_CEILOMETER_INSTALL']):
|
||||
neutron.ceilometer_enable(config_file)
|
||||
|
||||
if util.str2bool(CONF['CONFIG_LBAAS_INSTALL']):
|
||||
neutron.install('openstack-lbaas')
|
||||
neutron.config_lbaas()
|
||||
|
||||
if util.str2bool(CONF['CONFIG_VPNAAS_INSTALL']):
|
||||
neutron.install('openstack-vpnaas')
|
||||
neutron.config_vpnaas()
|
||||
|
||||
util.run_command("systemctl restart update-triggers.target")
|
||||
neutron.sync_database()
|
||||
neutron.start_server()
|
||||
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 modules.conf import CONF
|
||||
from modules.neutron import Neutron
|
||||
from common import util
|
||||
|
||||
|
||||
neutron = Neutron.get()
|
||||
config_file = "/etc/neutron/neutron.conf"
|
||||
services = ['nova-compute', 'neutron-linuxbridge-agent']
|
||||
|
||||
neutron.install()
|
||||
neutron.config_debug(config_file)
|
||||
neutron.config_rabbitmq(config_file)
|
||||
neutron.config_auth(config_file)
|
||||
neutron.config_linux_bridge_agent()
|
||||
neutron.config_neutron_on_nova('/etc/nova/nova.conf')
|
||||
|
||||
if util.str2bool(CONF['CONFIG_CEILOMETER_INSTALL']):
|
||||
neutron.ceilometer_enable(config_file)
|
||||
|
||||
util.run_command("systemctl restart update-triggers.target")
|
||||
|
||||
neutron.start_server(services)
|
||||
@@ -0,0 +1,72 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 modules.nova import Nova
|
||||
from modules.conf import CONF
|
||||
from common import util
|
||||
|
||||
|
||||
nova = Nova.get()
|
||||
config_file = "/etc/nova/nova.conf"
|
||||
my_ip = util.get_ip()
|
||||
|
||||
# Install nova controller
|
||||
nova.install()
|
||||
nova.create_user()
|
||||
nova.create_service()
|
||||
nova.create_endpoint()
|
||||
|
||||
# Configure nova controller
|
||||
nova.config_debug(config_file)
|
||||
nova.config_database(config_file)
|
||||
nova.config_rabbitmq(config_file)
|
||||
nova.config_auth(config_file)
|
||||
|
||||
# Setup vncproxy
|
||||
config = \
|
||||
"[DEFAULT]\n" + \
|
||||
"my_ip=%s\n" % my_ip + \
|
||||
"[vnc]\n" + \
|
||||
"vncserver_listen=0.0.0.0\n" + \
|
||||
"vncserver_proxyclient_address=%s\n" % my_ip
|
||||
util.write_config(config_file, config)
|
||||
|
||||
# Setup glance host
|
||||
config = \
|
||||
"[glance]\n" + \
|
||||
"host=%s\n" % CONF['CONFIG_CONTROLLER_HOST']
|
||||
util.write_config(config_file, config)
|
||||
|
||||
# Setup nova-network if neutron is not installed
|
||||
if not util.str2bool(CONF['CONFIG_NEUTRON_INSTALL']):
|
||||
config = \
|
||||
"[DEFAULT]\n" + \
|
||||
"network_api_class = nova.network.api.API\n" + \
|
||||
"security_group_api = nova\n"
|
||||
util.write_config(config_file, config)
|
||||
|
||||
if CONF['CONFIG_HTTP_SERVICE'] == 'nginx':
|
||||
util.link_file('/usr/share/nginx/conf.d/nova-api.template',
|
||||
'/etc/nginx/nova-api.conf')
|
||||
else:
|
||||
util.link_file('/usr/share/defaults/httpd/conf.d/nova-api.template',
|
||||
'/etc/httpd/conf.d/nova-api.conf')
|
||||
|
||||
util.run_command("systemctl restart update-triggers.target")
|
||||
nova.sync_database()
|
||||
nova.start_server()
|
||||
@@ -0,0 +1,97 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Obed Muñoz <obed.n.munoz@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 modules import clearlinux
|
||||
from modules.nova import Nova
|
||||
from modules.conf import CONF
|
||||
from common import util
|
||||
|
||||
|
||||
nova = Nova.get()
|
||||
config_file = "/etc/nova/nova.conf"
|
||||
services = ['libvirtd.socket', 'nova-compute']
|
||||
my_ip = util.get_ip()
|
||||
|
||||
if CONF['CONFIG_HTTP_SERVICE'] == 'nginx':
|
||||
services.extend(['nginx', 'uwsgi@nova-metadata.socket'])
|
||||
elif CONF['CONFIG_HTTP_SERVICE'] == 'apache2':
|
||||
services.append('httpd')
|
||||
else:
|
||||
services.append('nova-api-metadata')
|
||||
|
||||
nova.install_compute()
|
||||
nova.config_debug(config_file)
|
||||
nova.config_rabbitmq(config_file)
|
||||
nova.config_auth(config_file)
|
||||
|
||||
# Setup vncproxy server
|
||||
config = ("[DEFAULT]\n"
|
||||
"my_ip={0}\n"
|
||||
"[vnc]\n"
|
||||
"vnc_enabled=True\n"
|
||||
"vncserver_listen=0.0.0.0\n"
|
||||
"vncserver_proxyclient_address={0}\n"
|
||||
"novncproxy_base_url=http://{1}:6080/vnc_auto.html\n"
|
||||
.format(my_ip, CONF['CONFIG_CONTROLLER_HOST']))
|
||||
|
||||
# Setup glance host
|
||||
config += ("[glance]\n"
|
||||
"host=%s\n") % CONF['CONFIG_CONTROLLER_HOST']
|
||||
|
||||
# Disable HW acceleration on unsupported HW
|
||||
if not clearlinux.support_hw_acceleration():
|
||||
config += ("[libvirt]\n"
|
||||
"virt_type=qemu\n")
|
||||
|
||||
util.write_config(config_file, config)
|
||||
|
||||
# Setup compute Networking
|
||||
if not util.str2bool(CONF['CONFIG_NEUTRON_INSTALL']):
|
||||
services.append("nova-network")
|
||||
network_manager = CONF['CONFIG_NOVA_NETWORK_MANAGER']
|
||||
network_size = CONF['CONFIG_NOVA_NETWORK_SIZE']
|
||||
multihost = CONF['CONFIG_NOVA_NETWORK_MULTIHOST']
|
||||
network_pubif = CONF['CONFIG_NOVA_NETWORK_PUBIF']
|
||||
network_privif = CONF['CONFIG_NOVA_COMPUTE_PRIVIF']
|
||||
config = \
|
||||
"[DEFAULT]\n" + \
|
||||
"network_api_class=nova.network.api.API\n" + \
|
||||
"security_group_api=nova\n" + \
|
||||
"firewall_driver=" + \
|
||||
"nova.virt.libvirt.firewall.IptablesFirewallDriver\n" + \
|
||||
"network_size=%s\n" % network_size + \
|
||||
"allow_same_net_traffic=False\n" + \
|
||||
"multi_host=%s\n" % multihost + \
|
||||
"send_arp_for_ha=True\n" + \
|
||||
"share_dhcp_address=True\n" + \
|
||||
"force_dhcp_release=True\n" + \
|
||||
"flat_network_bridge=br100\n" + \
|
||||
"public_interface=%s\n" % network_pubif + \
|
||||
"flat_interface=%s\n" % network_privif
|
||||
if util.str2bool(CONF['CONFIG_NOVA_NETWORK_AUTOASSIGNFLOATINGIP']):
|
||||
config += "auto_assign_floating_ip = True\n"
|
||||
util.write_config(config_file, config)
|
||||
|
||||
if util.str2bool(CONF['CONFIG_CEILOMETER_INSTALL']):
|
||||
nova.ceilometer_enable(config_file)
|
||||
|
||||
util.run_command("systemctl restart update-triggers.target")
|
||||
nova.start_server(services)
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
if [ -f /bin/swupd ];then
|
||||
if [ ! -f /usr/share/clear/bundles/openstack-configure ];then
|
||||
swupd bundle-add openstack-configure
|
||||
fi
|
||||
elif [ -f /bin/clr_bundle_add];then
|
||||
if [ ! -f /usr/share/clear/bundles/openstack-configure ];then
|
||||
clr_bundle_add openstack-configure
|
||||
fi
|
||||
fi
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
if [ -f /bin/swupd ];then
|
||||
if [ ! -f /usr/share/clear/bundles/openstack-configure ];then
|
||||
swupd bundle-add openstack-configure
|
||||
fi
|
||||
|
||||
if [ ! -f /usr/share/clear/bundles/openstack-python-clients -a ! -f /usr/share/clear/bundles/openstack-all-in-one ];then
|
||||
swupd bundle-add openstack-python-clients
|
||||
fi
|
||||
elif [ -f /bin/clr_bundle_add];then
|
||||
if [ ! -f /usr/share/clear/bundles/openstack-configure ];then
|
||||
clr_bundle_add openstack-configure
|
||||
fi
|
||||
|
||||
if [ ! -f /usr/share/clear/bundles/openstack-python-clients -a ! -f /usr/share/clear/bundles/openstack-all-in-one ];then
|
||||
clr_bundle_add openstack-python-clients
|
||||
fi
|
||||
fi
|
||||
@@ -0,0 +1,44 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 modules.glance import Glance
|
||||
from modules.neutron import Neutron
|
||||
from modules.nova import Nova
|
||||
from modules.conf import CONF
|
||||
from common import util
|
||||
|
||||
glance = Glance.get()
|
||||
nova = Nova.get()
|
||||
neutron = Neutron.get()
|
||||
|
||||
if util.str2bool(CONF['CONFIG_PROVISION_DEMO']):
|
||||
name = CONF['CONFIG_PROVISION_IMAGE_NAME']
|
||||
format = CONF['CONFIG_PROVISION_IMAGE_FORMAT']
|
||||
url = CONF['CONFIG_PROVISION_IMAGE_URL']
|
||||
glance.create_image(name, format, url, public=True)
|
||||
|
||||
fr = CONF['CONFIG_PROVISION_DEMO_FLOATRANGE']
|
||||
CONF['CONFIG_NOVA_NETWORK_FLOATRANGE'] = fr
|
||||
|
||||
if not util.str2bool(CONF['CONFIG_NEUTRON_INSTALL']):
|
||||
nova.create_network()
|
||||
nova.create_floating_ips()
|
||||
else:
|
||||
neutron.create_network('private', public=False)
|
||||
neutron.create_network('public', public=True)
|
||||
neutron.create_router('router', gw='public', interfaces=['private'])
|
||||
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 modules.rabbitmq import Rabbitmq
|
||||
from modules.conf import CONF
|
||||
|
||||
rabbitmq_auth_user = CONF["CONFIG_AMQP_AUTH_USER"]
|
||||
rabbitmq_auth_pw = CONF["CONFIG_AMQP_AUTH_PASSWORD"]
|
||||
|
||||
rabbit = Rabbitmq.get()
|
||||
rabbit.install()
|
||||
rabbit.start_server()
|
||||
rabbit.add_user(rabbitmq_auth_user, rabbitmq_auth_pw)
|
||||
rabbit.set_permissions(rabbitmq_auth_user, '".*" ".*" ".*"')
|
||||
@@ -0,0 +1,58 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
#
|
||||
# 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 common import util
|
||||
from modules.conf import CONF
|
||||
from modules.swift import Swift
|
||||
|
||||
|
||||
swift = Swift.get()
|
||||
config_file = "/etc/swift/proxy-server.conf"
|
||||
|
||||
swift.install()
|
||||
swift.create_user()
|
||||
swift.create_service()
|
||||
swift.create_endpoint()
|
||||
|
||||
swift.config_auth(config_file)
|
||||
swift.config_memcache(config_file)
|
||||
swift.config_hash('/etc/swift/swift.conf')
|
||||
|
||||
# Storage configuration
|
||||
swift.parse_devices()
|
||||
swift.prepare_devices()
|
||||
swift.create_rings()
|
||||
swift.config_rsync()
|
||||
swift.config_storage_services()
|
||||
|
||||
if util.str2bool(CONF['CONFIG_CEILOMETER_INSTALL']):
|
||||
swift.ceilometer_enable(config_file)
|
||||
|
||||
util.run_command("systemctl restart update-triggers.target")
|
||||
|
||||
# Start controller services
|
||||
swift.start_server()
|
||||
|
||||
# Start storage node services
|
||||
services = ['rsyncd', 'swift-account', 'swift-account-auditor',
|
||||
'swift-account-reaper', 'swift-account-replicator',
|
||||
'swift-container', 'swift-container-auditor',
|
||||
'swift-container-replicator', 'swift-container-updater',
|
||||
'swift-object', 'swift-object-auditor',
|
||||
'swift-object-replicator', 'swift-object-updater']
|
||||
swift.start_server(services)
|
||||
@@ -0,0 +1,51 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 mock
|
||||
import testtools
|
||||
|
||||
from clearstack.answer_file import AnswerFile
|
||||
from clearstack.argument import Argument
|
||||
from clearstack.controller import Controller
|
||||
|
||||
conf = {'COMPONENT': [Argument('argument',
|
||||
'description',
|
||||
'CONFIG_ARGUMET',
|
||||
'secure')]}
|
||||
|
||||
for group in conf:
|
||||
Controller.get().add_group(group, conf[group])
|
||||
|
||||
|
||||
class AnswerFileTest(testtools.TestCase):
|
||||
def setUp(self):
|
||||
super(AnswerFileTest, self).setUp()
|
||||
|
||||
def test_generate_file(self):
|
||||
m = mock.mock_open()
|
||||
filename = '/tmp/clearstack.answerfile'
|
||||
with mock.patch('clearstack.answer_file.open', m, create=True):
|
||||
AnswerFile.get().generate(filename, {})
|
||||
m.assert_called_once_with(filename, 'w')
|
||||
|
||||
@mock.patch('os.path.isfile')
|
||||
def test_read_non_existing_file(self, mock_isfile):
|
||||
mock_isfile.side_effect = [False]
|
||||
filename = '/tmp/clearstack.answerfile'
|
||||
self.assertRaises(IOError, AnswerFile.get().read, filename, {})
|
||||
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 testtools
|
||||
|
||||
|
||||
class ArgumentTest(testtools.TestCase):
|
||||
def setUp(self):
|
||||
super(ArgumentTest, self).setUp()
|
||||
|
||||
# def test_argument_validate(self):
|
||||
# argument = Argument('cmd_option', 'description', 'conf_name',
|
||||
# 'default_value')
|
||||
# self.assertTrue(argument.validate('test'))
|
||||
|
||||
# def validator(value):
|
||||
# return 'ERROR'
|
||||
|
||||
# argument = Argument('cmd_option', 'description', 'conf_name',
|
||||
# 'default_value', [validator])
|
||||
# self.assertFalse(argument.validate('test'))
|
||||
@@ -0,0 +1,51 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 testtools
|
||||
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
class ModulesUtilTest(testtools.TestCase):
|
||||
def setUp(self):
|
||||
super(ModulesUtilTest, self).setUp()
|
||||
|
||||
# # Test if run_command is hidden debug logs
|
||||
# def test_0000_run_command(self):
|
||||
# util.setup_debugging(True, False)
|
||||
# util.run_command("echo", debug=False)
|
||||
# logging.StreamHandler().close()
|
||||
# self.assertEqual("echo" in open(self.log_file).read(), False)
|
||||
|
||||
# # Test if run_command is showing debug logs
|
||||
# def test_0001_run_command(self):
|
||||
# util.setup_debugging(True, False)
|
||||
# util.run_command("echo")
|
||||
# logging.StreamHandler().close()
|
||||
# self.assertEqual("echo" in open(self.log_file).read(), True)
|
||||
|
||||
# Test command not found
|
||||
def test_0002_run_command(self):
|
||||
self.assertRaises(Exception, util.run_command, "inexistente")
|
||||
|
||||
# Test simple command
|
||||
def test_0003_run_command(self):
|
||||
try:
|
||||
util.run_command("echo")
|
||||
except Exception:
|
||||
self.fail()
|
||||
@@ -0,0 +1,39 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 mock
|
||||
|
||||
import testtools
|
||||
|
||||
from clearstack.sequence import Sequence
|
||||
|
||||
|
||||
class SequenceTest(testtools.TestCase):
|
||||
def setUp(self):
|
||||
super(SequenceTest, self).setUp()
|
||||
|
||||
def test_run(self):
|
||||
mock_function = mock.Mock(return_value=False)
|
||||
mock_function.__name__ = 'Bar'
|
||||
|
||||
seq = Sequence('test', mock_function)
|
||||
self.assertRaises(Exception, seq.run)
|
||||
|
||||
seq = Sequence('test', mock_function, ["subsequence"])
|
||||
self.assertRaises(Exception, seq.run)
|
||||
@@ -0,0 +1,35 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 testtools
|
||||
from testtools import matchers
|
||||
|
||||
from clearstack.tests import utils
|
||||
|
||||
|
||||
class ShellTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ShellTest, self).setUp()
|
||||
|
||||
def test_help(self):
|
||||
required = 'usage:'
|
||||
help_text = utils.shell('--help')
|
||||
self.assertThat(help_text,
|
||||
matchers.MatchesRegex(required))
|
||||
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 os
|
||||
import sys
|
||||
import io
|
||||
|
||||
from clearstack import shell as clearstack_shell
|
||||
|
||||
|
||||
def shell(argstr):
|
||||
orig = sys.stdout
|
||||
clean_env = {}
|
||||
_old_env, os.environ = os.environ, clean_env.copy()
|
||||
try:
|
||||
sys.stdout = io.StringIO()
|
||||
_shell = clearstack_shell.ClearstackConfiguratorShell()
|
||||
_shell.main(argstr.split())
|
||||
except SystemExit:
|
||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||
assert exc_value, 0
|
||||
finally:
|
||||
out = sys.stdout.getvalue()
|
||||
sys.stdout.close()
|
||||
sys.stdout = orig
|
||||
os.environ = _old_env
|
||||
return out
|
||||
@@ -0,0 +1,200 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
# Author: Victor Morales <victor.morales@intel.com>
|
||||
#
|
||||
# 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 calendar
|
||||
import configparser
|
||||
import datetime
|
||||
import os
|
||||
import binascii
|
||||
import time
|
||||
import shutil
|
||||
|
||||
from clearstack import controller
|
||||
from clearstack.ssh import SshHandler
|
||||
from clearstack.controller import Controller
|
||||
from clearstack.common import util
|
||||
|
||||
|
||||
__now = datetime.datetime.now()
|
||||
__recipes_directory = "/tmp/clearstack-{0}-{1}-{2}-{3}/".format(
|
||||
__now.year, __now.month, __now.day, calendar.timegm(time.gmtime()))
|
||||
|
||||
|
||||
def arg(*args, **kwargs):
|
||||
def _decorator(func):
|
||||
func.__dict__.setdefault('arguments', []).insert(0, (args, kwargs))
|
||||
return func
|
||||
return _decorator
|
||||
|
||||
|
||||
def run_recipe(recipe_file, recipe_src, hosts):
|
||||
recipes_dir = __recipes_directory
|
||||
if not os.path.isdir(recipes_dir):
|
||||
os.makedirs(recipes_dir)
|
||||
|
||||
if controller.DEBUG and recipe_file.endswith('.py'):
|
||||
recipe_src = "from common import util\n" + \
|
||||
"util.setup_debugging(True)\n\n" + \
|
||||
recipe_src
|
||||
|
||||
recipe_file = os.path.join(recipes_dir, recipe_file)
|
||||
with open(recipe_file, "w") as f:
|
||||
f.write(recipe_src)
|
||||
|
||||
_run_recipe_in_hosts(recipe_file, recipes_dir, hosts)
|
||||
return True
|
||||
|
||||
|
||||
def _run_recipe_local(recipe_file):
|
||||
if recipe_file.endswith('.py'):
|
||||
util.run_command("python3 {0}".format(recipe_file))
|
||||
else:
|
||||
util.run_command("bash -f {0}".format(recipe_file))
|
||||
|
||||
|
||||
def _run_recipe_in_hosts(recipe_file, recipes_dir, _hosts):
|
||||
hosts = set(_hosts)
|
||||
ssh = SshHandler.get()
|
||||
|
||||
if util.has_localhost(hosts):
|
||||
_run_recipe_local(recipe_file)
|
||||
util.remove_localhost(hosts)
|
||||
|
||||
for host in hosts:
|
||||
try:
|
||||
ssh.transfer_file(recipe_file, recipes_dir, host)
|
||||
ssh.run_recipe(recipe_file, host)
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
|
||||
def get_all_hosts():
|
||||
conf = Controller.get().CONF
|
||||
hosts = set()
|
||||
hosts.update(set(conf["CONFIG_COMPUTE_HOSTS"].split(",")))
|
||||
hosts.add(conf["CONFIG_CONTROLLER_HOST"])
|
||||
hosts.add(conf["CONFIG_AMQP_HOST"])
|
||||
hosts.add(conf["CONFIG_MARIADB_HOST"])
|
||||
hosts.add(conf["CONFIG_MONGODB_HOST"])
|
||||
|
||||
return hosts
|
||||
|
||||
|
||||
def generate_conf_file(conf_file):
|
||||
""" create defaults.conf file """
|
||||
conf = Controller.get().CONF
|
||||
config_file = configparser.RawConfigParser()
|
||||
config_file.optionxform = str
|
||||
dir_name = os.path.dirname(conf_file)
|
||||
|
||||
if not os.path.isdir(dir_name):
|
||||
os.makedirs(dir_name)
|
||||
|
||||
config_file.add_section("general")
|
||||
for key in conf.keys():
|
||||
config_file.set("general", key, '{0}'.format(conf[key]))
|
||||
|
||||
with open(conf_file, 'w') as f:
|
||||
config_file.write(f)
|
||||
|
||||
|
||||
def copy_resources():
|
||||
_copy_resources_to_hosts(get_all_hosts())
|
||||
return True
|
||||
|
||||
|
||||
def _copy_resources_local():
|
||||
resources_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
modules_src = "{0}/modules".format(resources_dir)
|
||||
common_src = "{0}/common".format(resources_dir)
|
||||
|
||||
modules_dst = "{0}/modules".format(__recipes_directory)
|
||||
common_dst = "{0}/common".format(__recipes_directory)
|
||||
conf_file = "{0}/defaults.conf".format(__recipes_directory)
|
||||
|
||||
generate_conf_file(conf_file)
|
||||
shutil.copytree(modules_src, modules_dst)
|
||||
shutil.copytree(common_src, common_dst)
|
||||
|
||||
|
||||
def _copy_resources_to_hosts(_hosts):
|
||||
try:
|
||||
SshHandler.get().test_hosts(_hosts)
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
hosts = set(_hosts)
|
||||
ssh = SshHandler.get()
|
||||
resources_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
modules_dir = "{0}/modules".format(resources_dir)
|
||||
common_dir = "{0}/common".format(resources_dir)
|
||||
conf_file = "{0}/defaults.conf".format(__recipes_directory)
|
||||
|
||||
if util.has_localhost(hosts):
|
||||
_copy_resources_local()
|
||||
|
||||
util.remove_localhost(hosts)
|
||||
|
||||
if not os.path.isfile(conf_file):
|
||||
generate_conf_file(conf_file)
|
||||
|
||||
""" Copy modules and conf to hosts """
|
||||
for host in hosts:
|
||||
try:
|
||||
ssh.transfer_file(modules_dir, __recipes_directory, host)
|
||||
ssh.transfer_file(common_dir, __recipes_directory, host)
|
||||
ssh.transfer_file(conf_file, __recipes_directory, host)
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def get_logs():
|
||||
SshHandler.get().get_logs(get_all_hosts())
|
||||
|
||||
|
||||
def get_template(template):
|
||||
directory = "{0}/{1}".format(os.path.dirname(
|
||||
os.path.realpath(__file__)), "templates")
|
||||
if not template.endswith(".sh"):
|
||||
template = template + ".py"
|
||||
template = os.path.join(directory, template)
|
||||
source = "\n{0} {1} {0}\n".format("#" * 5, template)
|
||||
with open(template, 'r') as f:
|
||||
source += f.read()
|
||||
source += "\n{0}\n".format("#" * 60)
|
||||
return source
|
||||
|
||||
raise Exception("cannot load {0} template".format(template))
|
||||
|
||||
|
||||
def generate_random_pw():
|
||||
return binascii.b2a_hex(os.urandom(10)).decode("utf-8")
|
||||
|
||||
|
||||
def generate_ssh_keys(output):
|
||||
util.run_command("ssh-keygen -b 4096 -f {0} -a 500 -N ''"
|
||||
.format(output))
|
||||
|
||||
|
||||
def setup_debugging(debug):
|
||||
controller.DEBUG = debug
|
||||
util.setup_debugging(debug, is_remote_host=False)
|
||||
@@ -0,0 +1,62 @@
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Alberto Murillo <alberto.murillo.silva@intel.com>
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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 ipaddress
|
||||
import os
|
||||
import socket
|
||||
|
||||
|
||||
def y_or_n(value):
|
||||
if not value.lower() in ("n", "y"):
|
||||
raise ValueError("please set 'y' or 'n'")
|
||||
|
||||
|
||||
def true_or_false(value):
|
||||
if not value.lower() in ("true", "false"):
|
||||
raise ValueError("please set 'True' or 'False'")
|
||||
|
||||
|
||||
def ip_or_hostname(value):
|
||||
for v in value.split(","):
|
||||
try:
|
||||
ipaddress.ip_address(v)
|
||||
except ValueError:
|
||||
socket.gethostbyname(v)
|
||||
|
||||
|
||||
def cidr(value):
|
||||
ip = ipaddress.ip_network(value)
|
||||
if not ip:
|
||||
raise ValueError("Invalid cidr")
|
||||
|
||||
|
||||
def file(value):
|
||||
value = os.path.expanduser(value)
|
||||
if not os.path.exists(value):
|
||||
raise ValueError("file {0} not found".format(value))
|
||||
|
||||
|
||||
def not_empty(value):
|
||||
if not value.strip():
|
||||
raise ValueError("empty value")
|
||||
|
||||
|
||||
def digit(value):
|
||||
if not value.isdigit():
|
||||
raise ValueError("{0} is not a digit".format(value))
|
||||
@@ -0,0 +1,5 @@
|
||||
pbr # Apache-2.0
|
||||
ipaddress # Python-2.0
|
||||
netifaces # MIT
|
||||
paramiko # LGPL-2.1
|
||||
sphinx # BSD-2-Clause
|
||||
@@ -0,0 +1,55 @@
|
||||
[metadata]
|
||||
name = clearstack
|
||||
summary = Tool for set up an OpenStack environment
|
||||
description-file =
|
||||
README.rst
|
||||
author = Alberto Murillo, Julio Montes, Obed Muñoz, Victor Morales
|
||||
home-page =
|
||||
classifier =
|
||||
Environment :: OpenStack
|
||||
Intended Audience :: Information Technology
|
||||
Intended Audience :: System Administrators
|
||||
License :: OSI Approved :: Apache Software License
|
||||
Operating System :: POSIX :: Linux
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3.3
|
||||
|
||||
[files]
|
||||
packages =
|
||||
clearstack
|
||||
|
||||
[global]
|
||||
setup-hooks =
|
||||
pbr.hooks.setup_hook
|
||||
|
||||
[entry_points]
|
||||
console_scripts =
|
||||
clearstack = clearstack.shell:main
|
||||
|
||||
[build_sphinx]
|
||||
source-dir = doc/source
|
||||
build-dir = doc/build
|
||||
all_files = 1
|
||||
|
||||
[pbr]
|
||||
warnerrors = True
|
||||
|
||||
[upload_sphinx]
|
||||
upload-dir = doc/build/html
|
||||
|
||||
[compile_catalog]
|
||||
directory = clearstack/locale
|
||||
domain = clearstack
|
||||
|
||||
[update_catalog]
|
||||
domain = clearstack
|
||||
output_dir = clearstack/locale
|
||||
input_file = clearstack/locale/clearstack.pot
|
||||
|
||||
[extract_messages]
|
||||
keywords = _ gettext ngettext l_ lazy_gettext
|
||||
mapping_file = babel.cfg
|
||||
output_file = clearstack/locale/clearstack.pot
|
||||
|
||||
[wheel]
|
||||
universal = 1
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (c) 2015 Intel Corporation
|
||||
#
|
||||
# Author: Julio Montes <julio.montes@intel.com>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
|
||||
import setuptools
|
||||
|
||||
# In python < 2.7.4, a lazy loading of package `pbr` will break
|
||||
# setuptools if some other modules registered functions in `atexit`.
|
||||
# solution from: http://bugs.python.org/issue15881#msg170215
|
||||
try:
|
||||
import multiprocessing # noqa
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['pbr'],
|
||||
pbr=True,
|
||||
packages=['clearstack'],
|
||||
package_dir={'clearstack': 'clearstack'},
|
||||
scripts=['clearstack/templates/pre_compute.sh',
|
||||
'clearstack/templates/pre_controller.sh']
|
||||
)
|
||||
@@ -0,0 +1,4 @@
|
||||
coverage>=3.6
|
||||
flake8>=2.2.4
|
||||
testrepository>=0.0.18
|
||||
mock
|
||||
@@ -0,0 +1,41 @@
|
||||
[tox]
|
||||
minversion = 1.6
|
||||
skipsdist = True
|
||||
envlist = py34,pep8
|
||||
|
||||
[testenv]
|
||||
usedevelop = True
|
||||
install_command = pip install -U {opts} {packages}
|
||||
setenv = VIRTUAL_ENV={envdir}
|
||||
OS_STDOUT_NOCAPTURE=False
|
||||
OS_STDERR_NOCAPTURE=False
|
||||
|
||||
deps = -r{toxinidir}/requirements-py3.txt
|
||||
-r{toxinidir}/test-requirements-py3.txt
|
||||
commands = python setup.py testr --testr-args='{posargs}'
|
||||
|
||||
[testenv:pep8]
|
||||
commands =
|
||||
flake8
|
||||
|
||||
[testenv:venv]
|
||||
commands = {posargs}
|
||||
|
||||
[testenv:cover]
|
||||
commands = python setup.py testr --coverage --testr-args='{posargs}'
|
||||
|
||||
[tox:jenkins]
|
||||
downloadcache = ~/cache/pip
|
||||
|
||||
[testenv:debug]
|
||||
commands = oslo_debug_helper -t keystoneclient/tests {posargs}
|
||||
|
||||
[flake8]
|
||||
# H405: multi line docstring summary not separated with an empty line
|
||||
ignore = H405
|
||||
show-source = True
|
||||
exclude = .venv,.tox,dist,doc,*egg,build
|
||||
|
||||
[testenv:docs]
|
||||
commands=
|
||||
python setup.py build_sphinx
|
||||
Reference in New Issue
Block a user