Merge pull request #172 from harlowja/master

Allow packager to state when a package was already installed, make pip use the common base class and audit adjustments in shell logging. Fixing up to be in sync (again).
This commit is contained in:
Joshua Harlow 2012-04-19 22:29:56 -07:00
commit b91b595a60
17 changed files with 225 additions and 173 deletions

View File

@ -197,9 +197,6 @@ components:
running: devstack.components.horizon:HorizonRuntime
uninstall: devstack.components.horizon:HorizonUninstaller
packages:
- name: Django
removable: true
version: 1.3*
- name: django-registration
removable: true
version: 0.7*
@ -260,6 +257,9 @@ components:
- name: pyxattr
removable: true
version: 0.5*
pips:
- name: django
version: 1.4
keystone:
action_classes:
install: devstack.components.keystone:KeystoneInstaller

View File

@ -276,7 +276,7 @@ components:
- name: SQLAlchemy
version: 0.7.5
- name: django
version: 1.3.1
version: 1.4
- name: django-mailer
version: 0.1.0
- name: django-nose

View File

@ -238,9 +238,6 @@ components:
- name: python-dateutil
removable: true
version: 1.4*
- name: python-django
removable: true
version: 1.3*
- name: python-django-mailer
removable: true
version: 0.2*
@ -275,6 +272,8 @@ components:
removable: true
version: 1.0*
pips:
- name: django
version: 1.4
- name: django-nose-selenium
version: 0.7.3
- name: pycrypto

View File

