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)
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], ))
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)
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 _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)
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)
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)
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)
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)
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')
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))
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
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')
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],))
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')
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
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)
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')
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)
def _get_vm(self, destination_vms, uuid): dest_submitter = IVirtualizationContainerSubmitter(destination_vms) vmlist = yield dest_submitter.submit(IInfoVM, uuid) defer.returnValue(vmlist)
def _get_vmlist(self, destination_vms): dest_submitter = IVirtualizationContainerSubmitter(destination_vms) vmlist = yield dest_submitter.submit(IListVMS) defer.returnValue(vmlist)
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)
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')
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
def _sync_vms(self, cmd): submitter = IVirtualizationContainerSubmitter(self.context) remote_vms = yield submitter.submit(IListVMS) yield self._sync_vms_transact(remote_vms)
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)