Beispiel #1
0
 def _sync_virtual(self):
     parent = yield db.get(self.context, '__parent__')
     uuid = yield db.get(self.context, '__name__')
     submitter = IVirtualizationContainerSubmitter(parent)
     vm = yield submitter.submit(IInfoVM, uuid)
     yield self.sync_owner(vm)
     yield self._sync_vm(vm)
Beispiel #2
0
def handle_ownership_change(model, event):
    if model.__parent__ is None:
        log.msg(
            'Ownership change event handler suppressed: model is not attached to a parent yet',
            system='ownership-change-event')
        return

    msg = 'Compute "%s" owner changed from "%s" to "%s"' % (
        model, event.oldowner, event.nextowner)
    oldowner = getUtility(IAuthentication).getPrincipal(event.oldowner)
    newowner = getUtility(IAuthentication).getPrincipal(event.nextowner)
    oldulog = UserLogger(subject=model, owner=oldowner)
    newulog = UserLogger(subject=model, owner=newowner)
    log.msg(msg, system='ownership-change-event')
    oldulog.log(msg)
    newulog.log(msg)

    try:
        submitter = IVirtualizationContainerSubmitter(model.__parent__)
        blocking_yield(
            submitter.submit(ISetOwner, model.__name__, model.__owner__))
    except Exception:
        log.err(system='ownership-change-event')
        raise

    curtransaction = transaction.get()
    curtransaction.addAfterCommitHook(update_statistics_dbhook,
                                      args=([event.oldowner,
                                             event.nextowner], ))
Beispiel #3
0
 def _sync_virtual(self):
     parent = yield db.get(self.context, '__parent__')
     uuid = yield db.get(self.context, '__name__')
     submitter = IVirtualizationContainerSubmitter(parent)
     vm = yield submitter.submit(IInfoVM, uuid)
     yield self.sync_owner(vm)
     yield self._sync_vm(vm)
Beispiel #4
0
    def _execute(self, cmd, args):
        name = yield db.get(self.context, '__name__')
        parent = yield db.get(self.context, '__parent__')

        submitter = IVirtualizationContainerSubmitter(parent)
        yield submitter.submit(IUndeployVM, name)

        @db.transact
        def finalize_vm():
            ippools = db.get_root()['oms_root']['ippools']
            ip = netaddr.IPAddress(self.context.ipv4_address.split('/')[0])
            log.msg('Attempting to deallocate IP %s from the pools' % ip,
                    system='undeploy-action')
            if ippools.free(ip):
                ulog = UserLogger(principal=cmd.protocol.interaction.
                                  participations[0].principal,
                                  subject=self.context,
                                  owner=self.context.__owner__)
                ulog.log('Deallocated IP: %s', ip)
                log.msg('Deallocated IP %s' % ip, system='ippool')
            vm = traverse1(canonical_path(self.context))
            if vm is not None:
                noLongerProvides(vm, IDeployed)
                alsoProvides(vm, IUndeployed)

        yield finalize_vm()

        vm_parameters = yield self.get_parameters()

        utils = getAllUtilitiesRegisteredFor(IPostUndeployHook)

        for util in utils:
            yield defer.maybeDeferred(util.execute, self.context, cmd,
                                      vm_parameters)
Beispiel #5
0
    def sync_owner_transact(self, vm):
        owner = self.context.__owner__
        parent = self.context.__parent__
        uuid = self.context.__name__

        # PUSH if owner is set and is modified, PULL only when OMS owner is not set
        if owner is not None:
            if vm.get('owner') != owner:
                log.msg('Attempting to push owner (%s) of %s to agent' % (owner, self.context),
                        system='sync')
                submitter = IVirtualizationContainerSubmitter(parent)
                d = submitter.submit(ISetOwner, uuid, owner)
                d.addCallback(lambda r: log.msg('Owner pushing for %s successful' % self.context,
                                                system='sync'))
                d.addErrback(log.err, system='sync')
        elif vm.get('owner'):
            compute = TmpObj(self.context)
            newowner = getUtility(IAuthentication).getPrincipal(vm['owner'])
            if newowner is not None:
                log.msg('Modifying ownership of "%s" from %s to %s.'
                        % (compute, owner, newowner), system='sync')
                compute.__owner__ = newowner
                with SuppressEvents(self.context):
                    compute.apply()
            else:
                log.msg('User not found: "%s" while restoring owner for %s. '
                        'Leaving as-is' % (vm['owner'], compute), system='sync')