@ -17,8 +17,10 @@
import weakref
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 packager
from devstack import pip
from devstack import settings
from devstack import shell as sh
@ -122,33 +124,13 @@ class ComponentBase(object):
return tr.TraceReader(tr.trace_fn(self.trace_dir, tr.IN_TRACE)).exists()
class PackageBasedComponentMixin(object):
"""Mix this into classes that need to manipulate
OS-level packages.
"""
PACKAGER_KEY_NAME = 'packager_name'
def __init__(self):
self.default_packager = self.distro.get_default_package_manager()
def get_packager(self, pkg_info):
if self.PACKAGER_KEY_NAME in pkg_info:
packager_name = pkg_info[self.PACKAGER_KEY_NAME]
LOG.debug('Loading custom package manager %r', packager_name)
packager = importer.import_entry_point(packager_name)(self.distro)
else:
LOG.debug('Using default package manager')
packager = self.default_packager
return packager
class PkgInstallComponent(ComponentBase, PackageBasedComponentMixin):
def __init__(self, *args, **kargs):
class PkgInstallComponent(ComponentBase):
def __init__(self, packager_factory, *args, **kargs):
ComponentBase.__init__(self, *args, **kargs)
PackageBasedComponentMixin.__init__(self)
self.tracewriter = tr.TraceWriter(tr.trace_fn(self.trace_dir,
tr.IN_TRACE))
self.packages = kargs.get('packages', list())
self.packager_factory = packager_factory
def _get_download_locations(self):
return list()
@ -207,46 +189,32 @@ class PkgInstallComponent(ComponentBase, PackageBasedComponentMixin):
pkg_list = list(self.packages)
for name in self.desired_subsystems:
if name in self.subsystem_info:
# Todo handle duplicates/version differences?
LOG.debug(
"Extending package list with packages for subsystem %r",
name)
subsystem_pkgs = self.subsystem_info[name].get('packages', [])
pkg_list.extend(subsystem_pkgs)
LOG.debug("Extending package list with packages for subsystem %r", name)
pkg_list.extend(self.subsystem_info[name].get('packages', []))
return pkg_list
def install(self):
LOG.debug('Preparing to install packages for %r', self.component_name)
pkgs = self._get_packages()
if pkgs:
pkg_names = set([p['name'] for p in pkgs])
utils.log_iterable(pkg_names, logger=LOG,
header="Setting up %s distribution packages" % (len(pkg_names)))
with utils.progress_bar(INSTALL_TITLE, len(pkgs)) as p_bar:
for (i, p) in enumerate(pkgs):
self.tracewriter.package_installed(p)
packager = self.get_packager(p)
packager.install(p)
p_bar.update(i + 1)
else:
LOG.info('No packages to install for %r', self.component_name)
pkg_names = set([p['name'] for p in pkgs])
utils.log_iterable(pkg_names, logger=LOG,
header="Setting up %s distribution packages" % (len(pkg_names)))
with utils.progress_bar(INSTALL_TITLE, len(pkgs)) as p_bar:
for (i, p) in enumerate(pkgs):
self.tracewriter.package_installed(p)
self.packager_factory.get_packager_for(p).install(p)
p_bar.update(i + 1)
return self.trace_dir
def pre_install(self):
pkgs = self._get_packages()
if pkgs:
mp = self._get_param_map(None)
for p in pkgs:
packager = self.get_packager(p)
packager.pre_install(p, mp)
for p in pkgs:
self.packager_factory.get_packager_for(p).pre_install(p, self._get_param_map(None))
def post_install(self):
pkgs = self._get_packages()
if pkgs:
mp = self._get_param_map(None)
for p in pkgs:
packager = self.get_packager(p)
packager.post_install(p, mp)
for p in pkgs:
self.packager_factory.get_packager_for(p).post_install(p, self._get_param_map(None))
def _get_config_files(self):
return list()
@ -313,9 +281,10 @@ class PkgInstallComponent(ComponentBase, PackageBasedComponentMixin):
class PythonInstallComponent(PkgInstallComponent):
def __init__(self, *args, **kargs):
def __init__(self, pip_factory, *args, **kargs):
PkgInstallComponent.__init__(self, *args, **kargs)
self.pips = kargs.get('pips', list())
self.pip_factory = pip_factory
def _get_python_directories(self):
py_dirs = dict()
@ -326,7 +295,6 @@ class PythonInstallComponent(PkgInstallComponent):
pip_list = list(self.pips)
for name in self.desired_subsystems:
if name in self.subsystem_info:
# TODO handle duplicates/version differences?
LOG.debug("Extending pip list with pips for subsystem %r" % (name))
subsystem_pips = self.subsystem_info[name].get('pips', list())
pip_list.extend(subsystem_pips)
@ -341,9 +309,21 @@ class PythonInstallComponent(PkgInstallComponent):
with utils.progress_bar(INSTALL_TITLE, len(pips)) as p_bar:
for (i, p) in enumerate(pips):
self.tracewriter.pip_installed(p)
pip.install(p, self.distro)
self.pip_factory.get_packager_for(p).install(p)
p_bar.update(i + 1)
def pre_install(self):
PkgInstallComponent.pre_install(self)
pips = self._get_pips()
for p in pips:
self.pip_factory.get_packager_for(p).pre_install(p, self._get_param_map(None))
def post_install(self):
PkgInstallComponent.post_install(self)
pips = self._get_pips()
for p in pips:
self.pip_factory.get_packager_for(p).post_install(p, self._get_param_map(None))
def _install_python_setups(self):
py_dirs = self._get_python_directories()
if py_dirs:
@ -378,13 +358,13 @@ class PythonInstallComponent(PkgInstallComponent):
return trace_dir
class PkgUninstallComponent(ComponentBase, PackageBasedComponentMixin):
def __init__(self, *args, **kargs):
class PkgUninstallComponent(ComponentBase):
def __init__(self, packager_factory, *args, **kargs):
ComponentBase.__init__(self, *args, **kargs)
PackageBasedComponentMixin.__init__(self)
self.tracereader = tr.TraceReader(tr.trace_fn(self.trace_dir,
tr.IN_TRACE))
self.keep_old = kargs.get('keep_old')
self.keep_old = kargs.get('keep_old', False)
self.packager_factory = packager_factory
def unconfigure(self):
if not self.keep_old:
@ -434,8 +414,7 @@ class PkgUninstallComponent(ComponentBase, PackageBasedComponentMixin):
which_removed = set()
with utils.progress_bar(UNINSTALL_TITLE, len(pkgs), reverse=True) as p_bar:
for (i, p) in enumerate(pkgs):
packager = self.get_packager(p)
if packager.remove(p):
if self.packager_factory.get_packager_for(p).remove(p):
which_removed.add(p['name'])
p_bar.update(i + 1)
utils.log_iterable(which_removed, logger=LOG,
@ -468,8 +447,9 @@ class PkgUninstallComponent(ComponentBase, PackageBasedComponentMixin):
class PythonUninstallComponent(PkgUninstallComponent):
def __init__(self, *args, **kargs):
def __init__(self, pip_factory, *args, **kargs):
PkgUninstallComponent.__init__(self, *args, **kargs)
self.pip_factory = pip_factory
def uninstall(self):
self._uninstall_python()
@ -487,7 +467,11 @@ class PythonUninstallComponent(PkgUninstallComponent):
header="Uninstalling %s python packages" % (len(pip_names)))
with utils.progress_bar(UNINSTALL_TITLE, len(pips), reverse=True) as p_bar:
for (i, p) in enumerate(pips):
pip.uninstall(p, self.distro)
try:
self.pip_factory.get_packager_for(p).remove(p)
except excp.ProcessExecutionError as e:
# NOTE(harlowja): pip seems to die if a pkg isn't there even in quiet mode
pass
p_bar.update(i + 1)
def _uninstall_python(self):
@ -561,7 +545,7 @@ class ProgramRuntime(ComponentBase):
# Adjust the program options now that we have real locations
program_opts = utils.param_replace_list(self._get_app_options(app_name), self._get_param_map(app_name))
# Start it with the given settings
LOG.debug("Starting %r using %r", app_name, run_type)
LOG.debug("Starting %r using %r", app_name, run_type)
details_fn = instance.start(app_name,
app_pth=app_pth, app_dir=app_dir, opts=program_opts)
LOG.info("Started %r details are in %r", app_name, details_fn)
@ -580,6 +564,7 @@ class ProgramRuntime(ComponentBase):
LOG.debug("Stopping %r using %r", app_name, how)
except RuntimeError as e:
LOG.warn("Could not load class %r which should be used to stop %r: %s", how, app_name, e)
continue
if killcls in killer_instances:
killer = killer_instances[killcls]
else:

View File

@ -130,9 +130,6 @@ class HorizonInstaller(comp.PythonInstallComponent):
LOG.info("Fixing up database named %r", DB_NAME)
db.drop_db(self.cfg, self.pw_gen, self.distro, DB_NAME)
db.create_db(self.cfg, self.pw_gen, self.distro, DB_NAME, utf8=True)
# db.grant_permissions(self.cfg, self.pw_gen, self.distro,
# self.cfg.getdefaulted('db', 'sql_user', 'root')
# )
def pre_install(self):
comp.PythonInstallComponent.pre_install(self)
@ -146,6 +143,7 @@ class HorizonInstaller(comp.PythonInstallComponent):
self._setup_db()
self._sync_db()
self._setup_blackhole()
# Anything to fixup after it was installed??
self._config_fixups()
def _get_apache_user_group(self):

View File

@ -77,7 +77,6 @@ class Distro(object):
'No platform configuration data for %r (%s)' %
(plt, distname))
@decorators.log_debug
def __init__(self, name, distro_pattern, packager_name, commands, components):
self.name = name
self._distro_pattern = re.compile(distro_pattern, re.IGNORECASE)

View File

@ -63,7 +63,7 @@ class RabbitPackager(apt.AptPackager):
self._execute_apt(cmd)
return True
def install(self, pkg):
def _install(self, pkg):
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600
name = pkg['name']

View File

