def prepare(self, task): """Prepare the deployment environment for this task's node. Generates the TFTP configuration for PXE-booting both the deployment and user images, fetches the TFTP image from Glance and add it to the local cache. :param task: a TaskManager instance containing the node to act on. :raises: NetworkError: if the previous cleaning ports cannot be removed or if new cleaning ports cannot be created. :raises: InvalidParameterValue when the wrong power state is specified or the wrong driver info is specified for power management. :raises: StorageError If the storage driver is unable to attach the configured volumes. :raises: other exceptions by the node's power driver if something wrong occurred during the power action. :raises: any boot interface's prepare_ramdisk exceptions. """ node = task.node deploy_utils.populate_storage_driver_internal_info(task) if node.provision_state in [states.ACTIVE, states.ADOPTING]: task.driver.boot.prepare_instance(task) else: if node.provision_state == states.DEPLOYING: fast_track_deploy = manager_utils.is_fast_track(task) if fast_track_deploy: # The agent has already recently checked in and we are # configured to take that as an indicator that we can # skip ahead. LOG.debug( 'The agent for node %(node)s has recently ' 'checked in, and the node power will remain ' 'unmodified.', {'node': task.node.uuid}) else: # Adding the node to provisioning network so that the dhcp # options get added for the provisioning port. manager_utils.node_power_action(task, states.POWER_OFF) # NOTE(vdrok): in case of rebuild, we have tenant network # already configured, unbind tenant ports if present if task.driver.storage.should_write_image(task): if not fast_track_deploy: power_state_to_restore = ( manager_utils.power_on_node_if_needed(task)) task.driver.network.unconfigure_tenant_networks(task) task.driver.network.add_provisioning_network(task) if not fast_track_deploy: manager_utils.restore_power_state_if_needed( task, power_state_to_restore) task.driver.storage.attach_volumes(task) if (not task.driver.storage.should_write_image(task) or fast_track_deploy): # We have nothing else to do as this is handled in the # backend storage system, and we can return to the caller # as we do not need to boot the agent to deploy. # Alternatively, we are in a fast track deployment # and have nothing else to do. return deploy_opts = deploy_utils.build_agent_options(node) task.driver.boot.prepare_ramdisk(task, deploy_opts)
def prepare(self, task): """Prepare the deployment environment for this task's node. Generates the TFTP configuration for PXE-booting both the deployment and user images, fetches the TFTP image from Glance and add it to the local cache. :param task: a TaskManager instance containing the node to act on. :raises: NetworkError: if the previous cleaning ports cannot be removed or if new cleaning ports cannot be created. :raises: InvalidParameterValue when the wrong power state is specified or the wrong driver info is specified for power management. :raises: StorageError If the storage driver is unable to attach the configured volumes. :raises: other exceptions by the node's power driver if something wrong occurred during the power action. :raises: any boot interface's prepare_ramdisk exceptions. """ node = task.node deploy_utils.populate_storage_driver_internal_info(task) if node.provision_state in [states.ACTIVE, states.ADOPTING]: task.driver.boot.prepare_instance(task) else: if node.provision_state == states.DEPLOYING: fast_track_deploy = manager_utils.is_fast_track(task) if fast_track_deploy: # The agent has already recently checked in and we are # configured to take that as an indicator that we can # skip ahead. LOG.debug('The agent for node %(node)s has recently ' 'checked in, and the node power will remain ' 'unmodified.', {'node': task.node.uuid}) else: # Adding the node to provisioning network so that the dhcp # options get added for the provisioning port. manager_utils.node_power_action(task, states.POWER_OFF) # NOTE(vdrok): in case of rebuild, we have tenant network # already configured, unbind tenant ports if present if task.driver.storage.should_write_image(task): if not fast_track_deploy: power_state_to_restore = ( manager_utils.power_on_node_if_needed(task)) task.driver.network.unconfigure_tenant_networks(task) task.driver.network.add_provisioning_network(task) if not fast_track_deploy: manager_utils.restore_power_state_if_needed( task, power_state_to_restore) task.driver.storage.attach_volumes(task) if (not task.driver.storage.should_write_image(task) or fast_track_deploy): # We have nothing else to do as this is handled in the # backend storage system, and we can return to the caller # as we do not need to boot the agent to deploy. # Alternatively, we are in a fast track deployment # and have nothing else to do. return deploy_opts = deploy_utils.build_agent_options(node) task.driver.boot.prepare_ramdisk(task, deploy_opts)
def prepare(self, task): node = task.node # Log a warning if the boot_option is wrong... and # otherwise reset it. boot_option = deploy_utils.get_boot_option(node) if boot_option != 'ramdisk': LOG.warning( 'Incorrect "boot_option" set for node %(node)s ' 'and will be overridden to "ramdisk" as to ' 'match the deploy interface. Found: %(boot_opt)s.', { 'node': node.uuid, 'boot_opt': boot_option }) i_info = task.node.instance_info i_info.update({'capabilities': {'boot_option': 'ramdisk'}}) node.instance_info = i_info node.save() deploy_utils.populate_storage_driver_internal_info(task) if node.provision_state == states.DEPLOYING: # Ask the network interface to validate itself so # we can ensure we are able to proceed. task.driver.network.validate(task) manager_utils.node_power_action(task, states.POWER_OFF) # NOTE(TheJulia): If this was any other interface, we would # unconfigure tenant networks, add provisioning networks, etc. task.driver.storage.attach_volumes(task) if node.provision_state in (states.ACTIVE, states.UNRESCUING): # In the event of takeover or unrescue. task.driver.boot.prepare_instance(task)
def prepare(self, task): """Prepare the deployment environment for this task's node. Generates the TFTP configuration for PXE-booting both the deployment and user images, fetches the TFTP image from Glance and add it to the local cache. :param task: a TaskManager instance containing the node to act on. :raises: NetworkError: if the previous cleaning ports cannot be removed or if new cleaning ports cannot be created. :raises: InvalidParameterValue when the wrong power state is specified or the wrong driver info is specified for power management. :raises: StorageError If the storage driver is unable to attach the configured volumes. :raises: other exceptions by the node's power driver if something wrong occurred during the power action. :raises: any boot interface's prepare_ramdisk exceptions. """ node = task.node deploy_utils.populate_storage_driver_internal_info(task) if node.provision_state in [states.ACTIVE, states.ADOPTING]: task.driver.boot.prepare_instance(task) else: if node.provision_state == states.DEPLOYING: # Adding the node to provisioning network so that the dhcp # options get added for the provisioning port. manager_utils.node_power_action(task, states.POWER_OFF) # NOTE(vdrok): in case of rebuild, we have tenant network # already configured, unbind tenant ports if present task.driver.network.unconfigure_tenant_networks(task) task.driver.network.add_provisioning_network(task) task.driver.storage.attach_volumes(task) deploy_opts = deploy_utils.build_agent_options(node) task.driver.boot.prepare_ramdisk(task, deploy_opts)
def prepare(self, task): node = task.node # Log a warning if the boot_option is wrong... and # otherwise reset it. boot_option = deploy_utils.get_boot_option(node) if boot_option != 'ramdisk': LOG.warning('Incorrect "boot_option" set for node %(node)s ' 'and will be overridden to "ramdisk" as to ' 'match the deploy interface. Found: %(boot_opt)s.', {'node': node.uuid, 'boot_opt': boot_option}) i_info = task.node.instance_info i_info.update({'capabilities': {'boot_option': 'ramdisk'}}) node.instance_info = i_info node.save() deploy_utils.populate_storage_driver_internal_info(task) if node.provision_state == states.DEPLOYING: # Ask the network interface to validate itself so # we can ensure we are able to proceed. task.driver.network.validate(task) manager_utils.node_power_action(task, states.POWER_OFF) # NOTE(TheJulia): If this was any other interface, we would # unconfigure tenant networks, add provisioning networks, etc. task.driver.storage.attach_volumes(task) if node.provision_state in (states.ACTIVE, states.UNRESCUING): # In the event of takeover or unrescue. task.driver.boot.prepare_instance(task)
def prepare(self, task): node = task.node deploy_utils.populate_storage_driver_internal_info(task) if node.provision_state == states.DEPLOYING: # Ask the network interface to validate itself so # we can ensure we are able to proceed. task.driver.network.validate(task) manager_utils.node_power_action(task, states.POWER_OFF) # NOTE(TheJulia): If this was any other interface, we would # unconfigure tenant networks, add provisioning networks, etc. task.driver.storage.attach_volumes(task) if node.provision_state in (states.ACTIVE, states.UNRESCUING): # In the event of takeover or unrescue. task.driver.boot.prepare_instance(task)
def prepare(self, task): """Prepare the deployment environment for this node. :param task: a TaskManager instance. :raises: NetworkError: if the previous cleaning ports cannot be removed or if new cleaning ports cannot be created. :raises: InvalidParameterValue when the wrong power state is specified or the wrong driver info is specified for power management. :raises: StorageError If the storage driver is unable to attach the configured volumes. :raises: other exceptions by the node's power driver if something wrong occurred during the power action. :raises: exception.ImageRefValidationFailed if image_source is not Glance href and is not HTTP(S) URL. :raises: any boot interface's prepare_ramdisk exceptions. """ node = task.node deploy_utils.populate_storage_driver_internal_info(task) if node.provision_state == states.DEPLOYING: # Adding the node to provisioning network so that the dhcp # options get added for the provisioning port. manager_utils.node_power_action(task, states.POWER_OFF) if task.driver.storage.should_write_image(task): # NOTE(vdrok): in case of rebuild, we have tenant network # already configured, unbind tenant ports if present task.driver.network.unconfigure_tenant_networks(task) task.driver.network.add_provisioning_network(task) # Signal to storage driver to attach volumes task.driver.storage.attach_volumes(task) if not task.driver.storage.should_write_image(task): # We have nothing else to do as this is handled in the # backend storage system, and we can return to the caller # as we do not need to boot the agent to deploy. return if node.provision_state in (states.ACTIVE, states.UNRESCUING): # Call is due to conductor takeover task.driver.boot.prepare_instance(task) elif node.provision_state != states.ADOPTING: if node.provision_state not in (states.RESCUING, states.RESCUEWAIT, states.RESCUE, states.RESCUEFAIL): node.instance_info = ( deploy_utils.build_instance_info_for_deploy(task)) node.save() if CONF.agent.manage_agent_boot: deploy_opts = deploy_utils.build_agent_options(node) task.driver.boot.prepare_ramdisk(task, deploy_opts)
def prepare(self, task): """Prepare the deployment environment for this node. :param task: a TaskManager instance. :raises: NetworkError: if the previous cleaning ports cannot be removed or if new cleaning ports cannot be created. :raises: InvalidParameterValue when the wrong power state is specified or the wrong driver info is specified for power management. :raises: StorageError If the storage driver is unable to attach the configured volumes. :raises: other exceptions by the node's power driver if something wrong occurred during the power action. :raises: exception.ImageRefValidationFailed if image_source is not Glance href and is not HTTP(S) URL. :raises: any boot interface's prepare_ramdisk exceptions. """ node = task.node deploy_utils.populate_storage_driver_internal_info(task) if node.provision_state == states.DEPLOYING: # Adding the node to provisioning network so that the dhcp # options get added for the provisioning port. manager_utils.node_power_action(task, states.POWER_OFF) if task.driver.storage.should_write_image(task): # NOTE(vdrok): in case of rebuild, we have tenant network # already configured, unbind tenant ports if present task.driver.network.unconfigure_tenant_networks(task) task.driver.network.add_provisioning_network(task) # Signal to storage driver to attach volumes task.driver.storage.attach_volumes(task) if node.provision_state == states.ACTIVE: # Call is due to conductor takeover task.driver.boot.prepare_instance(task) elif node.provision_state != states.ADOPTING: if task.driver.storage.should_write_image(task): instance_info = deploy_utils.build_instance_info_for_deploy( task) node.instance_info = instance_info node.save() if CONF.agent.manage_agent_boot: if task.driver.storage.should_write_image(task): deploy_opts = deploy_utils.build_agent_options(node) else: deploy_opts = None task.driver.boot.prepare_ramdisk(task, deploy_opts)
def prepare(self, task): """Prepare the deployment environment for this task's node. Generates the TFTP configuration for PXE-booting both the deployment and user images, fetches the TFTP image from Glance and add it to the local cache. :param task: a TaskManager instance containing the node to act on. :raises: NetworkError: if the previous cleaning ports cannot be removed or if new cleaning ports cannot be created. :raises: InvalidParameterValue when the wrong power state is specified or the wrong driver info is specified for power management. :raises: StorageError If the storage driver is unable to attach the configured volumes. :raises: other exceptions by the node's power driver if something wrong occurred during the power action. :raises: any boot interface's prepare_ramdisk exceptions. """ node = task.node deploy_utils.populate_storage_driver_internal_info(task) if node.provision_state in [states.ACTIVE, states.ADOPTING]: task.driver.boot.prepare_instance(task) else: if node.provision_state == states.DEPLOYING: # Adding the node to provisioning network so that the dhcp # options get added for the provisioning port. manager_utils.node_power_action(task, states.POWER_OFF) # NOTE(vdrok): in case of rebuild, we have tenant network # already configured, unbind tenant ports if present if task.driver.storage.should_write_image(task): task.driver.network.unconfigure_tenant_networks(task) task.driver.network.add_provisioning_network(task) task.driver.storage.attach_volumes(task) deploy_opts = deploy_utils.build_agent_options(node) task.driver.boot.prepare_ramdisk(task, deploy_opts)
def prepare(self, task): """Prepare the deployment environment for this node. :param task: a TaskManager instance. :raises: NetworkError: if the previous cleaning ports cannot be removed or if new cleaning ports cannot be created. :raises: InvalidParameterValue when the wrong power state is specified or the wrong driver info is specified for power management. :raises: StorageError If the storage driver is unable to attach the configured volumes. :raises: other exceptions by the node's power driver if something wrong occurred during the power action. :raises: exception.ImageRefValidationFailed if image_source is not Glance href and is not HTTP(S) URL. :raises: exception.InvalidParameterValue if network validation fails. :raises: any boot interface's prepare_ramdisk exceptions. """ node = task.node deploy_utils.populate_storage_driver_internal_info(task) if node.provision_state == states.DEPLOYING: # Validate network interface to ensure that it supports boot # options configured on the node. try: task.driver.network.validate(task) except exception.InvalidParameterValue: # For 'neutron' network interface validation will fail # if node is using 'netboot' boot option while provisioning # a whole disk image. Updating 'boot_option' in node's # 'instance_info' to 'local for backward compatibility. # TODO(stendulker): Fail here once the default boot # option is local. with excutils.save_and_reraise_exception(reraise=False) as ctx: instance_info = node.instance_info capabilities = instance_info.get('capabilities', {}) if 'boot_option' not in capabilities: capabilities['boot_option'] = 'local' instance_info['capabilities'] = capabilities node.instance_info = instance_info node.save() # Re-validate the network interface task.driver.network.validate(task) else: ctx.reraise = True # Adding the node to provisioning network so that the dhcp # options get added for the provisioning port. manager_utils.node_power_action(task, states.POWER_OFF) if task.driver.storage.should_write_image(task): # NOTE(vdrok): in case of rebuild, we have tenant network # already configured, unbind tenant ports if present task.driver.network.unconfigure_tenant_networks(task) task.driver.network.add_provisioning_network(task) # Signal to storage driver to attach volumes task.driver.storage.attach_volumes(task) if not task.driver.storage.should_write_image(task): # We have nothing else to do as this is handled in the # backend storage system, and we can return to the caller # as we do not need to boot the agent to deploy. return if node.provision_state in (states.ACTIVE, states.UNRESCUING): # Call is due to conductor takeover task.driver.boot.prepare_instance(task) elif node.provision_state != states.ADOPTING: if node.provision_state not in (states.RESCUING, states.RESCUEWAIT, states.RESCUE, states.RESCUEFAIL): node.instance_info = ( deploy_utils.build_instance_info_for_deploy(task)) node.save() if CONF.agent.manage_agent_boot: deploy_opts = deploy_utils.build_agent_options(node) task.driver.boot.prepare_ramdisk(task, deploy_opts)
def prepare(self, task): """Prepare the deployment environment for this node. :param task: a TaskManager instance. :raises: NetworkError: if the previous cleaning ports cannot be removed or if new cleaning ports cannot be created. :raises: InvalidParameterValue when the wrong power state is specified or the wrong driver info is specified for power management. :raises: StorageError If the storage driver is unable to attach the configured volumes. :raises: other exceptions by the node's power driver if something wrong occurred during the power action. :raises: exception.ImageRefValidationFailed if image_source is not Glance href and is not HTTP(S) URL. :raises: exception.InvalidParameterValue if network validation fails. :raises: any boot interface's prepare_ramdisk exceptions. """ def _update_instance_info(): node.instance_info = ( deploy_utils.build_instance_info_for_deploy(task)) node.save() node = task.node deploy_utils.populate_storage_driver_internal_info(task) if node.provision_state == states.DEPLOYING: # Validate network interface to ensure that it supports boot # options configured on the node. try: task.driver.network.validate(task) except exception.InvalidParameterValue: # For 'neutron' network interface validation will fail # if node is using 'netboot' boot option while provisioning # a whole disk image. Updating 'boot_option' in node's # 'instance_info' to 'local for backward compatibility. # TODO(stendulker): Fail here once the default boot # option is local. # NOTE(TheJulia): Fixing the default boot mode only # masks the failure as the lack of a user definition # can be perceived as both an invalid configuration and # reliance upon the default configuration. The reality # being that in most scenarios, users do not want network # booting, so the changed default should be valid. with excutils.save_and_reraise_exception(reraise=False) as ctx: instance_info = node.instance_info capabilities = utils.parse_instance_info_capabilities(node) if 'boot_option' not in capabilities: capabilities['boot_option'] = 'local' instance_info['capabilities'] = capabilities node.instance_info = instance_info node.save() # Re-validate the network interface task.driver.network.validate(task) else: ctx.reraise = True # Determine if this is a fast track sequence fast_track_deploy = manager_utils.is_fast_track(task) if fast_track_deploy: # The agent has already recently checked in and we are # configured to take that as an indicator that we can # skip ahead. LOG.debug( 'The agent for node %(node)s has recently checked ' 'in, and the node power will remain unmodified.', {'node': task.node.uuid}) else: # Powering off node to setup networking for port and # ensure that the state is reset if it is inadvertently # on for any unknown reason. manager_utils.node_power_action(task, states.POWER_OFF) if task.driver.storage.should_write_image(task): # NOTE(vdrok): in case of rebuild, we have tenant network # already configured, unbind tenant ports if present if not fast_track_deploy: power_state_to_restore = ( manager_utils.power_on_node_if_needed(task)) task.driver.network.unconfigure_tenant_networks(task) task.driver.network.add_provisioning_network(task) if not fast_track_deploy: manager_utils.restore_power_state_if_needed( task, power_state_to_restore) else: # Fast track sequence in progress _update_instance_info() # Signal to storage driver to attach volumes task.driver.storage.attach_volumes(task) if (not task.driver.storage.should_write_image(task) or fast_track_deploy): # We have nothing else to do as this is handled in the # backend storage system, and we can return to the caller # as we do not need to boot the agent to deploy. # Alternatively, we could be in a fast track deployment # and again, we should have nothing to do here. return if node.provision_state in (states.ACTIVE, states.UNRESCUING): # Call is due to conductor takeover task.driver.boot.prepare_instance(task) elif node.provision_state != states.ADOPTING: if node.provision_state not in (states.RESCUING, states.RESCUEWAIT, states.RESCUE, states.RESCUEFAIL): _update_instance_info() if CONF.agent.manage_agent_boot: deploy_opts = deploy_utils.build_agent_options(node) task.driver.boot.prepare_ramdisk(task, deploy_opts)