Beispiel #6
0
    def _execute(self, cmd, args):
        name = yield db.get(self.context, '__name__')
        parent = yield db.get(self.context, '__parent__')

        submitter = IVirtualizationContainerSubmitter(parent)
        yield submitter.submit(IUndeployVM, name)

        @db.transact
        def finalize_vm():
            ippools = db.get_root()['oms_root']['ippools']
            ip = netaddr.IPAddress(self.context.ipv4_address.split('/')[0])
            if ippools.free(ip):
                ulog = UserLogger(principal=cmd.protocol.interaction.participations[0].principal,
                                  subject=self.context, owner=self.context.__owner__)
                ulog.log('Deallocated IP: %s', ip)

            vm = traverse1(canonical_path(self.context))
            if vm is not None:
                noLongerProvides(vm, IDeployed)
                alsoProvides(vm, IUndeployed)

        yield finalize_vm()

        vm_parameters = yield self.get_parameters()

        utils = getAllUtilitiesRegisteredFor(IPostUndeployHook)

        for util in utils:
            yield defer.maybeDeferred(util.execute, self.context, cmd, vm_parameters)
Beispiel #7
0
    def sync_owner_transact(self, vm):
        owner = self.context.__owner__
        parent = self.context.__parent__
        uuid = self.context.__name__

        # PUSH if owner is set and is modified, PULL only when OMS owner is not set
        if owner is not None:
            if vm.get('owner') != owner:
                log.msg('Attempting to push owner (%s) of %s to agent' %
                        (owner, self.context),
                        system='sync')
                submitter = IVirtualizationContainerSubmitter(parent)
                d = submitter.submit(ISetOwner, uuid, owner)
                d.addCallback(lambda r: log.msg(
                    'Owner pushing for %s successful' % self.context,
                    system='sync'))
                d.addErrback(log.err, system='sync')
        elif vm.get('owner'):
            compute = TmpObj(self.context)
            newowner = getUtility(IAuthentication).getPrincipal(vm['owner'])
            if newowner is not None:
                log.msg('Modifying ownership of "%s" from %s to %s.' %
                        (compute, owner, newowner),
                        system='sync')
                compute.__owner__ = newowner
                with SuppressEvents(self.context):
                    compute.apply()
            else:
                log.msg('User not found: "%s" while restoring owner for %s. '
                        'Leaving as-is' % (vm['owner'], compute),
                        system='sync')
 def _sync_virtual(self):
     parent = yield db.get(self.context, '__parent__')
     name = yield db.get(self.context, '__name__')
     submitter = IVirtualizationContainerSubmitter(parent)
     vmlist = yield submitter.submit(IListVMS)
     for vm in vmlist:
         if vm['uuid'] == name:
             yield self.sync_owner(vm)
             yield self._sync_vm(vm)
Beispiel #9
0
    def gather_vms(self):

        @db.ro_transact
        def get_vms_if_not_empty():
            vms = follow_symlinks(self.context['vms']) or []

            for vm in vms:
                if IVirtualCompute.providedBy(vm):
                    return vms

            log.msg('%s: no VMs' % (self.context.hostname), system='metrics', logLevel=logging.DEBUG)

        vms = yield get_vms_if_not_empty()

        # get the metrics for all running VMS
        if not vms or self.context.state != u'active':
            return

        name = yield db.get(self.context, 'hostname')

        try:
            log.msg('%s: gather VM metrics' % (name), system='metrics', logLevel=logging.DEBUG)
            submitter = IVirtualizationContainerSubmitter(vms)
            metrics = yield submitter.submit(IGetGuestMetrics, __killhook=self._killhook)
        except OperationRemoteError as e:
            log.msg('%s: remote error: %s' % (name, e), system='metrics', logLevel=logging.DEBUG)
            if e.remote_tb:
                log.msg(e.remote_tb, system='metrics', logLevel=logging.DEBUG)
            return
        except Exception:
            log.msg("%s: error gathering VM metrics" % name, system='metrics', logLevel=logging.ERROR)
            if get_config().getboolean('debug', 'print_exceptions'):
                log.err(system='metrics')
            return

        if not metrics:
            log.msg('%s: no VM metrics received!' % name, system='metrics', logLevel=logging.WARNING)
            return

        log.msg('%s: VM metrics received: %s' % (name, len(metrics)), system='metrics')
        timestamp = int(time.time() * 1000)

        # db transact is needed only to traverse the zodb.
        @db.ro_transact
        def get_streams():
            streams = []
            for uuid, data in metrics.items():
                if vms[uuid] and vms[uuid]['metrics']:
                    vm_metrics = vms[uuid]['metrics']
                    for k in data:
                        if vm_metrics[k]:
                            streams.append((IStream(vm_metrics[k]), (timestamp, data[k])))
            return streams

        # streams could defer the data appending but we don't care
        for stream, data_point in (yield get_streams()):
            stream.add(data_point)
