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    
Size: Mime:
# Copyright 2014 TrilioData Inc.
# All Rights Reserved.


"""
Scheduler Service
"""

from oslo_config import cfg

from workloadmgr import context
from workloadmgr import db
from workloadmgr import exception
from workloadmgr import flags
from workloadmgr import manager
from workloadmgr.openstack.common import excutils
from workloadmgr.openstack.common import importutils
from workloadmgr.openstack.common import log as logging
from workloadmgr.openstack.common.notifier import api as notifier

LOG = logging.getLogger(__name__)

scheduler_driver_opt = cfg.StrOpt(
    'scheduler_driver',
    default='workloadmgr.scheduler.filter_scheduler.'
    'FilterScheduler',
    help='Default scheduler driver to use')

FLAGS = flags.FLAGS
FLAGS.register_opt(scheduler_driver_opt)


class SchedulerManager(manager.Manager):
    """Chooses a host to create snapshot."""

    RPC_API_VERSION = '2.0'

    def __init__(self, scheduler_driver=None, service_name=None,
                 *args, **kwargs):
        if not scheduler_driver:
            scheduler_driver = FLAGS.scheduler_driver
        self.driver = importutils.import_object(scheduler_driver)
        super(SchedulerManager, self).__init__(*args, **kwargs)

    def init_host(self):
        ctxt = context.get_admin_context()

    def get_host_list(self, context):
        """Get a list of hosts from the HostManager."""
        return self.driver.get_host_list()

    def get_service_capabilities(self, context):
        """Get the normalized set of capabilities for this zone."""
        return self.driver.get_service_capabilities()

    def update_service_capabilities(self, context, service_name=None,
                                    host=None, capabilities=None, **kwargs):
        """Process a capability update from a service node."""
        if capabilities is None:
            capabilities = {}
        self.driver.update_service_capabilities(service_name,
                                                host,
                                                capabilities)

    def file_search(self, context, topic, search_id,
                    request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                snapshot_ref = db.file_search_get(context, search_id)

                request_spec.update(
                    {'search_id': search_id, 'file_search_properties': {}})

            self.driver.schedule_file_search(context, request_spec,
                                             filter_properties)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                file_search_state = {'status': {'status': 'error'}, 'error_msg': {'error_msg': str(ex)}}
                self._set_file_search_state_and_notify(
                    'file_search', file_search_state, context, ex, request_spec)

    def workload_create(self, context, topic, workload_id,
                        request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                workload_ref = db.workload_get(context, workload_id)

                request_spec.update(
                    {'workload_id': workload_id, 'workload_properties': {}})

            self.driver.schedule_workload_create(context, request_spec,
                                                   filter_properties)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                workload_state = {'status': {'status': 'error'}, 'error_msg': {'error_msg': str(ex)}}
                self._set_workload_state_and_notify('workload_create',
                                                    workload_state,
                                                    context, ex, request_spec)

    def workload_delete(self, context, topic, workload_id,
                        request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                workload_ref = db.workload_get(context, workload_id)

                request_spec.update(
                    {'workload_id': workload_id, 'workload_properties': {}})

            self.driver.schedule_workload_delete(context, request_spec,
                                                 filter_properties)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                workload_state = {'status': {'status': 'error'}, 'error_msg': {'error_msg': str(ex)}}
                self._set_workload_state_and_notify('workload_delete',
                                                    workload_state,
                                                    context, ex, request_spec)

    def workload_reset(self, context, topic, workload_id,
                       request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                workload_ref = db.workload_get(context, workload_id)

                request_spec.update(
                    {'workload_id': workload_id, 'workload_properties': {}})

            self.driver.schedule_workload_reset(context, request_spec,
                                                filter_properties)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                workload_state = {'status': {'status': 'available'}}
                self._set_workload_state_and_notify('workload_reset',
                                                    workload_state,
                                                    context, ex, request_spec)

    def workload_snapshot(self, context, topic, snapshot_id,
                          request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                snapshot_ref = db.snapshot_get(context, snapshot_id)

                request_spec.update(
                    {'snapshot_id': snapshot_id, 'snapshot_properties': {}})

            self.driver.schedule_workload_snapshot(context, request_spec,
                                                   filter_properties)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                snapshot_ref = db.snapshot_get(context, snapshot_id)
                db.workload_update(context, snapshot_ref.workload_id, {'status': 'available'})
                snapshot_state = {'status': {'status': 'error'}, 'error_msg': {'error_msg': str(ex)}}
                self._set_snapshot_state_and_notify('workload_snapshot',
                                                    snapshot_state,
                                                    context, ex, request_spec)

    def workload_import(self, context, topic, workload_id, upgrade, jobid, values,
                        request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}

                request_spec.update(
                    {'workload_id': workload_id,
                     'upgrade': upgrade,
                     'jobid': jobid,
                     'values': values,
                     'workload_properties': {}})

            self.driver.schedule_workload_import(context, request_spec,
                                                filter_properties)
        except exception.NoValidHost as ex:
            workload_state = {'status': {'status': 'error'}}

    def snapshot_delete(self, context, topic, snapshot_id,
                        request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                snapshot_ref = db.snapshot_get(context, snapshot_id)

                request_spec.update(
                    {'snapshot_id': snapshot_id,
                     'snapshot_properties': {}})

            self.driver.schedule_snapshot_delete(context, request_spec,
                                                 filter_properties)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                snapshot_ref = db.snapshot_get(context, snapshot_id)
                db.workload_update(context, snapshot_ref.workload_id, {'status': 'available'})
                snapshot_state = {'status': {'status': 'error'}, 'error_msg': {'error_msg': str(ex)}}
                self._set_snapshot_state_and_notify('snapshot_delete',
                                                    snapshot_state,
                                                    context, ex, request_spec)

    def network_topology_restore(self, context, topic, restore_id,
                                 request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                restore_ref = db.restore_get(context, restore_id)

                request_spec.update(
                    {'restore_id': restore_id, 'restore_properties': {}}
                )

            self.driver.schedule_network_topology_restore(
                context, request_spec, filter_properties
            )
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                restore_ref = db.restore_get(context, restore_id)
                db.snapshot_update(context, restore_ref.snapshot_id, {'status': 'available'})
                db.workload_update(context, restore_ref.snapshots.workload_id, {'status': 'available'})
                restore_state = {'status': {'status': 'error'}, 'error_msg': {'error_msg': str(ex)}}
                self._set_restore_state_and_notify('network_topology_restore',
                                                   restore_state,
                                                   context, ex, request_spec)

    def snapshot_restore(self, context, topic, restore_id,
                         request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                restore_ref = db.restore_get(context, restore_id)

                request_spec.update(
                    {'restore_id': restore_id, 'restore_properties': {}})

            self.driver.schedule_snapshot_restore(context, request_spec,
                                                  filter_properties)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                restore_ref = db.restore_get(context, restore_id)
                db.snapshot_update(context, restore_ref.snapshot_id, {'status': 'available'})
                db.workload_update(context, restore_ref.snapshots.workload_id, {'status': 'available'})
                restore_state = {'status': {'status': 'error'}, 'error_msg': {'error_msg': str(ex)}}
                self._set_restore_state_and_notify('snapshot_restore',
                                                   restore_state,
                                                   context, ex, request_spec)

    def snapshot_mount(self, context, topic, snapshot_id, mount_vm_id,
                       request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                snapshot_ref = db.snapshot_get(context, snapshot_id)

                request_spec.update(
                    {'snapshot_id': snapshot_id,
                     'mount_vm_id': mount_vm_id,
                     'snapshot_properties': {}})

            self.driver.schedule_snapshot_mount(context, request_spec,
                                                filter_properties)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                snapshot_state = {'status': {'status': 'available'}}
                self._set_snapshot_state_and_notify('snapshot_mount',
                                                   snapshot_state,
                                                   context, ex, request_spec)

    def snapshot_dismount(self, context, topic, snapshot_id,
                          request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                snapshot_ref = db.snapshot_get(context, snapshot_id)

                request_spec.update(
                    {'snapshot_id': snapshot_id,
                     'snapshot_properties': {}})

            self.driver.schedule_snapshot_dismount(context, request_spec,
                                                   filter_properties)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                snapshot_state = {'status': {'status': 'available'}}
                self._set_snapshot_state_and_notify('snapshot_dismount',
                                                    snapshot_state,
                                                    context, ex, request_spec)

    def security_groups_restore(self, context, topic, restore_id,
                                request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                restore_ref = db.restore_get(context, restore_id)

                request_spec.update(
                    {'restore_id': restore_id, 'restore_properties': {}}
                )

            self.driver.schedule_security_groups_restore(
                context, request_spec, filter_properties
            )
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                restore_ref = db.restore_get(context, restore_id)
                db.snapshot_update(context, restore_ref.snapshot_id, {'status': 'available'})
                db.workload_update(context, restore_ref.snapshots.workload_id, {'status': 'available'})
                restore_state = {'status': {'status': 'error'}, 'error_msg': {'error_msg': str(ex)}}
                self._set_restore_state_and_notify('security_groups_restore',
                                                   restore_state,
                                                   context, ex, request_spec)

    def _set_file_search_state_and_notify(self, method, updates, context, ex,
                                          request_spec):
        LOG.error(_("Failed to schedule_%(method)s: %(ex)s") % locals())

        file_search_status = updates['status']
        properties = request_spec.get('snapshot_properties', {})

        search_id = request_spec.get('search_id', None)

        if search_id:
            if file_search_status['status'] == 'error' and updates.get('error_msg'):
                updates['error_msg'].update(file_search_status)
                db.file_search_update(context, search_id, updates['error_msg'])
            else:
                db.file_search_update(context, search_id, file_search_status)

        payload = dict(request_spec=request_spec,
                       snapshot_properties=properties,
                       search_id=search_id,
                       state=file_search_status,
                       method=method,
                       reason=ex)

        notifier.notify(context, notifier.publisher_id("scheduler"),
                        'scheduler.' + method, notifier.ERROR, payload)

    def _set_workload_state_and_notify(self, method, updates, context, ex,
                                       request_spec):
        LOG.error(_("Failed to schedule_%(method)s: %(ex)s") % locals())

        workload_status = updates['status']
        properties = request_spec.get('workload_properties', {})

        workload_id = request_spec.get('workload_id', None)

        if workload_id:
            if workload_status['status'] == 'error' and updates.get('error_msg'):
                updates['error_msg'].update(workload_status)
                db.workload_update(context, workload_id, updates['error_msg'])
            else:
                db.workload_update(context, workload_id, workload_status)

        payload = dict(request_spec=request_spec,
                       workload_properties=properties,
                       workload_id=workload_id,
                       state=workload_status,
                       method=method,
                       reason=ex)

        notifier.notify(context, notifier.publisher_id("scheduler"),
                        'scheduler.' + method, notifier.ERROR, payload)

    def _set_migration_plan_state_and_notify(self, method, updates, context, ex,
                                       request_spec):
        LOG.error(_("Failed to schedule_%(method)s: %(ex)s") % locals())

        migration_plan_status = updates['status']
        properties = request_spec.get('migration_plan_properties', {})

        migration_plan_id = request_spec.get('migration_plan_id', None)

        if migration_plan_id:
            db.migration_plan_update(context, migration_plan_id, migration_plan_status)

        migration_id = request_spec.get('migration_id', None)

        if migration_id:
            db.migration_update(context, migration_id, migration_plan_status)

        payload = dict(request_spec=request_spec,
                       migration_plan_properties=properties,
                       migration_plan_id=migration_plan_id,
                       state=migration_plan_status,
                       method=method,
                       reason=ex)

        notifier.notify(context, notifier.publisher_id("scheduler"),
                        'scheduler.' + method, notifier.ERROR, payload)

    def _set_snapshot_state_and_notify(self, method, updates, context, ex,
                                       request_spec):
        LOG.error(_("Failed to schedule_%(method)s: %(ex)s") % locals())

        snapshot_status = updates['status']
        properties = request_spec.get('snapshot_properties', {})

        snapshot_id = request_spec.get('snapshot_id', None)

        if snapshot_id:
            if snapshot_status['status'] == 'error' and updates.get('error_msg'):
                updates['error_msg'].update(snapshot_status)
                db.snapshot_update(context, snapshot_id, updates['error_msg'])
            else:
                db.snapshot_update(context, snapshot_id, snapshot_status)

        payload = dict(request_spec=request_spec,
                       snapshot_properties=properties,
                       snapshot_id=snapshot_id,
                       state=snapshot_status,
                       method=method,
                       reason=ex)

        notifier.notify(context, notifier.publisher_id("scheduler"),
                        'scheduler.' + method, notifier.ERROR, payload)

    def _set_restore_state_and_notify(self, method, updates, context, ex,
                                      request_spec):
        LOG.error(_("Failed to schedule_%(method)s: %(ex)s") % locals())

        restore_status = updates['status']
        properties = request_spec.get('restore_properties', {})

        restore_id = request_spec.get('restore_id', None)

        if restore_id:
            if restore_status['status'] == 'error' and updates.get('error_msg'):
                updates['error_msg'].update(restore_status)
                db.restore_update(context, restore_id, updates['error_msg'])
            else:
                db.restore_update(context, restore_id, restore_status)

        payload = dict(request_spec=request_spec,
                       restore_properties=properties,
                       restore_id=restore_id,
                       state=restore_status,
                       method=method,
                       reason=ex)

        notifier.notify(context, notifier.publisher_id("scheduler"),
                        'scheduler.' + method, notifier.ERROR, payload)

    def schedule_send_email(self, context, topic, object_id, object_type,
                          request_spec=None, filter_properties=None):
        try:
            if not request_spec:
                request_spec = {'object_id': object_id, 'object_type': object_type,
                                'restore_properties': {}, 'snapshot_properties': {}}
            self.driver.schedule_send_email(context, request_spec, filter_properties)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                payload = dict(request_spec=request_spec,
                       object_id=object_id,
                       object_type=object_type,
                       state='sending email failed',
                       method='schedule_send_email',
                       reason=ex)
                notifier.notify(context, notifier.publisher_id("scheduler"),
                        'scheduler: schedule_send_email', notifier.ERROR, payload)

        notifier.notify(context, notifier.publisher_id("scheduler"),
                        'scheduler.' + method, notifier.ERROR, payload)

    def migration_plan_create(self, context, topic, migration_plan_id,
                              request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                migration_plan_ref = db.migration_plan_get(context, migration_plan_id)

                request_spec.update(
                    {'migration_plan_id': migration_plan_id, 'migration_plan_properties': {}})

            self.driver.schedule_migration_plan_create(context, request_spec,
                                                       filter_properties)
        except exception.NoValidHost as ex:
            migration_plan_state = {'status': {'status': 'error'}}
            self._set_migration_plan_state_and_notify('migration_plan_create',
                                                migration_plan_state,
                                                context, ex, request_spec)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                migration_plan_state = {'status': {'status': 'error'}}
                self._set_migration_plan_state_and_notify('migration_plan_create',
                                                    migration_plan_state,
                                                    context, ex, request_spec)

    def migration_plan_discovervms(self, context, topic, migration_plan_id,
                                   request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                migration_plan_ref = db.migration_plan_get(context, migration_plan_id)

                request_spec.update(
                    {'migration_plan_id': migration_plan_id, 'migration_plan_properties': {}})

            self.driver.schedule_migration_plan_discovervms(context, request_spec,
                                                            filter_properties)
        except exception.NoValidHost as ex:
            migration_plan_state = {'status': {'status': 'available'}}
            self._set_migration_plan_state_and_notify('migration_plan_discovervms',
                                                migration_plan_state,
                                                context, ex, request_spec)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                migration_plan_state = {'status': {'status': 'available'}}
                self._set_migration_plan_state_and_notify('migration_plan_discovervms',
                                                    migration_plan_state,
                                                    context, ex, request_spec)

    def migration_plan_delete(self, context, topic, migration_plan_id,
                        request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                migration_plan_ref = db.migration_plan_get(context, migration_plan_id)

                request_spec.update(
                    {'migration_plan_id': migration_plan_id, 'migration_plan_properties': {}})

            self.driver.schedule_migration_plan_delete(context, request_spec,
                                                 filter_properties)
        except exception.NoValidHost as ex:
            migration_plan_state = {'status': {'status': 'error'}}
            self._set_migration_plan_state_and_notify('migration_plan_delete',
                                                migration_plan_state,
                                                context, ex, request_spec)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                migration_plan_state = {'status': {'status': 'error'}}
                self._set_migration_plan_state_and_notify('migration_plan_delete',
                                                    migration_plan_state,
                                                    context, ex, request_spec)

    def migration_create(self, context, topic, migration_id,
                         request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                migration_ref = db.migration_get(context, migration_id)

                request_spec.update(
                    {'migration_id': migration_id, 'migration_plan_properties': {}})

            self.driver.schedule_migration_create(context, request_spec,
                                                  filter_properties)
        except exception.NoValidHost as ex:
            migration_state = {'status': {'status': 'error'}}
            self._set_migration_state_and_notify('migration_create',
                                                 migration_state,
                                                 context, ex, request_spec)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                migration_state = {'status': {'status': 'error'}}
                self._set_migration_state_and_notify('migration_create',
                                                   migration_state,
                                                   context, ex, request_spec)

    def migration_delete(self, context, topic, migration_id,
                         request_spec=None, filter_properties=None):
        try:
            if request_spec is None:
                request_spec = {}
                migration_ref = db.migration_get(context, migration_id)

                request_spec.update(
                    {'migration_id': migration_id,
                     'migration_plan_properties': {}})

            self.driver.schedule_migration_delete(context, request_spec,
                                                  filter_properties)
        except exception.NoValidHost as ex:
            migration_state = {'status': {'status': 'error'}}
            self._set_migration_state_and_notify('migration_delete',
                                                 migration_state,
                                                 context, ex, request_spec)
        except Exception as ex:
            with excutils.save_and_reraise_exception():
                migration_state = {'status': {'status': 'error'}}
                self._set_migration_state_and_notify('migration_delete',
                                                     migration_state,
                                                     context, ex, request_spec)