def start(self): vcs_string = version.version_string_with_vcs() logging.audit(_('Starting %(topic)s node (version %(vcs_string)s)'), {'topic': self.topic, 'vcs_string': vcs_string}) self.manager.init_host() conn1 = rpc.Connection.instance(new=True) conn2 = rpc.Connection.instance(new=True) conn3 = rpc.Connection.instance(new=True) if self.report_interval: consumer_all = rpc.TopicAdapterConsumer( connection=conn1, topic=self.topic, proxy=self) consumer_node = rpc.TopicAdapterConsumer( connection=conn2, topic='%s.%s' % (self.topic, self.host), proxy=self) fanout = rpc.FanoutAdapterConsumer( connection=conn3, topic=self.topic, proxy=self) self.timers.append(consumer_all.attach_to_eventlet()) self.timers.append(consumer_node.attach_to_eventlet()) self.timers.append(fanout.attach_to_eventlet()) pulse = utils.LoopingCall(self.report_state) pulse.start(interval=self.report_interval, now=False) self.timers.append(pulse) if self.periodic_interval: periodic = utils.LoopingCall(self.periodic_tasks) periodic.start(interval=self.periodic_interval, now=False) self.timers.append(periodic)
def start(self): vcs_string = version.version_string_with_vcs() logging.audit(_('Starting %(topic)s node (version %(vcs_string)s)'), { 'topic': self.topic, 'vcs_string': vcs_string }) self.manager.init_host() self.model_disconnected = False ctxt = context.get_admin_context() try: service_ref = db.service_get_by_args(ctxt, self.host, self.binary) self.service_id = service_ref['id'] except exception.NotFound: self._create_service_ref(ctxt) if 'nova-compute' == self.binary: self.manager.update_available_resource(ctxt) self.conn = rpc.create_connection(new=True) logging.debug("Creating Consumer connection for Service %s" % self.topic) # Share this same connection for these Consumers consumer_all = rpc.create_consumer(self.conn, self.topic, self, fanout=False) node_topic = '%s.%s' % (self.topic, self.host) consumer_node = rpc.create_consumer(self.conn, node_topic, self, fanout=False) fanout = rpc.create_consumer(self.conn, self.topic, self, fanout=True) consumers = [consumer_all, consumer_node, fanout] consumer_set = rpc.create_consumer_set(self.conn, consumers) # Wait forever, processing these consumers def _wait(): try: consumer_set.wait() finally: consumer_set.close() self.consumer_set_thread = greenthread.spawn(_wait) if self.report_interval: pulse = utils.LoopingCall(self.report_state) pulse.start(interval=self.report_interval, now=False) self.timers.append(pulse) if self.periodic_interval: periodic = utils.LoopingCall(self.periodic_tasks) periodic.start(interval=self.periodic_interval, now=False) self.timers.append(periodic)
def start(self): vcs_string = version.version_string_with_vcs() LOG.audit(_('Starting %(topic)s node (version %(vcs_string)s)'), { 'topic': self.topic, 'vcs_string': vcs_string }) self.manager.init_host() self.model_disconnected = False ctxt = context.get_admin_context() try: service_ref = db.service_get_by_args(ctxt, self.host, self.binary) self.service_id = service_ref['id'] except exception.NotFound: self._create_service_ref(ctxt) if self.backdoor_port is not None: self.manager.backdoor_port = self.backdoor_port self.conn = rpc.create_connection(new=True) LOG.debug( _("Creating Consumer connection for Service %s") % self.topic) self.manager.pre_start_hook(rpc_connection=self.conn) rpc_dispatcher = self.manager.create_rpc_dispatcher() # Share this same connection for these Consumers self.conn.create_consumer(self.topic, rpc_dispatcher, fanout=False) node_topic = '%s.%s' % (self.topic, self.host) self.conn.create_consumer(node_topic, rpc_dispatcher, fanout=False) self.conn.create_consumer(self.topic, rpc_dispatcher, fanout=True) # Consume from all consumers in a thread self.conn.consume_in_thread() self.manager.post_start_hook() if self.report_interval: pulse = utils.LoopingCall(self.report_state) pulse.start(interval=self.report_interval, initial_delay=self.report_interval) self.timers.append(pulse) if self.periodic_interval: if self.periodic_fuzzy_delay: initial_delay = random.randint(0, self.periodic_fuzzy_delay) else: initial_delay = None periodic = utils.LoopingCall(self.periodic_tasks) periodic.start(interval=self.periodic_interval, initial_delay=initial_delay) self.timers.append(periodic)
def register_nova_listeners(self): self.tokens = {} class TopicProxy(): @staticmethod def authorize_vnc_console(context, **kwargs): print "Received a token: %s" % kwargs self.tokens[kwargs['token']] = \ {'args': kwargs, 'last_activity': time.time()} self.conn = rpc.create_connection(new=True) self.conn.create_consumer('vncproxy', TopicProxy) def delete_expired_tokens(): now = time.time() to_delete = [] for k, v in self.tokens.items(): if now - v['last_activity'] > FLAGS.vnc_proxy_idle_timeout: to_delete.append(k) for k in to_delete: del self.tokens[k] self.conn.consume_in_thread() utils.LoopingCall(delete_expired_tokens).start(1)
def rescue(self, context, instance, network_info): """Loads a VM using rescue images. A rescue is normally performed when something goes wrong with the primary images and data needs to be corrected/recovered. Rescuing should not edit or over-ride the original image, only allow for data recovery. """ self.destroy(instance, False) xml_dict = self.to_xml_dict(instance, rescue=True) rescue_images = {'image_id': FLAGS.baremetal_rescue_image_id, 'kernel_id': FLAGS.baremetal_rescue_kernel_id, 'ramdisk_id': FLAGS.baremetal_rescue_ramdisk_id} self._create_image(instance, '.rescue', rescue_images, network_info=network_info) timer = utils.LoopingCall(f=None) def _wait_for_rescue(): try: state = self._conn.reboot_domain(instance['name']) if state == power_state.RUNNING: LOG.debug(_('instance %s: rescued'), instance['name']) timer.stop() except Exception: LOG.exception(_('_wait_for_rescue failed')) timer.stop() timer.f = _wait_for_reboot return timer.start(interval=0.5, now=True)
def spawn(self, context, instance, image_meta, network_info, block_device_info=None): LOG.debug(_("<============= spawn of baremetal =============>")) def basepath(fname='', suffix=''): return os.path.join(FLAGS.instances_path, instance['name'], fname + suffix) bpath = basepath(suffix='') timer = utils.LoopingCall(f=None) xml_dict = self.to_xml_dict(instance, network_info) self._create_image(context, instance, xml_dict, network_info=network_info, block_device_info=block_device_info) LOG.debug(_("instance %s: is building"), instance['name'], instance=instance) LOG.debug(xml_dict, instance=instance) def _wait_for_boot(): try: LOG.debug(_("Key is injected but instance is not running yet"), instance=instance) #(old_ref, new_ref) = db.instance_update_and_get_original( db.instance_update( context, instance['id'], {'vm_state': vm_states.BUILDING}) #notifications.send_update(context, old_ref, new_ref) state = self._conn.create_domain(xml_dict, bpath) if state == power_state.RUNNING: LOG.debug(_('instance %s: booted'), instance['name'], instance=instance) #(old_ref, new_ref) = db.instance_update_and_get_original( db.instance_update( context, instance['id'], {'vm_state': vm_states.ACTIVE}) #notifications.send_update(context, old_ref, new_ref) LOG.debug(_('~~~~~~ current state = %s ~~~~~~'), state, instance=instance) LOG.debug(_("instance %s spawned successfully"), instance['name'], instance=instance) else: LOG.debug(_('instance %s:not booted'), instance['name'], instance=instance) except Exception: LOG.exception(_("Baremetal assignment is overcommitted."), instance=instance) #(old_ref, new_ref) = db.instance_update_and_get_original( db.instance_update( context, instance['id'], {'vm_state': vm_states.ERROR, 'power_state': power_state.FAILED}) #notifications.send_update(context, old_ref, new_ref) timer.stop() timer.f = _wait_for_boot return timer.start(interval=0.5)
def start(self): vcs_string = version.version_string_with_vcs() logging.audit(_('Starting %(topic)s node (version %(vcs_string)s)'), { 'topic': self.topic, 'vcs_string': vcs_string }) self.manager.init_host() self.model_disconnected = False ctxt = context.get_admin_context() try: service_ref = db.service_get_by_args(ctxt, self.host, self.binary) self.service_id = service_ref['id'] except exception.NotFound: self._create_service_ref(ctxt) if 'nova-compute' == self.binary: self.manager.update_available_resource(ctxt) conn1 = rpc.Connection.instance(new=True) conn2 = rpc.Connection.instance(new=True) conn3 = rpc.Connection.instance(new=True) if self.report_interval: consumer_all = rpc.TopicAdapterConsumer(connection=conn1, topic=self.topic, proxy=self) consumer_node = rpc.TopicAdapterConsumer(connection=conn2, topic='%s.%s' % (self.topic, self.host), proxy=self) fanout = rpc.FanoutAdapterConsumer(connection=conn3, topic=self.topic, proxy=self) self.timers.append(consumer_all.attach_to_eventlet()) self.timers.append(consumer_node.attach_to_eventlet()) self.timers.append(fanout.attach_to_eventlet()) pulse = utils.LoopingCall(self.report_state) pulse.start(interval=self.report_interval, now=False) self.timers.append(pulse) if self.periodic_interval: periodic = utils.LoopingCall(self.periodic_tasks) periodic.start(interval=self.periodic_interval, now=False) self.timers.append(periodic)
def wait_for_task(self, task, id=None): """Return the result of the given task. The task is polled until it completes. Not re-entrant.""" done = event.Event() self.loop = utils.LoopingCall(self._poll_task, id, task, done) self.loop.start(FLAGS.xenapi_task_poll_interval, now=True) rv = done.wait() self.loop.stop() return rv
def start(self): vcs_string = version.version_string_with_vcs() LOG.audit(_('Starting %(topic)s node (version %(vcs_string)s)'), {'topic': self.topic, 'vcs_string': vcs_string}) self.manager.init_host() self.model_disconnected = False ctxt = context.get_admin_context() try: service_ref = db.service_get_by_args(ctxt, self.host, self.binary) self.service_id = service_ref['id'] except exception.NotFound: self._create_service_ref(ctxt) if 'nova-compute' == self.binary: self.manager.update_available_resource(ctxt) self.conn = rpc.create_connection(new=True) LOG.debug(_("Creating Consumer connection for Service %s") % self.topic) # Share this same connection for these Consumers self.conn.create_consumer(self.topic, self, fanout=False) node_topic = '%s.%s' % (self.topic, self.host) self.conn.create_consumer(node_topic, self, fanout=False) self.conn.create_consumer(self.topic, self, fanout=True) # Consume from all consumers in a thread self.conn.consume_in_thread() if self.report_interval: pulse = utils.LoopingCall(self.report_state) pulse.start(interval=self.report_interval, now=False) self.timers.append(pulse) if self.periodic_interval: periodic = utils.LoopingCall(self.periodic_tasks) periodic.start(interval=self.periodic_interval, now=False) self.timers.append(periodic)
def _wait_for_task(self, instance_id, task_ref): """ Return a Deferred that will give the result of the given task. The task is polled until it completes. """ done = event.Event() loop = utils.LoopingCall(self._poll_task, instance_id, task_ref, done) loop.start(FLAGS.vmwareapi_task_poll_interval, now=True) ret_val = done.wait() loop.stop() return ret_val
def reboot(self, instance): timer = utils.LoopingCall(f=None) def _wait_for_reboot(): try: state = self._conn.reboot_domain(instance['name']) if state == power_state.RUNNING: LOG.debug(_('instance %s: rebooted'), instance['name']) timer.stop() except Exception: LOG.exception(_('_wait_for_reboot failed')) timer.stop() timer.f = _wait_for_reboot return timer.start(interval=0.5, now=True)
def wait_for_task(self, task, uuid=None): """Return the result of the given task. The task is polled until it completes.""" done = event.Event() loop = utils.LoopingCall(f=None) def _poll_task(): """Poll the given XenAPI task, and return the result if the action was completed successfully or not. """ try: ctxt = context.get_admin_context() name = self.call_xenapi("task.get_name_label", task) status = self.call_xenapi("task.get_status", task) # Ensure action is never > 255 action = dict(action=name[:255], error=None) log_instance_actions = (FLAGS.xenapi_log_instance_actions and uuid) if log_instance_actions: action["instance_uuid"] = uuid if status == "pending": return elif status == "success": result = self.call_xenapi("task.get_result", task) LOG.info( _("Task [%(name)s] %(task)s status:" " success %(result)s") % locals()) if log_instance_actions: db.instance_action_create(ctxt, action) done.send(_parse_xmlrpc_value(result)) else: error_info = self.call_xenapi("task.get_error_info", task) LOG.warn( _("Task [%(name)s] %(task)s status:" " %(status)s %(error_info)s") % locals()) if log_instance_actions: action["error"] = str(error_info) db.instance_action_create(ctxt, action) done.send_exception(self.XenAPI.Failure(error_info)) except self.XenAPI.Failure, exc: LOG.warn(exc) done.send_exception(*sys.exc_info()) loop.stop()
def join(self, member_id, group_id, service=None): """Join the given service with it's group""" msg = _('DB_Driver: join new ServiceGroup member %(member_id)s to ' 'the %(group_id)s group, service = %(service)s') LOG.debug(msg, locals()) if service is None: raise RuntimeError( _('service is a mandatory argument for DB based' ' ServiceGroup driver')) report_interval = service.report_interval if report_interval: pulse = utils.LoopingCall(self._report_state, service) pulse.start(interval=report_interval, initial_delay=report_interval) return pulse
def _spawn(self, instance, vm_ref): """Spawn a new instance""" LOG.debug(_('Starting VM %s...'), vm_ref) self._start(instance, vm_ref) instance_name = instance.name LOG.info( _('Spawning VM %(instance_name)s created %(vm_ref)s.') % locals()) def _inject_files(): injected_files = instance.injected_files if injected_files: # Check if this is a JSON-encoded string and convert if needed. if isinstance(injected_files, basestring): try: injected_files = json.loads(injected_files) except ValueError: LOG.exception( _("Invalid value for injected_files: '%s'") % injected_files) injected_files = [] # Inject any files, if specified for path, contents in instance.injected_files: LOG.debug(_("Injecting file path: '%s'") % path) self.inject_file(instance, path, contents) # NOTE(armando): Do we really need to do this in virt? # NOTE(tr3buchet): not sure but wherever we do it, we need to call # reset_network afterwards timer = utils.LoopingCall(f=None) def _wait_for_boot(): try: state = self.get_info(instance_name)['state'] db.instance_set_state(context.get_admin_context(), instance['id'], state) if state == power_state.RUNNING: LOG.debug(_('Instance %s: booted'), instance_name) timer.stop() _inject_files() return True except Exception, exc: LOG.warn(exc) LOG.exception(_('instance %s: failed to boot'), instance_name) db.instance_set_state(context.get_admin_context(), instance['id'], power_state.SHUTDOWN) timer.stop() return False
def destroy(self, instance, network_info, block_device_info=None, cleanup=True): timer = utils.LoopingCall(f=None) while True: try: self._conn.destroy_domain(instance['name']) break except Exception as ex: msg = (_("Error encountered when destroying instance " "'%(name)s': %(ex)s") % {"name": instance["name"], "ex": ex}) LOG.debug(msg) break if cleanup: self._cleanup(instance) return True
def spawn(self, context, instance, image_meta, network_info, block_device_info=None): LOG.debug(_("<============= spawn of baremetal =============>")) def basepath(fname='', suffix=''): return os.path.join(FLAGS.instances_path, instance['name'], fname + suffix) bpath = basepath(suffix='') timer = utils.LoopingCall(f=None) xml_dict = self.to_xml_dict(instance, network_info) self._create_image(context, instance, xml_dict, network_info=network_info, block_device_info=block_device_info) LOG.debug(_("instance %s: is building"), instance['name']) LOG.debug(_(xml_dict)) def _wait_for_boot(): try: LOG.debug(_("Key is injected but instance is not running yet")) db.instance_update(context, instance['id'], {'vm_state': vm_states.BUILDING}) state = self._conn.create_domain(xml_dict, bpath) if state == power_state.RUNNING: LOG.debug(_('instance %s: booted'), instance['name']) db.instance_update(context, instance['id'], {'vm_state': vm_states.ACTIVE}) LOG.debug(_('~~~~~~ current state = %s ~~~~~~'), state) LOG.debug(_("instance %s spawned successfully"), instance['name']) else: LOG.debug(_('instance %s:not booted'), instance['name']) except Exception as Exn: LOG.debug(_("Bremetal assignment is overcommitted.")) db.instance_update(context, instance['id'], {'vm_state': vm_states.OVERCOMMIT, 'power_state': power_state.SUSPENDED}) timer.stop() timer.f = _wait_for_boot return timer.start(interval=0.5, now=True)
def wait_for_task(self, task, id=None): """Return the result of the given task. The task is polled until it completes.""" done = event.Event() loop = utils.LoopingCall(f=None) def _poll_task(): """Poll the given XenAPI task, and return the result if the action was completed successfully or not. """ try: name = self._session.xenapi.task.get_name_label(task) status = self._session.xenapi.task.get_status(task) if id: action = dict( instance_id=int(id), action=name[0:255], # Ensure action is never > 255 error=None) if status == "pending": return elif status == "success": result = self._session.xenapi.task.get_result(task) LOG.info( _("Task [%(name)s] %(task)s status:" " success %(result)s") % locals()) done.send(_parse_xmlrpc_value(result)) else: error_info = self._session.xenapi.task.get_error_info(task) action["error"] = str(error_info) LOG.warn( _("Task [%(name)s] %(task)s status:" " %(status)s %(error_info)s") % locals()) done.send_exception(self.XenAPI.Failure(error_info)) if id: db.instance_action_create(context.get_admin_context(), action) except self.XenAPI.Failure, exc: LOG.warn(exc) done.send_exception(*sys.exc_info()) loop.stop()
def wait_for_vhd_coalesce(session, instance_id, sr_ref, vdi_ref, original_parent_uuid): """ Spin until the parent VHD is coalesced into its parent VHD Before coalesce: * original_parent_vhd * parent_vhd snapshot Atter coalesce: * parent_vhd snapshot """ max_attempts = FLAGS.xenapi_vhd_coalesce_max_attempts attempts = {'counter': 0} def _poll_vhds(): attempts['counter'] += 1 if attempts['counter'] > max_attempts: counter = attempts['counter'] msg = (_("VHD coalesce attempts exceeded (%(counter)d >" " %(max_attempts)d), giving up...") % locals()) raise exception.Error(msg) VMHelper.scan_sr(session, instance_id, sr_ref) parent_uuid = get_vhd_parent_uuid(session, vdi_ref) if original_parent_uuid and (parent_uuid != original_parent_uuid): LOG.debug( _("Parent %(parent_uuid)s doesn't match original parent" " %(original_parent_uuid)s, waiting for coalesce...") % locals()) else: # Breakout of the loop (normally) and return the parent_uuid raise utils.LoopingCallDone(parent_uuid) loop = utils.LoopingCall(_poll_vhds) loop.start(FLAGS.xenapi_vhd_coalesce_poll_interval, now=True) parent_uuid = loop.wait() return parent_uuid
def attach_to_eventlet(self): """Only needed for unit tests!""" timer = utils.LoopingCall(self.fetch, enable_callbacks=True) timer.start(0.1) return timer
def __init__(self, scheduler_driver=None, *args, **kwargs): super(VNCProxyAuthManager, self).__init__(*args, **kwargs) self.tokens = {} utils.LoopingCall(self._delete_expired_tokens).start(1)
def __init__(self, app): self.app = app self.token_cache = {} utils.LoopingCall(self.delete_expired_cache_items).start(1)