Beispiel #10
0
def handle_virtual_compute_config_change_request(compute, event):
    c = sudo(compute)
    compute_p = yield db.get(c, '__parent__')
    compute_type = yield db.get(compute_p, 'backend')
    # At the moment we only handle openvz backend updates (OMS-568)
    if compute_type != 'openvz':
        return

    update_param_whitelist = ['diskspace',
                              'memory',
                              'num_cores',
                              'swap_size']

    param_modifier = {'diskspace': lambda d: d['total']}

    unit_corrections_coeff = {'memory': 1 / 1024.0,
                              'swap_size': 1 / 1024.0,
                              'diskspace': 1 / 1024.0}

    params_to_update = filter(lambda (k, v): k in update_param_whitelist, event.modified.iteritems())

    if len(params_to_update) == 0:
        return

    # correct unit coefficients (usually MB -> GB)
    params_to_update = map(lambda (k, v): (k, param_modifier.get(k, lambda x: x)(v)), params_to_update)
    params_to_update = map(lambda (k, v): (k, unit_corrections_coeff.get(k) * v
                                            if k in unit_corrections_coeff else v), params_to_update)

    @db.transact
    def update_vm_limits(cpu_limit):
        logger.debug("Setting cpu_limit to %s, previous value %s" % (cpu_limit / 100.0, c.cpu_limit))
        c.cpu_limit = cpu_limit / 100.0
    
    cores_setting = filter(lambda(k, v): k == 'num_cores', params_to_update)
    if len(cores_setting) == 1:
        # adjust cpu_limit to follow the number of cores as well
        cpu_limit = int(cores_setting[0][1] * get_config().getfloat('vms', 'cpu_limit', 80))
        log.msg("Updating cpulimit to %s" % cpu_limit, system='vm-configuration-update')

        params_to_update.append(('cpu_limit', cpu_limit))
        yield update_vm_limits(cpu_limit)

    submitter = IVirtualizationContainerSubmitter((yield db.get(compute, '__parent__')))
    try:
        yield submitter.submit(IUpdateVM, (yield db.get(compute, '__name__')), dict(params_to_update))
    except Exception as e:
        @db.transact
        def reset_to_original_values():
            for mk, mv in event.modified.iteritems():
                setattr(compute, mk, event.original[mk])
        yield reset_to_original_values()
        raise e  # must re-throw, because sys.exc_info seems to get erased with the yield
    else:
        owner = (yield db.get(compute, '__owner__'))
        UserLogger(subject=compute, owner=owner).log('Compute "%s" configuration changed' % compute)
Beispiel #11
0
    def gather_vms(self):

        @db.ro_transact
        def get_vms_if_not_empty():
            vms = follow_symlinks(self.context['vms']) or []

            for vm in vms:
                if IVirtualCompute.providedBy(vm):
                    return vms

            log.msg('%s: no VMs' % (self.context.hostname), system='metrics', logLevel=logging.DEBUG)

        vms = yield get_vms_if_not_empty()

        # get the metrics for all running VMS
        if not vms or self.context.state != u'active':
            return

        name = yield db.get(self.context, 'hostname')

        try:
            log.msg('%s: gather VM metrics' % (name), system='metrics', logLevel=logging.DEBUG)
            submitter = IVirtualizationContainerSubmitter(vms)
            metrics = yield submitter.submit(IGetGuestMetrics, __killhook=self._killhook)
        except OperationRemoteError as e:
            log.msg('%s: remote error: %s' % (name, e), system='metrics', logLevel=logging.DEBUG)
            if e.remote_tb:
                log.msg(e.remote_tb, system='metrics', logLevel=logging.DEBUG)
            return
        except Exception:
            log.msg("%s: error gathering VM metrics" % name, system='metrics', logLevel=logging.ERROR)
            if get_config().getboolean('debug', 'print_exceptions'):
                log.err(system='metrics')

        if not metrics:
            log.msg('%s: no VM metrics received!' % name, system='metrics', logLevel=logging.WARNING)
            return

        log.msg('%s: VM metrics received: %s' % (name, len(metrics)), system='metrics')
        timestamp = int(time.time() * 1000)

        # db transact is needed only to traverse the zodb.
        @db.ro_transact
        def get_streams():
            streams = []
            for uuid, data in metrics.items():
                if vms[uuid] and vms[uuid]['metrics']:
                    vm_metrics = vms[uuid]['metrics']
                    for k in data:
                        if vm_metrics[k]:
                            streams.append((IStream(vm_metrics[k]), (timestamp, data[k])))
            return streams

        # streams could defer the data appending but we don't care
        for stream, data_point in (yield get_streams()):
            stream.add(data_point)
Beispiel #12
0
    def _execute(self, cmd, args):
        name = yield db.get(self.context, '__name__')
        parent = yield db.get(self.context, '__parent__')

        submitter = IVirtualizationContainerSubmitter(parent)
        try:
            vm = yield submitter.submit(IInfoVM, name)
            max_key_len = max(len(key) for key in vm)
            for key, value in vm.items():
                cmd.write("%s %s\n" % ((key + ':').ljust(max_key_len), value))
        except Exception as e:
            cmd.write("%s\n" % format_error(e))
            log.err(system='action-info')
Beispiel #13
0
    def _execute(self, cmd, args):
        name = yield db.get(self.context, '__name__')
        parent = yield db.get(self.context, '__parent__')

        submitter = IVirtualizationContainerSubmitter(parent)
        try:
            for vm in (yield submitter.submit(IListVMS)):
                if vm['uuid'] == name:
                    max_key_len = max(len(key) for key in vm)
                    for key, value in vm.items():
                        cmd.write("%s %s\n" % ((key + ':').ljust(max_key_len), value))
        except Exception as e:
            cmd.write("%s\n" % format_error(e))