@ -33,9 +33,6 @@ 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"
@ -68,24 +65,38 @@ class DBInstaller(db.DBInstaller):
class HorizonInstaller(horizon.HorizonInstaller):
def _config_fixups(self):
(user, group) = self._get_apache_user_group()
def _config_fix_wsgi(self):
# This is recorded so it gets cleaned up during uninstall
self.tracewriter.file_touched(SOCKET_CONF)
LOG.info("Fixing up %r and %r files" % (SOCKET_CONF, HTTPD_CONF))
self.tracewriter.file_touched("/etc/httpd/conf.d/wsgi-socket-prefix.conf")
LOG.info("Fixing up %r" % ("/etc/httpd/conf.d/wsgi-socket-prefix.conf"))
contents = "WSGISocketPrefix %s" % (sh.joinpths(self.log_dir, "wsgi-socket"))
with sh.Rooted(True):
# Fix the socket prefix to someplace we can use
fc = "WSGISocketPrefix %s" % (sh.joinpths(self.log_dir, "wsgi-socket"))
sh.write_file(SOCKET_CONF, fc)
# Now adjust the run user and group (of httpd.conf)
new_lines = list()
for line in sh.load_file(HTTPD_CONF).splitlines():
if line.startswith("User "):
line = "User %s" % (user)
if line.startswith("Group "):
line = "Group %s" % (group)
new_lines.append(line)
sh.write_file(HTTPD_CONF, utils.joinlinesep(*new_lines))
# The name seems to need to come after wsgi.conf (so thats what we are doing)
sh.write_file("/etc/httpd/conf.d/wsgi-socket-prefix.conf", contents)
def _config_fix_httpd(self):
LOG.info("Fixing up %r" % ('/etc/httpd/conf/httpd.conf'))
(user, group) = self._get_apache_user_group()
old_lines = sh.load_file('/etc/httpd/conf/httpd.conf').splitlines()
new_lines = list()
for line in old_lines:
# Directives in the configuration files are case-insensitive,
# but arguments to directives are often case sensitive...
# NOTE(harlowja): we aren't handling multi-line fixups...
if re.match("^\s*User\s+(.*)$", line, re.I):
line = "User %s" % (user)
if re.match("^\s*Group\s+(.*)$", line, re.I):
line = "Group %s" % (group)
if re.match("^\s*Listen\s+(.*)$", line, re.I):
line = "Listen 0.0.0.0:80"
new_lines.append(line)
contents = utils.joinlinesep(*new_lines)
with sh.Rooted(True):
sh.write_file('/etc/httpd/conf/httpd.conf', contents)
def _config_fixups(self):
self._config_fix_wsgi()
self._config_fix_httpd()
class RabbitRuntime(rabbit.RabbitRuntime):
@ -159,7 +170,7 @@ class YumPackagerWithRelinks(yum.YumPackager):
sh.unlink(tgt)
return response
def install(self, pkg):
def _install(self, pkg):
yum.YumPackager.install(self, pkg)
options = pkg.get('packager_options', {})
links = options.get('links', [])

View File

