Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
contego / home / tvault / .virtenv / bin / tvault-contego
Size: Mime:
#!/home/tvault/.virtenv/bin/python
# Copyright 2014 TrilioData Inc.
# All Rights Reserved.

"""Starter script for TrilioVault Contego - Openstack Nova Compute Extension."""

# Normally, a nova service would import eventlet here and
# monkey_patch the core libraries so use the greenthread-friendly versions.
# However, since we actually execute some of the code to run in separate
# threads (hence we use the tpool() functionality provided by eventlet), we
# skip monkey_patching the thread libraries.
import eventlet
eventlet.sleep()
eventlet.monkey_patch()

import gettext
import os
import sys
import gc
import traceback
import greenlet
import signal
import pkg_resources
from contego.nova.extension.driver import vault

try:
    from oslo_log import log as logging
except ImportError:
    from nova.openstack.common import log as logging

try:
    from oslo.config import cfg
except ImportError:
    from oslo_config import cfg

gettext.install('nova', unicode=1)


# Preload this otherwise it leads to the main
# manager class not loading because we won't be able to load the virt module
# so that we may pull out the connection string paramters.
from nova.compute import flavors
from nova import version

# If ../nova/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
                                                os.pardir,
                                                os.pardir))
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
    sys.path.insert(0, possible_topdir)

from nova.conductor import rpcapi as conductor_rpcapi
from nova import config
import nova.db.api
from nova import exception
from nova import objects
from nova.objects import base as objects_base
from nova import service
from nova import context
from nova import objects

LOG = logging.getLogger(__name__)

try:
    CONTEGO_VERSION = pkg_resources.get_distribution("tvault-contego").version
except Exception as ex:
    LOG.warning("Not able to fetch Contego version.")
    CONTEGO_VERSION = ''
# Stole this from Essex RPC code. To debug problems, we allow
# dumping of all active greenthreads. There is no cost to this code living
# on a production system.


def is_gt_liberty():
    release = int(version.version_string().split('.')[0])
    if release <= 2015 and release > 1000:
        return False
    elif release <= 12:
        return False
    else:
        return True


def find_objects(t):
    return filter(lambda o: isinstance(o, t), gc.get_objects())


def print_threads():
    for i, gt in enumerate(find_objects(greenlet.greenlet)):
        LOG.info("greenthread %s\n%s", i,
                 ''.join(traceback.format_stack(gt.gr_frame)))
    for i, stack in sys._current_frames().items():
        LOG.info("thread %s\n%s", i,
                 ''.join(traceback.format_stack(stack)))


def sig_usr2_handler(signum, frame):
    print_threads()


def block_db_access():
    class NoDB(object):
        def __getattr__(self, attr):
            return self

        def __call__(self, *args, **kwargs):
            stacktrace = "".join(traceback.format_stack())
            LOG.error('No db access allowed in tvault-contego: %s' %
                      stacktrace)
            raise exception.DBNotAllowed('tvault-contego')

    nova.db.api.IMPL = NoDB()


def setup_conductor():
    if not cfg.CONF.conductor.use_local:
        block_db_access()
        objects_base.NovaObject.indirection_api = \
            conductor_rpcapi.ConductorAPI()


def sigend_handler():
    vault.update_in_progress_files_on_exit()
    vault.unmount_backup_media()


# set_process_cgroup - Moves the main PID to the "trilio" cgroup
# created by the install. Once the main PID is moved all children
# will be placed in the cgroup by default.
def set_process_cgroup():
    our_pid = os.getpid()
    if os.path.exists("/sys/fs/cgroup/cpu/trilio/tasks"):
        LOG.info('Moving PID %s to cgroup' % our_pid)
        cpu_taskfile = os.open("/sys/fs/cgroup/cpu/trilio/tasks", os.O_WRONLY)
        if cpu_taskfile < 0:
            LOG.error('Could not add PID to cpu tasks')
        else:
            os.write(cpu_taskfile, str(our_pid))
            os.close(cpu_taskfile)
    else:
        LOG.info('CPU Control group missing. Skipping...')

    if os.path.exists("/sys/fs/cgroup/blkio/trilio/tasks"):
        blkio_taskfile = os.open(
            "/sys/fs/cgroup/blkio/trilio/tasks", os.O_WRONLY)
        if blkio_taskfile < 0:
            LOG.error('Could not add PID to blkio tasks')
        else:
            os.write(blkio_taskfile, str(our_pid))
            os.close(blkio_taskfile)
    else:
        LOG.info('I/O Control Group missing. I/O limit not set.')


if __name__ == '__main__':
    objects.register_all()
    config.parse_args(sys.argv)
    contego_opts = [
        cfg.StrOpt('contego_' + CONTEGO_VERSION + '_manager',
                   default='contego.nova.extension.manager.ContegoManager',
                   help='TrilioVault Contego - Openstack Nova Compute Extension')]

    if 'compute_driver' in cfg.CONF.keys():
        cfg.CONF.set_default('compute_driver', 'libvirt.LibvirtDriver')
    else:
        contego_opts.append(cfg.StrOpt('compute_driver',
                                       default='libvirt.LibvirtDriver',
                                       help='TrilioVault Contego - Compute driver'))
    cfg.CONF.register_opts(contego_opts)

    try:
        logging.setup(cfg.CONF, 'nova')
    except TypeError:
        logging.setup('nova')

    vault.mount_backup_media()

    signal.signal(signal.SIGUSR2, sig_usr2_handler)
    setup_conductor()
    ctxt = context.get_admin_context()
    binary_name = 'contego_' + CONTEGO_VERSION
    if is_gt_liberty():
        binary_name = 'nova-contego_' + CONTEGO_VERSION

    try:
        lst = objects.service.ServiceList.get_by_topic(ctxt, 'contego')
        for lt in lst:
            if lt.host == cfg.CONF.host and lt.binary != binary_name:
                lt.destroy()
    except Exception as ex:
        LOG.error(ex.message)
        pass

    try:
        lst = objects.service.ServiceList.get_by_topic(ctxt, 'contego_1')
        for lt in lst:
            if lt.host == cfg.CONF.host and lt.binary != binary_name:
                lt.destroy()
    except Exception as ex:
        LOG.error(ex.message)
        pass

    set_process_cgroup()
    server = service.Service.create(binary=binary_name,
                                    db_allowed=False, topic="contego_1")
    service.serve(server)
    service.wait()
    sigend_handler()
    signal.signal(signal.SIGTERM, sigend_handler)
    signal.signal(signal.SIGINT, sigend_handler)