Beispiel #14
0
    def _execute(self, cmd, args):
        action_name = getattr(self, 'action_name', self._name + "ing")

        name = yield db.get(self.context, '__name__')
        parent = yield db.get(self.context, '__parent__')

        yield self.set_inprogress()

        self._action_log(cmd, '%s %s' % (action_name, name))
        submitter = IVirtualizationContainerSubmitter(parent)

        try:
            yield submitter.submit(self.job, name)
        except Exception as e:
            self._action_log(cmd, '%s' % (format_error(e)))
            raise
Beispiel #15
0
    def sync_owner(self, vm):
        owner = yield db.get(self.context, '__owner__')
        parent = yield db.get(self.context, '__parent__')
        uuid = yield db.get(self.context, '__name__')

        if vm.get('owner'):
            if owner != vm['owner']:
                @db.transaft
                def pull_owner():
                    compute = TmpObj(self.context)
                    newowner = getUtility(IAuthentication).getPrincipal(vm['owner'])
                    compute.__owner__ = newowner
                    compute.apply()
                yield pull_owner()
        elif owner is not None:
            log.msg('Attempting to push owner (%s) of %s to agent' % (owner, self.context), system='sync')
            submitter = IVirtualizationContainerSubmitter(parent)
            yield submitter.submit(ISetOwner, uuid, owner)
            log.msg('Owner pushing for %s successful' % self.context, system='sync')
Beispiel #16
0
def handle_ownership_change(model, event):
    msg = 'Compute "%s" owner changed from "%s" to "%s"' % (model, event.oldowner, event.nextoner)

    oldowner = getUtility(IAuthentication).getPrincipal(event.oldowner)
    newowner = getUtility(IAuthentication).getPrincipal(event.nextowner)
    oldulog = UserLogger(subject=model, owner=oldowner)
    newulog = UserLogger(subject=model, owner=newowner)
    log.msg(msg, system='ownership-change-event')
    oldulog.log(msg)
    newulog.log(msg)

    try:
        submitter = IVirtualizationContainerSubmitter(model.__parent__)
        blocking_yield(submitter.submit(ISetOwner, model.__name__, model.__owner__))
    except Exception:
        log.err(system='ownership-change-event')
        raise

    curtransaction = transaction.get()
    curtransaction.addAfterCommitHook(update_statistics_dbhook, args=([event.oldowner, event.nextowner],))
Beispiel #17
0
    def sync_owner_transact(self, vm):
        owner = self.context.__owner__
        parent = self.context.__parent__
        uuid = self.context.__name__

        if vm.get('owner'):
            if owner != vm['owner']:
                compute = TmpObj(self.context)
                newowner = getUtility(IAuthentication).getPrincipal(vm['owner'])
                if newowner is not None:
                    compute.__owner__ = newowner
                    compute.apply()
                else:
                    log.msg('User not found: "%s" while restoring owner for %s. '
                            'Leaving as-is' % (vm['owner'], compute), system='sync')
        elif owner is not None:
            log.msg('Attempting to push owner (%s) of %s to agent' % (owner, self.context), system='sync')
            submitter = IVirtualizationContainerSubmitter(parent)
            d = submitter.submit(ISetOwner, uuid, owner)
            d.addCallback(lambda r: log.msg('Owner pushing for %s successful' % self.context, system='sync'))
            d.addErrback(log.err, system='sync')
Beispiel #18
0
    def _execute(self, cmd, args):
        action_name = getattr(self, 'action_name', self._name + "ing")

        name = yield db.get(self.context, '__name__')

        if not self.context.license_activated:
            self._action_log(
                cmd, '%s %s failed: VM license is not activated yet' %
                (action_name, name))
            return

        parent = yield db.get(self.context, '__parent__')

        yield self.set_inprogress()

        self._action_log(cmd, '%s %s' % (action_name, name))
        submitter = IVirtualizationContainerSubmitter(parent)

        try:
            yield submitter.submit(self.job, name)
        except Exception as e:
            self._action_log(cmd, '%s' % (format_error(e)))
            raise
Beispiel #19
0
def handle_virtual_compute_config_change_request(compute, event):
    update_param_whitelist = ['cpu_limit',
                              'diskspace',
                              'memory',
                              'num_cores',
                              'swap_size']

    param_modifier = {'diskspace': lambda d: d['total']}

    unit_corrections_coeff = {'memory': 1 / 1024.0,
                              'swap_size': 1 / 1024.0,
                              'diskspace': 1 / 1024.0}

    params_to_update = filter(lambda (k, v): k in update_param_whitelist, event.modified.iteritems())

    if len(params_to_update) == 0:
        return

    # correct unit coefficients (usually MB -> GB)
    params_to_update = map(lambda (k, v): (k, param_modifier.get(k, lambda x: x)(v)), params_to_update)
    params_to_update = map(lambda (k, v): (k, unit_corrections_coeff.get(k) * v
                                            if k in unit_corrections_coeff else v), params_to_update)

    submitter = IVirtualizationContainerSubmitter((yield db.get(compute, '__parent__')))
    try:
        yield submitter.submit(IUpdateVM, (yield db.get(compute, '__name__')), dict(params_to_update))
    except Exception as e:
        @db.transact
        def reset_to_original_values():
            for mk, mv in event.modified.iteritems():
                setattr(compute, mk, event.original[mk])
        yield reset_to_original_values()
        raise e  # must re-throw, because sys.exc_info seems to get erased with the yield
    else:
        owner = (yield db.get(compute, '__owner__'))
        UserLogger(subject=compute, owner=owner).log('Compute "%s" configuration changed' % compute)
