def configure_logging(log_level, cli_args): root_logger = logging.getLogger().logger console_logger = logging.StreamHandler(sys.stdout) console_format = '%(levelname)s: @%(name)s : %(message)s' if sh.in_terminal(): console_logger.setFormatter(colorlog.TermFormatter(console_format)) else: console_logger.setFormatter(logging.Formatter(console_format)) root_logger.addHandler(console_logger) root_logger.setLevel(log_level)
def configure_logging(verbosity_level=1, dry_run=False): # Debug by default root_logger = logging.getLogger().logger root_logger.setLevel(logging.DEBUG) # Set our pretty logger console_logger = logging.StreamHandler(sys.stdout) console_format = '%(levelname)s: @%(name)s : %(message)s' if sh.in_terminal(): console_logger.setFormatter(colorlog.TermFormatter(console_format)) else: console_logger.setFormatter(logging.Formatter(console_format)) root_logger.addHandler(console_logger) # Adjust logging verbose level based on the command line switch. log_level = logging.INFO if verbosity_level >= 3: log_level = logging.DEBUG elif verbosity_level == 2 or dry_run: log_level = logging.AUDIT root_logger.setLevel(log_level)
# 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 urlparse import urlparse import re from devstack import log as logging from devstack import shell as sh LOG = logging.getLogger("devstack.downloader") GIT_EXT_REG = re.compile(r"^(.*?)\.git\s*$", re.IGNORECASE) GIT_MASTER_BRANCH = "master" CLONE_CMD = ["git", "clone"] CHECKOUT_CMD = ['git', 'checkout'] PULL_CMD = ['git', 'pull'] def _gitdownload(storewhere, uri, branch=None): dirsmade = list() if sh.isdir(storewhere): LOG.info("Updating code located at [%s]" % (storewhere)) cmd = CHECKOUT_CMD + [GIT_MASTER_BRANCH] sh.execute(*cmd, cwd=storewhere) cmd = PULL_CMD
# under the License. import json import re import tempfile from devstack import date from devstack import exceptions as excp from devstack import log as logging from devstack import runner as base from devstack import settings from devstack import shell as sh from devstack import trace as tr from devstack import utils LOG = logging.getLogger("devstack.runners.screen") # My running type RUN_TYPE = settings.RUN_TYPE_SCREEN TYPE = settings.RUN_TYPE_TYPE # Trace constants SCREEN_TEMPL = "%s.screen" ARGS = "ARGS" NAME = "NAME" SESSION_ID = 'SESSION_ID' # Screen session name SESSION_NAME = 'stack' SESSION_DEF_TITLE = SESSION_NAME SESSION_NAME_MTCHER = re.compile(r"^\s*([\d]+\.%s)\s*(.*)$" % (SESSION_NAME))
# not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import functools import pprint from devstack import log as logging # Very useful example ones... # See: http://wiki.python.org/moin/PythonDecoratorLibrary LOG = logging.getLogger("devstack.decorators") def log_debug(f): @functools.wraps(f) def wrapper(*args, **kargs): LOG.debug('%s(%s, %s) ->', f.func_name, str(args), str(kargs)) rv = f(*args, **kargs) LOG.debug("<- %s" % (pprint.pformat(rv, indent=2))) return rv return wrapper
import fileinput import getpass import grp import os import pwd import shutil import subprocess import sys import time from devstack import env from devstack import exceptions as excp from devstack import log as logging LOG = logging.getLogger("devstack.shell") ROOT_USER = "******" ROOT_USER_UID = 0 SUDO_UID = 'SUDO_UID' SUDO_GID = 'SUDO_GID' SHELL_QUOTE_REPLACERS = { "\"": "\\\"", "(": "\\(", ")": "\\)", "$": '\$', '`': '\`', } SHELL_WRAPPER = "\"%s\"" ROOT_PATH = os.sep DRYRUN_MODE = False DRY_RC = 0
from devstack import component as comp from devstack import date from devstack import exceptions from devstack import libvirt as virsh from devstack import log as logging from devstack import settings from devstack import shell as sh from devstack import utils from devstack.components import db from devstack.components import keystone #id TYPE = settings.NOVA LOG = logging.getLogger('devstack.components.nova') #special generated conf API_CONF = 'nova.conf' #normal conf PASTE_CONF = 'nova-api-paste.ini' PASTE_SOURCE_FN = 'api-paste.ini' POLICY_CONF = 'policy.json' LOGGING_SOURCE_FN = 'logging_sample.conf' LOGGING_CONF = "logging.conf" CONFIGS = [PASTE_CONF, POLICY_CONF, LOGGING_CONF] ADJUST_CONFIGS = [PASTE_CONF] #this is a special conf NET_INIT_CONF = 'nova-network-init.sh'
# 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 devstack import log as logging from devstack import packager as pack from devstack import shell as sh LOG = logging.getLogger("devstack.packaging.yum") # Root yum command YUM_CMD = ['yum'] # Tolerant is enabled since we might already have it installed/erased YUM_INSTALL = ["install", "-y", "-t"] YUM_REMOVE = ['erase', '-y', "-t"] # Yum separates its pkg names and versions with a dash VERSION_TEMPL = "%s-%s" class YumPackager(pack.Packager): def __init__(self, distro, keep_packages): pack.Packager.__init__(self, distro, keep_packages)
# # 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 optparse import IndentedHelpFormatter from optparse import OptionParser, OptionGroup from devstack.progs import actions from devstack import log as logging from devstack import version HELP_WIDTH = 80 LOG = logging.getLogger("devstack.opts") def _format_list(in_list): sorted_list = sorted(in_list) return "[" + ", ".join(sorted_list) + "]" def parse(): version_str = "%prog v" + version.version_string() help_formatter = IndentedHelpFormatter(width=HELP_WIDTH) parser = OptionParser(version=version_str, formatter=help_formatter) # Root options parser.add_option("-v",
import io from devstack import cfg from devstack import component as comp from devstack import log as logging from devstack import settings from devstack import shell as sh from devstack.components import db from devstack.components import keystone from devstack.image import creator #id TYPE = settings.GLANCE LOG = logging.getLogger("devstack.components.glance") #config files/sections API_CONF = "glance-api.conf" REG_CONF = "glance-registry.conf" API_PASTE_CONF = 'glance-api-paste.ini' REG_PASTE_CONF = 'glance-registry-paste.ini' SCRUB_CONF = 'glance-scrubber.conf' SCRUB_PASTE_CONF = 'glance-scrubber-paste.ini' LOGGING_CONF = "logging.conf" LOGGING_SOURCE_FN = 'logging.cnf.sample' POLICY_JSON = 'policy.json' CONFIGS = [API_CONF, REG_CONF, API_PASTE_CONF, REG_PASTE_CONF, POLICY_JSON, LOGGING_CONF, SCRUB_CONF, SCRUB_PASTE_CONF] READ_CONFIGS = [API_CONF, REG_CONF, API_PASTE_CONF,
# 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 devstack import log as logging LOG = logging.getLogger("devstack.environment") def get(): return dict(os.environ) def set(key, value): # This is really screwy, python is really odd in this area # See: from http://docs.python.org/library/os.html # Calling putenv() directly does not change os.environ, so it's better to modify os.environ. if key is not None: LOG.audit("Setting environment key %r to value %r" % (str(key), str(value))) os.environ[str(key)] = str(value)
from devstack import colorlog from devstack import exceptions as excp from devstack import log as logging from devstack import settings from devstack import shell as sh from devstack import version # The pattern will match either a comment to the EOL, or a # token to be subbed. The replacer will check which it got and # act accordingly. Note that we need the MULTILINE flag # for the comment checks to work in a string containing newlines PARAM_SUB_REGEX = re.compile(r"#.*$|%([\w\d]+?)%", re.MULTILINE) EXT_COMPONENT = re.compile(r"^\s*([\w-]+)(?:\((.*)\))?\s*$") MONTY_PYTHON_TEXT_RE = re.compile("([a-z0-9A-Z\?!.,'\"]+)") LOG = logging.getLogger("devstack.util") DEF_IP = "127.0.0.1" IP_LOOKER = '8.8.8.8' DEF_IP_VERSION = settings.IPV4 PRIVATE_OCTS = [] ALL_NUMS = re.compile(r"^\d+$") START_NUMS = re.compile(r"^(\d+)(\D+)") STAR_VERSION = 0 # Thx cowsay # See: http://www.nog.net/~tony/warez/cowsay.shtml COWS = dict() COWS['happy'] = r''' {header} \ {ear}__{ear} \ ({eye}{eye})\_______
# 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 devstack import component as comp from devstack import log as logging LOG = logging.getLogger("devstack.components.nova_client") class NovaClientUninstaller(comp.PythonUninstallComponent): def __init__(self, *args, **kargs): comp.PythonUninstallComponent.__init__(self, *args, **kargs) class NovaClientInstaller(comp.PythonInstallComponent): def __init__(self, *args, **kargs): comp.PythonInstallComponent.__init__(self, *args, **kargs) def _get_download_locations(self): places = list() places.append({ 'uri': ("git", "novaclient_repo"),
# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright (C) 2012 Yahoo! Inc. All Rights Reserved. # # 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 devstack import log as logging from devstack import settings LOG = logging.getLogger("devstack.cfg.helpers") def make_id(section, option): joinwhat = [] if section is not None: joinwhat.append(str(section)) if option is not None: joinwhat.append(str(option)) return "/".join(joinwhat)
import contextlib import json import os import re import tarfile import urllib2 import urlparse from devstack import downloader as down from devstack import log from devstack import shell as sh from devstack import utils from devstack.components import keystone LOG = log.getLogger("devstack.image.uploader") # Glance commands IMAGE_ADD = ['glance', 'add', '-A', '%TOKEN%', '--silent-upload', 'name="%NAME%"', 'is_public=true', 'container_format=%CONTAINER_FORMAT%', 'disk_format=%DISK_FORMAT%'] DETAILS_SHOW = ['glance', '-A', '%TOKEN%', 'details'] # Extensions that tarfile knows how to work with TAR_EXTS = ['.tgz', '.gzip', '.gz', '.bz2', '.tar'] # Used to attempt to produce a name for images (to see if we already have it) # And to use as the final name...
# # 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 devstack import component as comp from devstack import log as logging from devstack import shell as sh from devstack.components import nova LOG = logging.getLogger("devstack.components.novnc") # Where the application is really UTIL_DIR = 'utils' VNC_PROXY_APP = 'nova-novncproxy' APP_OPTIONS = { # This reaches into the nova configuration file # TODO can we stop that? VNC_PROXY_APP: ['--flagfile', '%NOVA_CONF%', '--web', '.'], } class NoVNCUninstaller(comp.PythonUninstallComponent): def __init__(self, *args, **kargs): comp.PythonUninstallComponent.__init__(self, *args, **kargs)
# License for the specific language governing permissions and limitations # under the License. import io from devstack import cfg from devstack import component as comp from devstack import log as logging from devstack import shell as sh from devstack.components import db from devstack.components import keystone from devstack.image import uploader LOG = logging.getLogger("devstack.components.glance") # Config files/sections API_CONF = "glance-api.conf" REG_CONF = "glance-registry.conf" API_PASTE_CONF = 'glance-api-paste.ini' REG_PASTE_CONF = 'glance-registry-paste.ini' SCRUB_CONF = 'glance-scrubber.conf' SCRUB_PASTE_CONF = 'glance-scrubber-paste.ini' LOGGING_CONF = "logging.conf" LOGGING_SOURCE_FN = 'logging.cnf.sample' POLICY_JSON = 'policy.json' CONFIGS = [ API_CONF, REG_CONF, API_PASTE_CONF, REG_PASTE_CONF, POLICY_JSON, LOGGING_CONF, SCRUB_CONF, SCRUB_PASTE_CONF ]
# 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 time import re from devstack import log as logging from devstack import shell as sh from devstack import utils LOG = logging.getLogger("install.screen") SCREEN_MAKE = ['screen', '-d', '-m', '-S', '%NAME%', '-t', '%NAME%'] LIST_CMD = ['screen', '-list'] KILL_CMD = ['screen', '-r', "%ENTRY%", '-X', 'kill'] QUIT_CMD = ['screen', '-r', "%ENTRY%", '-X', 'kill'] NAME_POSTFIX = ".devstack" RUN_TYPE = "SCREEN" TYPE = "TYPE" class ScreenRunner(object): def __init__(self): pass def stop(self, name, *args, **kargs):
# # 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 abc from devstack import decorators from devstack import log as logging from devstack import utils LOG = logging.getLogger("devstack.packager") class Packager(object): __meta__ = abc.ABCMeta @decorators.log_debug def __init__(self, distro): self.distro = distro @abc.abstractmethod def install(self, pkg): pass @abc.abstractmethod def _remove(self, pkg):
# 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 urlparse import urlunparse import re from devstack import date from devstack import env from devstack import log as logging from devstack import shell as sh from devstack import utils from devstack.components import keystone LOG = logging.getLogger('devstack.env_rc') # General extraction cfg keys + sections CFG_MAKE = { 'FLAT_INTERFACE': ('nova', 'flat_interface'), 'HOST_IP': ('host', 'ip'), } # General password keys PASSWORDS_MAKES = { 'ADMIN_PASSWORD': '******', 'SERVICE_PASSWORD': '******', 'RABBIT_PASSWORD': '******', 'SERVICE_TOKEN': 'service_token', 'MYSQL_PASSWORD': '******', }
# 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 from devstack import component as comp from devstack import log as logging from devstack import shell as sh from devstack import utils LOG = logging.getLogger("devstack.components.swift") # Swift has alot of config files! SWIFT_CONF = 'swift.conf' PROXY_SERVER_CONF = 'proxy-server.conf' ACCOUNT_SERVER_CONF = 'account-server.conf' CONTAINER_SERVER_CONF = 'container-server.conf' OBJECT_SERVER_CONF = 'object-server.conf' RSYNC_CONF = 'rsyncd.conf' SYSLOG_CONF = 'rsyslog.conf' SWIFT_MAKERINGS = 'swift-remakerings' SWIFT_STARTMAIN = 'swift-startmain' SWIFT_INIT = 'swift-init' SWIFT_IMG = 'drives/images/swift.img' DEVICE_PATH = 'drives/sdb1' CONFIGS = [
import getpass import grp import os.path import pwd import shutil import subprocess import fileinput from devstack import env from devstack import exceptions as excp from devstack import log as logging MKPW_CMD = ["openssl", 'rand', '-hex'] PASS_ASK_ENV = 'PASS_ASK' LOG = logging.getLogger("devstack.shell") ROOT_USER = "******" ROOT_USER_UID = 0 SUDO_UID = 'SUDO_UID' SUDO_GID = 'SUDO_GID' #root context guard class Rooted(object): def __init__(self, run_as_root): self.root_mode = run_as_root self.engaged = False def __enter__(self): if self.root_mode and not got_root(): root_mode()
# # 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 devstack import component as comp from devstack import exceptions as excp from devstack import log as logging from devstack import shell as sh from devstack import utils import abc LOG = logging.getLogger("devstack.components.db") # Need to reset pw to blank since this distributions don't seem to # always reset it when u uninstall the db RESET_BASE_PW = '' # Links about how to reset if we fail to set the PW SQL_RESET_PW_LINKS = [ 'https://help.ubuntu.com/community/MysqlPasswordReset', 'http://dev.mysql.com/doc/refman/5.0/en/resetting-permissions.html', ] # Used as a generic error message BASE_ERROR = 'Currently we do not know how to %r for database type %r' # PW keys we warm up so u won't be prompted later
# # 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 devstack import component as comp from devstack import exceptions as excp from devstack import log as logging from devstack import shell as sh from devstack import utils LOG = logging.getLogger("devstack.components.horizon") # Actual dir names ROOT_HORIZON = 'horizon' ROOT_DASH = 'openstack_dashboard' # Name used for python install trace HORIZON_NAME = ROOT_HORIZON DASH_NAME = 'dashboard' # Config files messed with HORIZON_PY_CONF = "horizon_settings.py" HORIZON_PY_CONF_TGT = ['local', 'local_settings.py'] HORIZON_APACHE_CONF = '000-default' CONFIGS = [HORIZON_PY_CONF, HORIZON_APACHE_CONF]
# # 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 contextlib from devstack import exceptions as excp from devstack import importer from devstack import log as logging from devstack import shell as sh from devstack import utils LOG = logging.getLogger('devstack.libvirt') # See: http://libvirt.org/uri.html LIBVIRT_PROTOCOL_MAP = { 'qemu': "qemu:///system", 'kvm': "qemu:///system", 'xen': 'xen:///', 'uml': 'uml:///system', 'lxc': 'lxc:///', } # Status is either dead or alive! _DEAD = 'DEAD' _ALIVE = 'ALIVE' # Type that should always work
# a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import functools import pprint from devstack import log as logging # Very useful example ones... # See: http://wiki.python.org/moin/PythonDecoratorLibrary LOG = logging.getLogger("devstack.decorators") def log_debug(f): @functools.wraps(f) def wrapper(*args, **kargs): LOG.debug('%s(%s, %s) ->', f.func_name, str(args), str(kargs)) rv = f(*args, **kargs) LOG.debug("<- %s" % (pprint.pformat(rv, indent=2))) return rv return wrapper
# under the License. import io from devstack import cfg from devstack import component as comp from devstack import log as logging from devstack import settings from devstack import shell as sh from devstack import utils from devstack.components import db #id TYPE = settings.QUANTUM LOG = logging.getLogger("devstack.components.quantum") #vswitch pkgs VSWITCH_PLUGIN = 'openvswitch' PKG_VSWITCH = "quantum-openvswitch.json" V_PROVIDER = "quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPlugin" #config files (some only modified if running as openvswitch) PLUGIN_CONF = "plugins.ini" QUANTUM_CONF = 'quantum.conf' PLUGIN_LOC = ['etc'] AGENT_CONF = 'ovs_quantum_plugin.ini' AGENT_LOC = ["etc", "quantum", "plugins", "openvswitch"] AGENT_BIN_LOC = ["quantum", "plugins", "openvswitch", 'agent'] CONFIG_FILES = [PLUGIN_CONF, AGENT_CONF]
# License for the specific language governing permissions and limitations # under the License. import glob import platform import re import yaml from devstack import decorators from devstack import importer from devstack import log as logging from devstack import settings from devstack import shell as sh LOG = logging.getLogger('devstack.distro') class Distro(object): @classmethod def load_all(cls, path=settings.STACK_DISTRO_DIR): """Returns a list of the known distros.""" results = [] input_files = glob.glob(sh.joinpths(path, '*.yaml')) if not input_files: raise RuntimeError( 'Did not find any distro definition files in %s' % path) for fn in input_files: cls_kvs = None
# 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 devstack import exceptions as excp from devstack import log as logging from devstack import shell as sh LOG = logging.getLogger("devstack.pip") PIP_UNINSTALL_CMD_OPTS = ['-y', '-q'] PIP_INSTALL_CMD_OPTS = ['-q'] def _make_pip_name(name, version): if version is None: return str(name) return "%s==%s" % (name, version) def install(pip, distro): name = pip['name'] root_cmd = distro.get_command_config('pip') LOG.audit("Installing python package %r using pip command %s" % (name, root_cmd))
# 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 devstack import decorators from devstack import log as logging from devstack import utils LOG = logging.getLogger("devstack.packager") class Packager(object): @decorators.log_debug def __init__(self, distro, keep_packages): self.distro = distro self.keep_packages = keep_packages def install(self, pkg): raise NotImplementedError() def remove(self, pkg): if self.keep_packages: return False
# under the License. import glob import platform import re import shlex import yaml from devstack import decorators from devstack import importer from devstack import log as logging from devstack import settings from devstack import shell as sh LOG = logging.getLogger('devstack.distro') class Distro(object): @classmethod def load_all(cls, path=settings.STACK_DISTRO_DIR): """Returns a list of the known distros.""" results = [] input_files = glob.glob(sh.joinpths(path, '*.yaml')) if not input_files: raise RuntimeError( 'Did not find any distro definition files in %r' % path) for fn in input_files: cls_kvs = None filename = sh.abspth(fn) LOG.audit("Attempting to load distro definition from %r" %
# 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 devstack import log as logging from devstack import packager as pack from devstack import shell as sh LOG = logging.getLogger("devstack.packaging.apt") # Base apt commands APT_GET = ['apt-get'] APT_PURGE = ["purge", "-y"] APT_REMOVE = ["remove", "-y"] APT_INSTALL = ["install", "-y"] APT_AUTOREMOVE = ['autoremove', '-y'] # Should we use remove or purge? APT_DO_REMOVE = APT_PURGE # Make sure its non-interactive # http://awaseconfigurations.wordpress.com/tag/debian_frontend/ ENV_ADDITIONS = {'DEBIAN_FRONTEND': 'noninteractive'}
# 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 devstack import component as comp from devstack import log as logging LOG = logging.getLogger("devstack.components.keystone_client") class KeyStoneClientUninstaller(comp.PythonUninstallComponent): def __init__(self, *args, **kargs): comp.PythonUninstallComponent.__init__(self, *args, **kargs) class KeyStoneClientInstaller(comp.PythonInstallComponent): def __init__(self, *args, **kargs): comp.PythonInstallComponent.__init__(self, *args, **kargs) def _get_download_locations(self): places = list() places.append({ 'uri': ("git", "keystoneclient_repo"),
# 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 devstack import log as logging LOG = logging.getLogger("devstack.environment") def get(): return dict(os.environ) def set(k, v): #this is really screwy, python is really odd in this area #from http://docs.python.org/library/os.html if k is not None: LOG.debug("Setting environment key [%s] to value [%s]" % (k, v)) os.environ[str(k)] = str(v) def get_key(key, default_value=None):
# License for the specific language governing permissions and limitations # under the License. import re import ConfigParser from devstack import date from devstack import env from devstack import exceptions as excp from devstack import log as logging from devstack import settings from devstack import shell as sh from devstack import utils LOG = logging.getLogger("devstack.cfg") PW_TMPL = "Enter a password for %s: " ENV_PAT = re.compile(r"^\s*\$\{([\w\d]+):\-(.*)\}\s*$") SUB_MATCH = re.compile(r"(?:\$\(([\w\d]+):([\w\d]+))\)") CACHE_MSG = "(value will now be internally cached)" DEF_PW_MSG = "[or press enter to get a generated one]" PW_PROMPTS = { 'horizon_keystone_admin': "Enter a password to use for horizon and keystone (20 chars or less) %s: " % (DEF_PW_MSG), 'service_token': 'Enter a token to use for the service admin token %s: ' % (DEF_PW_MSG), 'sql': 'Enter a password to use for your sql database user %s: ' % (DEF_PW_MSG), 'rabbit': 'Enter a password to use for your rabbit user %s: ' % (DEF_PW_MSG), 'old_sql': "Please enter your current mysql password so we that can reset it for next time: ", } class StackConfigParser(ConfigParser.RawConfigParser):
# License for the specific language governing permissions and limitations # under the License. """Platform-specific logic for Ubunutu Oneiric components. """ import tempfile import time from devstack.components import db from devstack import log as logging from devstack import shell as sh from devstack import utils from devstack.packaging import apt LOG = logging.getLogger(__name__) class DBInstaller(db.DBInstaller): def _configure_db_confs(self): LOG.info("Fixing up %r mysql configs.", self.distro.name) fc = sh.load_file('/etc/mysql/my.cnf') lines = fc.splitlines() new_lines = list() for line in lines: if line.startswith('bind-address'): line = 'bind-address = %s' % ('0.0.0.0') new_lines.append(line) fc = utils.joinlinesep(*new_lines) with sh.Rooted(True):
import termcolor from devstack import exceptions as excp from devstack import log as logging from devstack import settings from devstack import shell as sh from devstack import version # The pattern will match either a comment to the EOL, or a # token to be subbed. The replacer will check which it got and # act accordingly. Note that we need the MULTILINE flag # for the comment checks to work in a string containing newlines PARAM_SUB_REGEX = re.compile(r"#.*$|%([\w\d]+?)%", re.MULTILINE) EXT_COMPONENT = re.compile(r"^\s*([\w-]+)(?:\((.*)\))?\s*$") MONTY_PYTHON_TEXT_RE = re.compile("([a-z0-9A-Z\?!.,'\"]+)") LOG = logging.getLogger("devstack.util") DEF_IP = "127.0.0.1" IP_LOOKER = '8.8.8.8' DEF_IP_VERSION = settings.IPV4 PRIVATE_OCTS = [] ALL_NUMS = re.compile(r"^\d+$") START_NUMS = re.compile(r"^(\d+)(\D+)") STAR_VERSION = 0 #thx cowsay COWS = dict() COWS['happy'] = r''' {header} \ {ear}__{ear} \ ({eye}{eye})\_______ (__)\ )\/\
# 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 devstack import log as logging from devstack import settings LOG = logging.getLogger("devstack.cfg.helpers") def make_id(section, option): joinwhat = [] if section is not None: joinwhat.append(str(section)) if option is not None: joinwhat.append(str(option)) return "/".join(joinwhat) def fetch_run_type(config): run_type = config.getdefaulted("default", "run_type", settings.RUN_TYPE_DEF) return run_type.upper()
# License for the specific language governing permissions and limitations # under the License. from urlparse import urlunparse import re from devstack import date from devstack import env from devstack import log as logging from devstack import settings from devstack import shell as sh from devstack import utils from devstack.components import keystone LOG = logging.getLogger('devstack.env_rc') # General extraction cfg keys + sections CFG_MAKE = { 'FLAT_INTERFACE': ('nova', 'flat_interface'), 'HOST_IP': ('host', 'ip'), } # General password keys PASSWORDS_MAKES = { 'ADMIN_PASSWORD': '******', 'SERVICE_PASSWORD': '******', 'RABBIT_PASSWORD': '******', 'SERVICE_TOKEN': 'service_token', 'MYSQL_PASSWORD': '******', }
# # 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 tempfile import TemporaryFile import time from devstack import log as logging from devstack import packager as pack from devstack import settings from devstack import shell as sh LOG = logging.getLogger("devstack.packaging.apt") #base apt commands APT_GET = ['apt-get'] APT_PURGE = ["purge", "-y"] APT_REMOVE = ["remove", "-y"] APT_INSTALL = ["install", "-y"] APT_AUTOREMOVE = ['autoremove', '-y'] #should we use remove or purge? APT_DO_REMOVE = APT_PURGE #make sure its non-interactive ENV_ADDITIONS = {'DEBIAN_FRONTEND': 'noninteractive'} #apt separates its pkg names and versions with a equal sign
# 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 io from devstack import cfg from devstack import component as comp from devstack import log as logging from devstack import shell as sh from devstack import utils from devstack.components import db LOG = logging.getLogger("devstack.components.melange") # This db will be dropped then created DB_NAME = 'melange' # Subdirs of the checkout/download BIN_DIR = 'bin' # Basic configs ROOT_CONF = 'melange.conf.sample' ROOT_CONF_REAL_NAME = 'melange.conf' CONFIGS = [ROOT_CONF] CFG_LOC = ['etc', 'melange'] # Sensible defaults DEF_CIDR_RANGE = 'FE-EE-DD-00-00-00/24'
import contextlib import json import os import re import tarfile import urllib2 import urlparse from devstack import downloader as down from devstack import log from devstack import shell as sh from devstack import utils from devstack.components import keystone LOG = log.getLogger("devstack.image.creator") # These are used when looking inside archives KERNEL_FN_MATCH = re.compile(r"(.*)vmlinuz$", re.I) RAMDISK_FN_MATCH = re.compile(r"(.*)initrd$", re.I) IMAGE_FN_MATCH = re.compile(r"(.*)img$", re.I) # Glance commands KERNEL_ADD = [ 'glance', 'add', '-A', '%TOKEN%', '--silent-upload', 'name="%IMAGE_NAME%-kernel"', 'is_public=true', 'container_format=aki', 'disk_format=aki' ] INITRD_ADD = [ 'glance', 'add', '-A', '%TOKEN%', '--silent-upload', 'name="%IMAGE_NAME%-ramdisk"', 'is_public=true', 'container_format=ari',
import io import re import iniparse from devstack import cfg_helpers from devstack import date from devstack import env from devstack import exceptions as excp from devstack import log as logging from devstack import settings from devstack import shell as sh from devstack import utils LOG = logging.getLogger("devstack.cfg") ENV_PAT = re.compile(r"^\s*\$\{([\w\d]+):\-(.*)\}\s*$") SUB_MATCH = re.compile(r"(?:\$\(([\w\d]+):([\w\d]+))\)") CACHE_MSG = "(value will now be internally cached)" def get_config(cfg_fn=None): if not cfg_fn: cfg_fn = sh.canon_path(settings.STACK_CONFIG_LOCATION) return StackConfigParser(fns=[cfg_fn]) class IgnoreMissingConfigParser(iniparse.RawConfigParser): DEF_INT = 0 DEF_FLOAT = 0.0 DEF_BOOLEAN = False
# 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 io from devstack import cfg from devstack import component as comp from devstack import log as logging from devstack import shell as sh from devstack import utils from devstack.components import db LOG = logging.getLogger("devstack.components.quantum") # Openvswitch special settings VSWITCH_PLUGIN = 'openvswitch' V_PROVIDER = "quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPlugin" # Config files (some only modified if running as openvswitch) PLUGIN_CONF = "plugins.ini" QUANTUM_CONF = 'quantum.conf' PLUGIN_LOC = ['etc'] AGENT_CONF = 'ovs_quantum_plugin.ini' AGENT_LOC = ["etc", "quantum", "plugins", "openvswitch"] AGENT_BIN_LOC = ["quantum", "plugins", "openvswitch", 'agent'] CONFIG_FILES = [PLUGIN_CONF, AGENT_CONF] # This db will be dropped and created
from devstack.components import horizon from devstack.components import keystone from devstack.components import keystone_client from devstack.components import nova from devstack.components import nova_client from devstack.components import novnc from devstack.components import openstack_x from devstack.components import quantum from devstack.components import quantum_client from devstack.components import rabbit from devstack.components import swift from devstack.packaging import apt from devstack.packaging import yum LOG = logging.getLogger("devstack.progs.actions") #this map controls which distro has #which package management class _PKGR_MAP = { settings.DEBIAN7: apt.AptPackager, settings.UBUNTU11: apt.AptPackager, settings.RHEL6: yum.YumPackager, } # This is used to map an action to a useful string for # the welcome display _WELCOME_MAP = { settings.INSTALL: "INSTALLER", settings.UNINSTALL: "UNINSTALLER", settings.START: "STARTER",
import ConfigParser import json import os import tarfile import tempfile import urllib import urllib2 from devstack import log from devstack import shell from devstack import utils from devstack.components import keystone LOG = log.getLogger("devstack.image.creator") class Image(object): KERNEL_FORMAT = ['glance', 'add', '-A', '%TOKEN%', '--silent-upload', \ 'name="%IMAGE_NAME%-kernel"', 'is_public=true', 'container_format=aki', \ 'disk_format=aki'] INITRD_FORMAT = ['glance', 'add', '-A', '%TOKEN%', '--silent-upload', \ 'name="%IMAGE_NAME%-ramdisk"', 'is_public=true', 'container_format=ari', \ 'disk_format=ari'] IMAGE_FORMAT = ['glance', 'add', '-A', '%TOKEN%', '--silent-upload', 'name="%IMAGE_NAME%.img"', 'is_public=true', 'container_format=ami', 'disk_format=ami', \ 'kernel_id=%KERNEL_ID%', 'ramdisk_id=%INITRD_ID%']
from devstack import cfg_helpers from devstack import downloader as down from devstack import exceptions as excp from devstack import importer from devstack import log as logging from devstack import pip from devstack import settings from devstack import shell as sh from devstack import trace as tr from devstack import utils from devstack.runners import fork from devstack.runners import upstart from devstack.runners import screen LOG = logging.getLogger("devstack.component") # How we actually setup and unsetup python PY_INSTALL = ['python', 'setup.py', 'develop'] PY_UNINSTALL = ['python', 'setup.py', 'develop', '--uninstall'] # Runtime status constants (return by runtime status) # TODO: move... STATUS_UNKNOWN = "unknown" STATUS_STARTED = "started" STATUS_STOPPED = "stopped" # Which run types to which runner class RUNNER_CLS_MAPPING = { settings.RUN_TYPE_FORK: fork.ForkRunner, settings.RUN_TYPE_UPSTART: upstart.UpstartRunner,
# 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 yaml from devstack import decorators from devstack import exceptions as excp from devstack import log as logging from devstack import shell as sh LOG = logging.getLogger("devstack.persona") class Persona(object): @classmethod def load_file(cls, fn): persona_fn = sh.abspth(fn) LOG.audit("Loading persona from file [%s]", persona_fn) cls_kvs = None try: with open(persona_fn, "r") as fh: cls_kvs = yaml.load(fh.read()) except (IOError, yaml.YAMLError) as err: LOG.warning('Could not load persona definition from %s: %s', persona_fn, err)
HORIZON_APACHE_TGT = ['/', 'etc', 'apache2', 'sites-enabled', '000-default'] CONFIGS = [HORIZON_PY_CONF, HORIZON_APACHE_CONF] DB_SYNC_CMD = ['python', 'manage.py', 'syncdb'] BLACKHOLE_DIR = '.blackhole' #hopefully this will be distro independent ?? APACHE_RESTART_CMD = ['service', 'apache2', 'restart'] APACHE_START_CMD = ['service', 'apache2', 'start'] APACHE_STOP_CMD = ['service', 'apache2', 'stop'] APACHE_STATUS_CMD = ['service', 'apache2', 'status'] #users which apache may not like starting as BAD_APACHE_USERS = ['root'] LOG = logging.getLogger("devstack.components.horizon") class HorizonUninstaller(comp.PythonUninstallComponent): def __init__(self, *args, **kargs): comp.PythonUninstallComponent.__init__(self, TYPE, *args, **kargs) class HorizonInstaller(comp.PythonInstallComponent): def __init__(self, *args, **kargs): comp.PythonInstallComponent.__init__(self, TYPE, *args, **kargs) self.git_loc = self.cfg.get("git", "horizon_repo") self.git_branch = self.cfg.get("git", "horizon_branch") self.horizon_dir = sh.joinpths(self.appdir, ROOT_HORIZON) self.dash_dir = sh.joinpths(self.appdir, ROOT_DASH)
from urlparse import urlunparse from devstack import cfg from devstack import component as comp from devstack import date from devstack import exceptions from devstack import libvirt as lv from devstack import log as logging from devstack import shell as sh from devstack import utils from devstack.components import db from devstack.components import keystone from devstack.components import rabbit LOG = logging.getLogger('devstack.components.nova') # Special generated conf API_CONF = 'nova.conf' # How we reference some config files (in applications) CFG_FILE_OPT = '--config-file' # Normal conf PASTE_CONF = 'nova-api-paste.ini' PASTE_SOURCE_FN = 'api-paste.ini' POLICY_CONF = 'policy.json' LOGGING_SOURCE_FN = 'logging_sample.conf' LOGGING_CONF = "logging.conf" CONFIGS = [PASTE_CONF, POLICY_CONF, LOGGING_CONF] ADJUST_CONFIGS = [PASTE_CONF]
""" import re from devstack import log as logging from devstack import shell as sh from devstack import utils from devstack.components import db from devstack.components import horizon from devstack.components import nova from devstack.components import rabbit from devstack.packaging import yum LOG = logging.getLogger(__name__) SOCKET_CONF = "/etc/httpd/conf.d/wsgi-socket-prefix.conf" HTTPD_CONF = '/etc/httpd/conf/httpd.conf' # See: http://wiki.libvirt.org/page/SSHPolicyKitSetup # FIXME: take from distro config?? LIBVIRT_POLICY_FN = "/etc/polkit-1/localauthority/50-local.d/50-libvirt-access.pkla" LIBVIRT_POLICY_CONTENTS = """ [libvirt Management Access] Identity={idents} Action=org.libvirt.unix.manage ResultAny=yes ResultInactive=yes ResultActive=yes """
# 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 tempfile import TemporaryFile from devstack import component as comp from devstack import log as logging from devstack import settings from devstack import shell as sh #id TYPE = settings.RABBIT LOG = logging.getLogger("devstack.components.rabbit") #hopefully these are distro independent.. START_CMD = ['service', "rabbitmq-server", "start"] STOP_CMD = ['service', "rabbitmq-server", "stop"] STATUS_CMD = ['service', "rabbitmq-server", "status"] RESTART_CMD = ['service', "rabbitmq-server", "restart"] PWD_CMD = ['rabbitmqctl', 'change_password', 'guest'] #the pkg json files rabbit mq server requires for installation REQ_PKGS = ['rabbitmq.json'] #default password RESET_BASE_PW = '' #how long we wait for rabbitmq to start up before doing commands on it
# 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 operator import os.path import re import sys from devstack import log as logging LOG = logging.getLogger("devstack.settings") # These also have meaning outside python, # ie in the pkg/pip listings so update there also! DEBIAN7 = "debian-wheezy" UBUNTU11 = "ubuntu-oneiric" RHEL6 = "rhel-6" # What this program is called PROG_NICE_NAME = "DEVSTACK" # These 2 identify the json post and pre install sections PRE_INSTALL = "pre-install" POST_INSTALL = "post-install" # Ip version constants for network ip detection
# # 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 urllib import progressbar from devstack import log as logging from devstack import shell as sh LOG = logging.getLogger("devstack.downloader") # Git master branch GIT_MASTER_BRANCH = "master" class Downloader(object): def __init__(self, uri, store_where): self.uri = uri self.store_where = store_where def download(self): raise NotImplementedError()
# under the License. import io from devstack import cfg from devstack import component as comp from devstack import log as logging from devstack import settings from devstack import shell as sh from devstack import utils from devstack.components import db #id TYPE = settings.MELANGE LOG = logging.getLogger("devstack.components.melange") #the pkg json files melange requires for installation REQ_PKGS = ['general.json', 'melange.json'] #this db will be dropped then created DB_NAME = 'melange' #subdirs of the checkout/download BIN_DIR = 'bin' #configs ROOT_CONF = 'melange.conf.sample' ROOT_CONF_REAL_NAME = 'melange.conf' CONFIGS = [ROOT_CONF] CFG_LOC = ['etc', 'melange']