def wait_for_provision_state(baremetal_client, node_uuid, provision_state, loops=10, sleep=1): """Wait for a given Provisioning state in Ironic Updating the provisioning state is an async operation, we need to wait for it to be completed. :param baremetal_client: Instance of Ironic client :type baremetal_client: ironicclient.v1.client.Client :param node_uuid: The Ironic node UUID :type node_uuid: str :param provision_state: The provisioning state name to wait for :type provision_state: str :param loops: How many times to loop :type loops: int :param sleep: How long to sleep between loops :type sleep: int :raises exceptions.StateTransitionFailed: if node.last_error is set """ for _l in range(0, loops): node = baremetal_client.node.get(node_uuid) if node is None: # The node can't be found in ironic, so we don't need to wait for # the provision state return if node.provision_state == provision_state: return # node.last_error should be None after any successful operation if node.last_error: raise exceptions.StateTransitionFailed( _("Error transitioning node %(uuid)s to provision state " "%(state)s: %(error)s. Now in state %(actual)s.") % { 'uuid': node_uuid, 'state': provision_state, 'error': node.last_error, 'actual': node.provision_state }) time.sleep(sleep) raise exceptions.Timeout( _("Node %(uuid)s did not reach provision state %(state)s. " "Now in state %(actual)s.") % { 'uuid': node_uuid, 'state': provision_state, 'actual': node.provision_state })
def _wait_for_drac_config_jobs(self, nodes): for node in nodes: print("Waiting for DRAC config jobs to finish on node {0}".format( node.uuid)) for _r in range(self.loops): resp = self.bm_client.node.vendor_passthru( node.uuid, 'list_unfinished_jobs', http_method='GET') if not resp.unfinished_jobs: break time.sleep(self.sleep_time) else: msg = ("Timed out waiting for DRAC config jobs on node {0}". format(node.uuid)) raise exceptions.Timeout(msg)
def take_action(self, parsed_args): self.log.debug("take_action(%s)" % parsed_args) queue_name = str(uuid.uuid4()) bm_client = self.app.client_manager.baremetal for node in bm_client.node.list(maintenance=False): # NOTE(bnemec): Ironic won't let us update the node while the # power_state is transitioning. # Make sure we have the current node state, and not a cached one # from the list call above, which may have happened minutes ago. node_detail = bm_client.node.get(node.uuid) if node_detail.power_state is None: self.log.warning( 'Node %s power state is in transition. ' 'Waiting up to %d seconds for it to ' 'complete.', node_detail.uuid, self.loops * self.sleep_time) for _r in range(self.loops): time.sleep(self.sleep_time) node_detail = bm_client.node.get(node.uuid) if node_detail.power_state is not None: break else: msg = ('Timed out waiting for node %s power state.' % node.uuid) raise exceptions.Timeout(msg) baremetal.configure( self.app.client_manager, node_uuids=[node.uuid], queue_name=queue_name, kernel_name=parsed_args.deploy_kernel, ramdisk_name=parsed_args.deploy_ramdisk, root_device=parsed_args.root_device, root_device_minimum_size=parsed_args.root_device_minimum_size, overwrite_root_device_hints=( parsed_args.overwrite_root_device_hints))
def take_action(self, parsed_args): self.log.debug("take_action(%s)" % parsed_args) bm_client = self.app.client_manager.baremetal image_client = self.app.client_manager.image try: kernel_id = osc_utils.find_resource(image_client.images, parsed_args.deploy_kernel).id except AttributeError: self.log.error("Please make sure that an image named \"%s\" exists" " in Glance and is the only image with this name." % parsed_args.deploy_ramdisk) return try: ramdisk_id = osc_utils.find_resource(image_client.images, parsed_args.deploy_ramdisk).id except AttributeError: self.log.error("Please make sure that an image named \"%s\" exists" " in Glance and is the only image with this name." % parsed_args.deploy_ramdisk) return self.log.debug("Using kernel ID: {0} and ramdisk ID: {1}".format( kernel_id, ramdisk_id)) for node in bm_client.node.list(maintenance=False): # NOTE(bnemec): Ironic won't let us update the node while the # power_state is transitioning. # Make sure we have the current node state, and not a cached one # from the list call above, which may have happened minutes ago. node_detail = bm_client.node.get(node.uuid) if node_detail.power_state is None: self.log.warning( 'Node %s power state is in transition. ' 'Waiting up to %d seconds for it to ' 'complete.', node_detail.uuid, self.loops * self.sleep_time) for _r in range(self.loops): time.sleep(self.sleep_time) node_detail = bm_client.node.get(node.uuid) if node_detail.power_state is not None: break else: msg = ('Timed out waiting for node %s power state.' % node.uuid) raise exceptions.Timeout(msg) # Get the full node info capabilities = node_detail.properties.get('capabilities', None) # Only update capabilities to add boot_option if it doesn't exist. if capabilities: if 'boot_option' not in capabilities: capabilities = "boot_option:local,%s" % capabilities else: capabilities = "boot_option:local" self.log.debug("Configuring boot for Node {0}".format(node.uuid)) bm_client.node.update(node.uuid, [ { 'op': 'add', 'path': '/properties/capabilities', 'value': capabilities, }, { 'op': 'add', 'path': '/driver_info/deploy_ramdisk', 'value': ramdisk_id, }, { 'op': 'add', 'path': '/driver_info/deploy_kernel', 'value': kernel_id, }, ]) self._apply_root_device_strategy( node_detail, parsed_args.root_device, parsed_args.root_device_minimum_size, parsed_args.overwrite_root_device_hints)