Beispiel #20
0
    def _execute(self, cmd, args):
        @db.ro_transact
        def get_destination():
            return (args.__parent__
                    if IVirtualizationContainer.providedBy(args) else
                    cmd.traverse(args.dest_path))

        @db.ro_transact
        def get_hostname(target):
            return target.hostname

        name = yield db.get(self.context, '__name__')
        source_vms = yield db.get(self.context, '__parent__')

        destination = yield get_destination()
        assert ICompute.providedBy(
            destination), 'Destination must be a Compute'
        assert not IVirtualCompute.providedBy(
            destination), 'Cannot migrate to a VM'
        destination_hostname = yield get_hostname(destination)
        destination_vms = follow_symlinks(destination['vms'])
        assert (yield db.get(destination_vms, 'backend')) == (yield db.get(source_vms, 'backend')),\
                'Destination backend is different from source'

        @db.transact
        def set_additional_keys():
            self._additional_keys = [
                canonical_path(destination_vms),
                canonical_path(destination)
            ]

        yield set_additional_keys()

        yield self.reacquire_until_clear()

        log.msg('Initiating migration for %s to %s' %
                (name, destination_hostname),
                system='migrate')

        try:
            if not (yield self._check_vm_pre(cmd, name, destination_hostname,
                                             destination_vms)):
                return

            source_submitter = IVirtualizationContainerSubmitter(source_vms)
            yield source_submitter.submit(IMigrateVM, name,
                                          destination_hostname,
                                          (not args.offline), False)
            log.msg('Migration done. Checking... %s' % destination_vms,
                    system='migrate')

            if (yield self._check_vm_post(cmd, name, destination_hostname,
                                          destination_vms)):
                log.msg('Migration finished successfully!', system='migrate')

                @db.transact
                def mv_and_inherit():
                    machines = db.get_root()['oms_root']['machines']
                    computes = db.get_root()['oms_root']['computes']
                    try:
                        destination_compute = machines[destination.__name__]
                        vm_compute = follow_symlinks(
                            computes[self.context.__name__])
                        vm_compute.failure = destination_compute.failure
                        vm_compute.suspicious = destination_compute.suspicious
                        dvms = follow_symlinks(destination_compute['vms'])
                        dvms.add(vm_compute)
                        log.msg('Model moved.', system='migrate')
                    except IndexError:
                        log.msg(
                            'Model NOT moved: destination compute or vms do not exist',
                            system='migrate')
                    except KeyError:
                        log.msg('Model NOT moved: already moved by sync?',
                                system='migrate')

                yield mv_and_inherit()
        except OperationRemoteError as e:
            self._action_log(cmd,
                             'Failed migration of %s to %s: remote error %s' %
                             (name, destination_hostname,
                              '\n%s' % e.remote_tb if e.remote_tb else ''),
                             logLevel=ERROR,
                             system='migrate')
Beispiel #21
0
def handle_virtual_compute_config_change_request(compute, event):
    c = sudo(compute)
    compute_p = yield db.get(c, '__parent__')
    compute_type = yield db.get(compute_p, 'backend')
    # At the moment we only handle openvz backend updates (OMS-568)
    if compute_type != 'openvz':
        return

    update_param_whitelist = ['diskspace', 'memory', 'num_cores', 'swap_size']

    param_modifier = {'diskspace': lambda d: d['total']}

    unit_corrections_coeff = {
        'memory': 1 / 1024.0,
        'swap_size': 1 / 1024.0,
        'diskspace': 1 / 1024.0
    }

    params_to_update = filter(lambda (k, v): k in update_param_whitelist,
                              event.modified.iteritems())

    if len(params_to_update) == 0:
        return

    # correct unit coefficients (usually MB -> GB)
    params_to_update = map(
        lambda (k, v): (k, param_modifier.get(k, lambda x: x)(v)),
        params_to_update)
    params_to_update = map(
        lambda (k, v): (k, unit_corrections_coeff.get(k) * v
                        if k in unit_corrections_coeff else v),
        params_to_update)

    @db.transact
    def update_vm_limits(cpu_limit):
        logger.debug("Setting cpu_limit to %s, previous value %s" %
                     (cpu_limit / 100.0, c.cpu_limit))
        c.cpu_limit = cpu_limit / 100.0

    cores_setting = filter(lambda (k, v): k == 'num_cores', params_to_update)
    if len(cores_setting) == 1:
        # adjust cpu_limit to follow the number of cores as well
        cpu_limit = int(cores_setting[0][1] *
                        get_config().getfloat('vms', 'cpu_limit', 80))
        log.msg("Updating cpulimit to %s" % cpu_limit,
                system='vm-configuration-update')

        params_to_update.append(('cpu_limit', cpu_limit))
        yield update_vm_limits(cpu_limit)

    submitter = IVirtualizationContainerSubmitter(
        (yield db.get(compute, '__parent__')))
    try:
        yield submitter.submit(IUpdateVM, (yield db.get(compute, '__name__')),
                               dict(params_to_update))
    except Exception as e:

        @db.transact
        def reset_to_original_values():
            for mk, mv in event.modified.iteritems():
                setattr(compute, mk, event.original[mk])

        yield reset_to_original_values()
        raise e  # must re-throw, because sys.exc_info seems to get erased with the yield
    else:
        owner = (yield db.get(compute, '__owner__'))
        UserLogger(subject=compute, owner=owner).log(
            'Compute "%s" configuration changed' % compute)