@ -15,45 +15,106 @@
# under the License.
import abc
import collections
from devstack import decorators
from devstack import importer
from devstack import log as logging
from devstack import utils
LOG = logging.getLogger("devstack.packager")
class PackageRegistry(object):
def __init__(self):
self.installed = dict()
self.removed = dict()
class Packager(object):
__meta__ = abc.ABCMeta
@decorators.log_debug
def __init__(self, distro):
self.distro = distro
self.registry = PackageRegistry()
@abc.abstractmethod
def install(self, pkg):
pass
@abc.abstractmethod
def _remove(self, pkg):
pass
name = pkg['name']
version = pkg.get('version')
if name in self.registry.installed:
existing_version = self.registry.installed[name]
if version == existing_version:
LOG.debug("Skipping install of %r since it already happened.", name)
else:
if existing_version is not None:
if utils.versionize(existing_version) < utils.versionize(version):
LOG.warn("A request has come in for a newer version of %r v(%s), when v(%s) was previously installed!", name, version, existing_version)
elif utils.versionize(existing_version) > utils.versionize(version):
LOG.warn("A request has come in for a older version of %r v(%s), when v(%s) was previously installed!", name, version, existing_version)
else:
LOG.warn("A request has come in for a different version of %r v(%s), when a unspecified version was previously installed!", name, version)
self._install(pkg)
LOG.debug("Noting that %r - v(%s) was installed.", name, (version or "??"))
self.registry.installed[name] = version
if name in self.registry.removed:
del(self.registry.removed[name])
def remove(self, pkg):
removable = pkg.get('removable', True)
if not removable:
return False
return self._remove(pkg)
name = pkg['name']
if name in self.registry.removed:
LOG.debug("Skipping removal of %r since it already happened.", name)
else:
self._remove(pkg)
LOG.debug("Noting that %r was removed.", name)
self.registry.removed[name] = True
if name in self.registry.installed:
del(self.registry.installed[name])
return True
def pre_install(self, pkg, params=None):
cmds = pkg.get('pre-install')
if cmds:
LOG.info("Running pre-install commands for package %r.",
pkg['name'])
LOG.info("Running pre-install commands for package %r.", pkg['name'])
utils.execute_template(*cmds, params=params)
def post_install(self, pkg, params=None):
cmds = pkg.get('post-install')
if cmds:
LOG.info("Running post-install commands for package %r.",
pkg['name'])
LOG.info("Running post-install commands for package %r.", pkg['name'])
utils.execute_template(*cmds, params=params)
@abc.abstractmethod
def _remove(self, pkg):
pass
@abc.abstractmethod
def _install(self, pkg):
pass
class PackagerFactory(object):
PACKAGER_KEY_NAME = 'packager_name'
def __init__(self, distro, default_packager):
self.default_packager = default_packager
self.distro = distro
self.fetched_packagers = dict()
def get_packager_for(self, pkg_info):
if self.PACKAGER_KEY_NAME in pkg_info:
packager_name = pkg_info[self.PACKAGER_KEY_NAME]
if packager_name in self.fetched_packagers:
packager = self.fetched_packagers[packager_name]
else:
LOG.debug('Loading custom package manager %r for package %r', packager_name, pkg_info['name'])
packager = importer.import_entry_point(packager_name)(self.distro)
self.fetched_packagers[packager_name] = packager
else:
packager = self.default_packager
return packager

View File

@ -40,6 +40,7 @@ VERSION_TEMPL = "%s=%s"
class AptPackager(pack.Packager):
def __init__(self, distro):
pack.Packager.__init__(self, distro)
# FIXME: Should this be coming from a setting somewhere?
@ -67,7 +68,7 @@ class AptPackager(pack.Packager):
self._execute_apt(APT_AUTOREMOVE)
return True
def install(self, pkg):
def _install(self, pkg):
name = pkg['name']
pkg_full = self._format_pkg_name(name, pkg.get("version"))
cmd = APT_INSTALL + [pkg_full]

View File

@ -32,6 +32,7 @@ VERSION_TEMPL = "%s-%s"
class YumPackager(pack.Packager):
def __init__(self, distro):
pack.Packager.__init__(self, distro)
@ -53,7 +54,7 @@ class YumPackager(pack.Packager):
def _install_special(self, name, info):
return False
def install(self, pkg):
def _install(self, pkg):
name = pkg['name']
if self._install_special(name, pkg):
return

View File