Beispiel #22
0
 def _get_vm(self, destination_vms, uuid):
     dest_submitter = IVirtualizationContainerSubmitter(destination_vms)
     vmlist = yield dest_submitter.submit(IInfoVM, uuid)
     defer.returnValue(vmlist)
Beispiel #23
0
 def _get_vmlist(self, destination_vms):
     dest_submitter = IVirtualizationContainerSubmitter(destination_vms)
     vmlist = yield dest_submitter.submit(IListVMS)
     defer.returnValue(vmlist)
Beispiel #24
0
    def _execute(self, cmd, args):
        if not any_stack_installed(self.context):
            return

        @db.transact
        def update_templates(container, templates):
            if not container['templates']:
                container.add(Templates())

            template_container = container['templates']

            for template in templates:
                name = template['template_name']

                if not template_container['by-name'][name]:
                    template_container.add(Template(unicode(name), get_u(template, 'domain_type')))

                t = template_container['by-name'][name].target
                t.cores = (get_i(template, 'vcpu_min'),
                           get_i(template, 'vcpu'),
                           max(-1, get_i(template, 'vcpu_max')))
                t.memory = (get_f(template, 'memory_min'),
                            get_f(template, 'memory'),
                            max(-1.0, get_f(template, 'memory_max')))
                t.swap = (get_f(template, 'swap_min'),
                          get_f(template, 'swap'),
                          max(-1.0, get_f(template, 'swap_max')))
                t.disk = (get_f(template, 'disk_min'),
                          get_f(template, 'disk'),
                          max(-1.0, get_f(template, 'disk_max')))
                t.nameserver = get_u(template, 'nameserver')

                t.username = get_u(template, 'username')
                t.password = get_u(template, 'passwd')

                t.cpu_limit = (get_i(template, 'vcpulimit_min'),
                               get_i(template, 'vcpulimit'))
                t.ip = get_u(template, 'ip_address')

            # delete templates no more offered upstream
            template_names = template_container['by-name'].listnames()
            vanished_template_names = set(template_names).difference(
                template['template_name'] for template in templates)

            for template in vanished_template_names:
                template_container.remove(follow_symlinks(template_container['by-name'][template]))

        for container in self.context.listcontent():
            if not IVirtualizationContainer.providedBy(container):
                continue

            submitter = IVirtualizationContainerSubmitter(container)
            templates = yield submitter.submit(IGetLocalTemplates)

            if not templates:
                log.msg('Did not find any templates on %s/%s' % (self.context, container),
                        system='sync-templates')
                continue

            log.msg('Synced templates on %s (%s). Updating %s templates' %
                    (self.context, container, len(templates)), system='sync-templates')

            yield update_templates(container, templates)
Beispiel #25
0
    def _execute(self, cmd, args):

        @db.ro_transact
        def get_destination():
            return (args.__parent__ if IVirtualizationContainer.providedBy(args)
                    else cmd.traverse(args.dest_path))

        @db.ro_transact
        def get_hostname(target):
            return target.hostname

        name = yield db.get(self.context, '__name__')
        source_vms = yield db.get(self.context, '__parent__')

        destination = yield get_destination()
        assert ICompute.providedBy(destination), 'Destination must be a Compute'
        assert not IVirtualCompute.providedBy(destination), 'Cannot migrate to a VM'
        destination_hostname = yield get_hostname(destination)
        destination_vms = follow_symlinks(destination['vms'])
        assert (yield db.get(destination_vms, 'backend')) == (yield db.get(source_vms, 'backend')),\
                'Destination backend is different from source'

        @db.transact
        def set_additional_keys():
            self._additional_keys = [canonical_path(destination_vms), canonical_path(destination)]
        yield set_additional_keys()

        yield self.reacquire_until_clear()

        log.msg('Initiating migration for %s to %s' % (name, destination_hostname), system='migrate')

        try:
            if not (yield self._check_vm_pre(name, destination_hostname, destination_vms)):
                return

            source_submitter = IVirtualizationContainerSubmitter(source_vms)
            yield source_submitter.submit(IMigrateVM, name, destination_hostname, (not args.offline), False)
            log.msg('Migration done. Checking... %s' % destination_vms, system='migrate')

            if (yield self._check_vm_post(cmd, name, destination_hostname, destination_vms)):
                log.msg('Migration finished successfully!', system='migrate')

                @db.transact
                def mv_and_inherit():
                    machines = db.get_root()['oms_root']['machines']
                    computes = db.get_root()['oms_root']['computes']
                    try:
                        destination_compute = machines[destination.__name__]
                        vm_compute = follow_symlinks(computes[self.context.__name__])
                        vm_compute.failure = destination_compute.failure
                        vm_compute.suspicious = destination_compute.suspicious
                        dvms = follow_symlinks(destination_compute['vms'])
                        dvms.add(vm_compute)
                        log.msg('Model moved.', system='migrate')
                    except IndexError:
                        log.msg('Model NOT moved: destination compute or vms do not exist', system='migrate')
                    except KeyError:
                        log.msg('Model NOT moved: already moved by sync?', system='migrate')
                yield mv_and_inherit()
        except OperationRemoteError as e:
            self._action_log(cmd, 'Failed migration of %s to %s: remote error %s' % (
                name, destination_hostname, '\n%s' % e.remote_tb if e.remote_tb else ''),
                logLevel=ERROR, system='migrate')
Beispiel #26
0
    def _execute(self, cmd, args):
        template = yield db.get(self.context, 'template')

        if not template:
            self._action_log(
                cmd,
                'Cannot deploy %s (%s) because no template was specified' %
                (self.context.hostname, self.context),
                system='deploy',
                logLevel=ERROR)
            return

        if (yield db.ro_transact(IDeployed.providedBy)(self.context)):
            log.msg('Attempt to deploy a deployed compute: %s' %
                    (self.context),
                    system='deploy')
            return

        @db.transact
        def allocate_ip_address():
            ippools = db.get_root()['oms_root']['ippools']
            ip = ippools.allocate()
            if ip is not None:
                self._action_log(cmd,
                                 'Allocated IP: %s for %s' %
                                 (ip, self.context),
                                 system='deploy')
                ulog = UserLogger(principal=cmd.protocol.interaction.
                                  participations[0].principal,
                                  subject=self.context,
                                  owner=self.context.__owner__)
                ulog.log('Allocated IP for %s: %s' % (self.context, ip))
                return ip
            else:
                raise Exception(
                    'Could not allocate IP for the new compute: pools exhausted or undefined'
                )

        @db.transact
        def cleanup_root_password():
            if getattr(self.context, 'root_password', None) is not None:
                self.context.root_password = None

        @db.transact
        def adjust_cpulimit():
            """Set cpulimit to a configured percentage * cores"""
            cores = getattr(self.context, 'num_cores', 1)
            cpu_limit_factor = get_config().getfloat('vms', 'cpu_limit', 80)
            cpu_limit = cores * cpu_limit_factor / 100.0
            log.msg("Updating cpulimit to %s" % cpu_limit, system='deploy')
            self.context.cpu_limit = cpu_limit

        target = (args if IVirtualizationContainer.providedBy(args) else
                  (yield db.get(self.context, '__parent__')))

        try:
            yield db.transact(alsoProvides)(self.context, IDeploying)

            vm_parameters = yield self.get_parameters()

            ipaddr = netaddr.IPAddress(vm_parameters['ip_address'])
            if vm_parameters['ip_address'] in (None, u'0.0.0.0/32', u'0.0.0.0',
                                               '0.0.0.0/32', '0.0.0.0'):
                ipaddr = yield allocate_ip_address()
                vm_parameters.update({'ip_address': str(ipaddr)})

            utils = getAllUtilitiesRegisteredFor(IPreDeployHook)
            for util in utils:
                yield defer.maybeDeferred(util.execute, self.context, cmd,
                                          vm_parameters)

            log.msg('Deploying %s to %s: issuing agent command' %
                    (self.context, target),
                    system='deploy')
            res = yield IVirtualizationContainerSubmitter(target).submit(
                IDeployVM, vm_parameters)
            yield cleanup_root_password()
            yield adjust_cpulimit()

            name = yield db.get(self.context, '__name__')
            hostname = yield db.get(self.context, 'hostname')
            owner = yield db.get(self.context, '__owner__')
            owner_obj = getUtility(IAuthentication).getPrincipal(owner)

            log.msg('Checking post-deploy...', system='deploy')

            @db.transact
            def set_notify_admin():
                if self.context.notify_admin:
                    self.context.license_activated = False
                    admin_logger.warning(
                        '%s (hostname=%s; owner=%s; targethost=%s(%s); ipaddr=%s) '
                        'requires activation!', self.context,
                        self.context.hostname, self.context.__owner__,
                        target.__parent__, target.__parent__.hostname,
                        vm_parameters['ip_address'])

            yield set_notify_admin()

            if not (yield self._check_vm_post(cmd, name, hostname, target)):
                self._action_log(cmd,
                                 'Deployment failed. Request result: %s' % res,
                                 system='deploy')
                return

            @db.transact
            def add_deployed_model_remove_from_hangar(c, target):
                path = canonical_path(target)
                target = traverse1(path)

                cpath = canonical_path(c)
                c = traverse1(cpath)
                if c is None:
                    raise Exception('Compute not found: "%s"' % cpath)

                new_compute = Compute(unicode(hostname), u'inactive')
                new_compute.__name__ = name
                new_compute.__owner__ = owner_obj
                new_compute.template = unicode(template)
                new_compute._ipv4_address = unicode(ipaddr)
                new_compute.mac_address = getattr(c, 'mac_address', None)
                new_compute.memory = getattr(c, 'memory', 0)
                new_compute.diskspace = getattr(c, 'diskspace', {u'total': 0})
                new_compute.num_cores = getattr(c, 'num_cores', 0)
                new_compute.license_activated = getattr(
                    c, 'license_activated', True)

                alsoProvides(new_compute, IVirtualCompute)
                alsoProvides(new_compute, IDeployed)
                noLongerProvides(new_compute, IManageable)
                target.add(new_compute)

                container = c.__parent__
                del container[name]

                timestamp = int(time.time() * 1000)
                IStream(new_compute).add((timestamp, {
                    'event': 'change',
                    'name': 'features',
                    'value': new_compute.features,
                    'old_value': self.context.features
                }))
                IStream(new_compute).add((timestamp, {
                    'event':
                    'change',
                    'name':
                    'ipv4_address',
                    'value':
                    new_compute._ipv4_address,
                    'old_value':
                    self.context._ipv4_address
                }))

            yield add_deployed_model_remove_from_hangar(self.context, target)

            self._action_log(
                cmd,
                'Deployment of "%s"(%s) is finished' %
                (vm_parameters['hostname'], self.context.__name__),
                system='deploy')

            auto_allocate = get_config().getboolean('vms', 'auto_allocate',
                                                    True)
            if not auto_allocate and not get_config().getboolean(
                    'stats', 'only_report_on_sync', True):
                yield defer.maybeDeferred(
                    getUtility(IUserStatisticsProvider).update, owner)

        except Exception as e:
            log.err(system='deploy')

            @db.transact
            def cleanup_deploying():
                noLongerProvides(self.context, IDeploying)

            yield cleanup_deploying()
            raise e