@ -29,7 +29,7 @@ class Persona(object):
@classmethod
def load_file(cls, fn):
persona_fn = sh.abspth(fn)
LOG.audit("Loading persona from file [%s]", persona_fn)
LOG.audit("Loading persona from file %r", persona_fn)
cls_kvs = None
try:
with open(persona_fn, "r") as fh:
@ -47,7 +47,6 @@ class Persona(object):
cls, cls_kvs, err)
return instance
@decorators.log_debug
def __init__(self, description,
supports,
components,

View File

@ -18,43 +18,39 @@
from devstack import exceptions as excp
from devstack import log as logging
from devstack import shell as sh
from devstack import utils
from devstack import packager as pack
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)
class Packager(pack.Packager):
def _make_pip_name(self, name, version):
if version is None:
return "%s" % (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))
name_full = _make_pip_name(name, pip.get('version'))
real_cmd = [root_cmd, 'install'] + PIP_INSTALL_CMD_OPTS
options = pip.get('options')
if options:
LOG.debug("Using pip options: %s" % (options))
real_cmd += [str(options)]
real_cmd += [name_full]
sh.execute(*real_cmd, run_as_root=True)
def _install(self, pip):
name = pip['name']
root_cmd = self.distro.get_command_config('pip')
LOG.audit("Installing python package %r using pip command %s" % (name, root_cmd))
name_full = self._make_pip_name(name, pip.get('version'))
real_cmd = [root_cmd] + ['install'] + PIP_INSTALL_CMD_OPTS
options = pip.get('options')
if options:
LOG.debug("Using pip options: %s" % (options))
real_cmd += [str(options)]
real_cmd += [name_full]
sh.execute(*real_cmd, run_as_root=True)
def uninstall(pip, distro, skip_errors=True):
root_cmd = distro.get_command('pip')
try:
def _remove(self, pip):
root_cmd = self.distro.get_command('pip')
# Versions don't seem to matter here...
name = _make_pip_name(pip['name'], None)
name = self._make_pip_name(pip['name'], None)
LOG.audit("Uninstalling python package %r using pip command %s" % (name, root_cmd))
cmd = [root_cmd, 'uninstall'] + PIP_UNINSTALL_CMD_OPTS + [name]
cmd = [root_cmd] + ['uninstall'] + PIP_UNINSTALL_CMD_OPTS + [name]
sh.execute(*cmd, run_as_root=True)
except excp.ProcessExecutionError:
if skip_errors:
LOG.debug(("Ignoring execution error that occured when uninstalling pip %r!"
" (this may be ok if it was uninstalled by a previous component)") % (name))
else:
raise

View File

@ -19,10 +19,13 @@ import abc
from devstack import env_rc
from devstack import exceptions as excp
from devstack import log as logging
from devstack import packager
from devstack import pip
from devstack import settings
from devstack import shell as sh
from devstack import utils
LOG = logging.getLogger("devstack.progs.actions")
@ -74,6 +77,8 @@ class ActionRunner(object):
desired_subsystems = persona.wanted_subsystems or {}
component_opts = persona.component_options or {}
instances = {}
pip_factory = packager.PackagerFactory(self.distro, pip.Packager(self.distro))
pkg_factory = packager.PackagerFactory(self.distro, self.distro.get_default_package_manager())
for c in components:
(cls, my_info) = self.distro.extract_component(c, self.NAME)
LOG.debug("Constructing class %s" % (cls))
@ -86,6 +91,8 @@ class ActionRunner(object):
cls_kvs['keep_old'] = self.keep_old
cls_kvs['desired_subsystems'] = desired_subsystems.get(c, set())
cls_kvs['options'] = component_opts.get(c, {})
cls_kvs['pip_factory'] = pip_factory
cls_kvs['packager_factory'] = pkg_factory
# The above is not overrideable...
for (k, v) in my_info.items():
if k not in cls_kvs:

View File

@ -145,8 +145,9 @@ def execute(*cmd, **kwargs):
else:
process_env = env.get()
LOG.debug("With environment %s", process_env)
# LOG.debug("With environment %s", process_env)
demoter = None
def demoter_functor(user_uid, user_gid):
def doit():
os.setregid(user_gid, user_gid)
@ -155,9 +156,10 @@ def execute(*cmd, **kwargs):
if not run_as_root:
(user_uid, user_gid) = get_suids()
if user_uid and user_gid:
LOG.debug("Not running as root, we will run with real & effective gid:uid --> %s:%s", user_gid, user_uid)
demoter = demoter_functor(user_uid=user_uid, user_gid=user_gid)
LOG.audit("Running as (user=%s, group=%s)", user_uid, user_gid)
demoter = demoter_functor(user_uid=user_uid, user_gid=user_gid)
else:
LOG.audit("Running as (user=%s, group=%s)", ROOT_USER_UID, ROOT_USER_UID)
rc = None
result = None
@ -639,7 +641,7 @@ def root_mode(quiet=True):
raise excp.StackException(msg)
else:
try:
LOG.debug("Escalating permissions to (user=%s, group=%s)" % (root_uid, root_gid))
LOG.audit("Escalating permissions to (user=%s, group=%s)" % (root_uid, root_gid))
os.setreuid(0, root_uid)
os.setregid(0, root_gid)
except OSError:
@ -653,7 +655,7 @@ def user_mode(quiet=True):
(sudo_uid, sudo_gid) = get_suids()
if sudo_uid is not None and sudo_gid is not None:
try:
LOG.debug("Dropping permissions to (user=%s, group=%s)" % (sudo_uid, sudo_gid))
LOG.audit("Dropping permissions to (user=%s, group=%s)" % (sudo_uid, sudo_gid))
os.setregid(0, sudo_gid)
os.setreuid(0, sudo_uid)
except OSError:

View File

@ -49,8 +49,6 @@ LOG = logging.getLogger("devstack.util")
DEF_IP = "127.0.0.1"
IP_LOOKER = '8.8.8.8'
DEF_IP_VERSION = settings.IPV4
ALL_NUMS = re.compile(r"^\d+$")
START_NUMS = re.compile(r"^(\d+)(\D+)")
STAR_VERSION = 0
# Thx cowsay
@ -236,31 +234,29 @@ def tempdir():
sh.deldir(tdir)
def versionize(input_version):
def versionize(input_version, unknown_version="-1.0"):
if input_version == None:
return distutils.version.LooseVersion(unknown_version)
input_version = str(input_version)
segments = input_version.split(".")
cleaned_segments = list()
for piece in segments:
piece = piece.strip()
if len(piece) == 0:
msg = "Disallowed empty version segment found"
raise ValueError(msg)
piece = piece.strip("*")
if len(piece) == 0:
cleaned_segments.append(STAR_VERSION)
elif ALL_NUMS.match(piece):
cleaned_segments.append(int(piece))
cleaned_segments.append("")
else:
piece_match = START_NUMS.match(piece)
if not piece_match:
msg = "Unknown version identifier %s" % (piece)
raise ValueError(msg)
piece = piece.strip("*")
if len(piece) == 0:
cleaned_segments.append(STAR_VERSION)
else:
cleaned_segments.append(int(piece_match.group(1)))
try:
piece = int(piece)
except ValueError:
pass
cleaned_segments.append(piece)
if not cleaned_segments:
msg = "Disallowed empty version found"
raise ValueError(msg)
num_parts = [str(p) for p in cleaned_segments]
return distutils.version.LooseVersion(".".join(num_parts))
return distutils.version.LooseVersion(unknown_version)
return distutils.version.LooseVersion(".".join([str(p) for p in cleaned_segments]))
def sort_versions(versions, descending=True):
@ -706,8 +702,8 @@ def goodbye(worked):
print(msg)
def welcome(ident):
lower = "| %s %s |" % (ident, version.version_string())
def welcome():
lower = "| %s |" % (version.version_string())
welcome_header = _get_welcome_stack()
max_line_len = len(max(welcome_header.splitlines(), key=len))
footer = color_text(settings.PROG_NICE_NAME, 'green')

11
stack
View File

@ -107,6 +107,10 @@ def setup_root(root_dir):
def run(args):
(repeat_string, line_max_len) = utils.welcome()
print(utils.center_text("Action Runner", repeat_string, line_max_len))
action = args.pop("action", '').strip().lower()
if action not in actions.get_action_names():
print(utils.color_text("No valid action specified!", "red"))
@ -122,9 +126,6 @@ def run(args):
root_dir = sh.joinpths(sh.gethomedir(), 'openstack')
root_dir = sh.abspth(root_dir)
setup_root(root_dir)
if not sh.isuseable(root_dir):
print(utils.color_text("Unreadable/writeable/executable root directory %r provided!" % (root_dir), "red"))
return False
persona_fn = args.pop('persona_fn')
if not persona_fn or not sh.isfile(persona_fn):
@ -132,10 +133,6 @@ def run(args):
return False
persona_fn = sh.abspth(persona_fn)
# Welcome!
(repeat_string, line_max_len) = utils.welcome(action.upper())
print(utils.center_text("Action Runner", repeat_string, line_max_len))
# !!
# Here on out we should be using the logger (and not print)!!
# !!