Beispiel #27
0
 def _sync_vms(self, cmd):
     submitter = IVirtualizationContainerSubmitter(self.context)
     remote_vms = yield submitter.submit(IListVMS)
     yield self._sync_vms_transact(remote_vms)
Beispiel #28
0
    def _execute(self, cmd, args):
        if not any_stack_installed(self.context):
            return

        @db.transact
        def update_templates(container, templates):
            if not container['templates']:
                container.add(Templates())

            template_container = container['templates']

            for template in templates:
                name = template['template_name']

                if not template_container['by-name'][name]:
                    template_container.add(
                        Template(unicode(name), get_u(template,
                                                      'domain_type')))

                t = template_container['by-name'][name].target
                t.cores = (get_i(template,
                                 'vcpu_min'), get_i(template, 'vcpu'),
                           max(-1, get_i(template, 'vcpu_max')))
                t.memory = (get_f(template,
                                  'memory_min'), get_f(template, 'memory'),
                            max(-1.0, get_f(template, 'memory_max')))
                t.swap = (get_f(template, 'swap_min'), get_f(template, 'swap'),
                          max(-1.0, get_f(template, 'swap_max')))
                t.disk = (get_f(template, 'disk_min'), get_f(template, 'disk'),
                          max(-1.0, get_f(template, 'disk_max')))
                t.nameserver = get_u(template, 'nameserver')

                t.username = get_u(template, 'username')
                t.password = get_u(template, 'passwd')

                t.cpu_limit = (get_i(template, 'vcpulimit_min'),
                               get_i(template, 'vcpulimit'))
                t.ip = get_u(template, 'ip_address')

            # delete templates no more offered upstream
            template_names = template_container['by-name'].listnames()
            vanished_template_names = set(template_names).difference(
                template['template_name'] for template in templates)

            for template in vanished_template_names:
                template_container.remove(
                    follow_symlinks(template_container['by-name'][template]))

        for container in self.context.listcontent():
            if not IVirtualizationContainer.providedBy(container):
                continue

            submitter = IVirtualizationContainerSubmitter(container)
            templates = yield submitter.submit(IGetLocalTemplates)

            if not templates:
                log.msg('Did not find any templates on %s/%s' %
                        (self.context, container),
                        system='sync-templates')
                continue

            log.msg('Synced templates on %s (%s). Updating %s templates' %
                    (self.context, container, len(templates)),
                    system='sync-templates')

            yield update_templates(container, templates)