Esempio n. 1
0
 def test_update_neutron(self, mock_gnvi, mock_updo, mock_wait_neutron):
     opts = pxe_utils.dhcp_options_for_instance()
     mock_gnvi.return_value = {"port-uuid": "vif-uuid"}
     with task_manager.acquire(self.context, self.node.uuid) as task:
         neutron.update_neutron(task, self.node)
     mock_updo.assertCalleOnceWith("vif-uuid", opts)
     mock_wait_neutron.assert_called_once_with(task)
Esempio n. 2
0
File: pxe.py Progetto: n1zyy/ironic
    def deploy(self, task):
        """Start deployment of the task's node'.

        Fetches instance image, creates a temporary keystone token file,
        updates the Neutron DHCP port options for next boot, and issues a
        reboot request to the power driver.
        This causes the node to boot into the deployment ramdisk and triggers
        the next phase of PXE-based deployment via
        VendorPassthru._continue_deploy().

        :param task: a TaskManager instance containing the node to act on.
        :returns: deploy state DEPLOYING.
        """
        _cache_instance_image(task.context, task.node)
        _check_image_size(task)

        # TODO(yuriyz): more secure way needed for pass auth token
        #               to deploy ramdisk
        _create_token_file(task)
        dhcp_opts = pxe_utils.dhcp_options_for_instance()
        neutron.update_neutron(task, dhcp_opts)
        manager_utils.node_set_boot_device(task, 'pxe', persistent=True)
        manager_utils.node_power_action(task, states.REBOOT)

        return states.DEPLOYWAIT
Esempio n. 3
0
    def deploy(self, task):
        """Start deployment of the task's node'.

        Fetches instance image, creates a temporary keystone token file,
        updates the Neutron DHCP port options for next boot, and issues a
        reboot request to the power driver.
        This causes the node to boot into the deployment ramdisk and triggers
        the next phase of PXE-based deployment via
        VendorPassthru._continue_deploy().

        :param task: a TaskManager instance containing the node to act on.
        :returns: deploy state DEPLOYING.
        """
        _cache_instance_image(task.context, task.node)
        _check_image_size(task)

        # TODO(yuriyz): more secure way needed for pass auth token
        #               to deploy ramdisk
        _create_token_file(task)
        dhcp_opts = pxe_utils.dhcp_options_for_instance()
        neutron.update_neutron(task, dhcp_opts)
        manager_utils.node_set_boot_device(task, 'pxe', persistent=True)
        manager_utils.node_power_action(task, states.REBOOT)

        return states.DEPLOYWAIT
Esempio n. 4
0
 def test_update_neutron_no_vif_data(self, mock_gnvi, mock_init,
                                     mock_wait_neutron):
     mock_gnvi.return_value = {}
     with task_manager.acquire(self.context, self.node.uuid) as task:
         neutron.update_neutron(task, self.node)
     self.assertFalse(mock_init.called)
     self.assertFalse(mock_wait_neutron.called)
Esempio n. 5
0
 def test_update_neutron(self, mock_gnvi, mock_updo, mock_wait_neutron):
     opts = pxe_utils.dhcp_options_for_instance()
     mock_gnvi.return_value = {'port-uuid': 'vif-uuid'}
     with task_manager.acquire(self.context, self.node.uuid) as task:
         neutron.update_neutron(task, self.node)
     mock_updo.assertCalleOnceWith('vif-uuid', opts)
     mock_wait_neutron.assert_called_once_with(task)
Esempio n. 6
0
 def test_update_neutron(self, mock_gnvi, mock_updo):
     opts = tftp.dhcp_options_for_instance(CONF.pxe.pxe_bootfile_name)
     mock_gnvi.return_value = {'port-uuid': 'vif-uuid'}
     with task_manager.acquire(self.context,
                               self.node.uuid) as task:
         neutron.update_neutron(task, self.node)
     mock_updo.assertCalleOnceWith('vif-uuid', opts)
Esempio n. 7
0
 def test_update_neutron_some_failures(self, mock_gnvi, mock_updo):
     # confirm update is called twice, one fails, but no exception raised
     mock_gnvi.return_value = {'p1': 'v1', 'p2': 'v2'}
     exc = exception.FailedToUpdateDHCPOptOnPort('fake exception')
     mock_updo.side_effect = [None, exc]
     with task_manager.acquire(self.context,
                               self.node.uuid) as task:
         neutron.update_neutron(task, self.node)
     self.assertEqual(2, mock_updo.call_count)
Esempio n. 8
0
 def test_update_neutron_some_failures(self, mock_gnvi, mock_updo, mock_wait_neutron):
     # confirm update is called twice, one fails, but no exception raised
     mock_gnvi.return_value = {"p1": "v1", "p2": "v2"}
     exc = exception.FailedToUpdateDHCPOptOnPort("fake exception")
     mock_updo.side_effect = [None, exc]
     with task_manager.acquire(self.context, self.node.uuid) as task:
         neutron.update_neutron(task, self.node)
     self.assertEqual(2, mock_updo.call_count)
     mock_wait_neutron.assert_called_once_with(task)
Esempio n. 9
0
 def test_update_neutron_some_failures(self, mock_gnvi, mock_updo,
                                       mock_wait_neutron):
     # confirm update is called twice, one fails, but no exception raised
     mock_gnvi.return_value = {'p1': 'v1', 'p2': 'v2'}
     exc = exception.FailedToUpdateDHCPOptOnPort('fake exception')
     mock_updo.side_effect = [None, exc]
     with task_manager.acquire(self.context, self.node.uuid) as task:
         neutron.update_neutron(task, self.node)
     self.assertEqual(2, mock_updo.call_count)
     mock_wait_neutron.assert_called_once_with(task)
Esempio n. 10
0
    def deploy(self, task):
        """Perform a deployment to a node.

        Perform the necessary work to deploy an image onto the specified node.
        This method will be called after prepare(), which may have already
        performed any preparatory steps, such as pre-caching some data for the
        node.

        :param task: a TaskManager instance.
        :returns: status of the deploy. One of ironic.common.states.
        """
        dhcp_opts = pxe_utils.dhcp_options_for_instance()
        neutron.update_neutron(task, dhcp_opts)
        manager_utils.node_set_boot_device(task, 'pxe', persistent=True)
        manager_utils.node_power_action(task, states.REBOOT)

        return states.DEPLOYWAIT
Esempio n. 11
0
    def take_over(self, task):
        """Take over management of this node from a dead conductor.

        If conductors' hosts maintain a static relationship to nodes, this
        method should be implemented by the driver to allow conductors to
        perform the necessary work during the remapping of nodes to conductors
        when a conductor joins or leaves the cluster.

        For example, the PXE driver has an external dependency:
            Neutron must forward DHCP BOOT requests to a conductor which has
            prepared the tftpboot environment for the given node. When a
            conductor goes offline, another conductor must change this setting
            in Neutron as part of remapping that node's control to itself.
            This is performed within the `takeover` method.

        :param task: a TaskManager instance.
        """
        neutron.update_neutron(task, CONF.agent.agent_pxe_bootfile_name)
Esempio n. 12
0
File: pxe.py Progetto: n1zyy/ironic
 def take_over(self, task):
     dhcp_opts = pxe_utils.dhcp_options_for_instance()
     neutron.update_neutron(task, dhcp_opts)
Esempio n. 13
0
 def take_over(self, task):
     neutron.update_neutron(task, CONF.pxe.pxe_bootfile_name)
Esempio n. 14
0
    def _continue_deploy(self, task, **kwargs):
        """Resume a deployment upon getting POST data from deploy ramdisk.

        This method raises no exceptions because it is intended to be
        invoked asynchronously as a callback from the deploy ramdisk.
        """
        node = task.node
        driver_info = _parse_driver_info(node)

        def _set_failed_state(msg):
            node.provision_state = states.DEPLOYFAIL
            node.target_provision_state = states.NOSTATE
            node.save(task.context)
            try:
                manager_utils.node_power_action(task, states.POWER_OFF)
            except Exception:
                msg = (_('Node %s failed to power off while handling deploy '
                         'failure. This may be a serious condition. Node '
                         'should be removed from Ironic or put in maintenance '
                         'mode until the problem is resolved.') % node.uuid)
                LOG.error(msg)
            finally:
                # NOTE(deva): node_power_action() erases node.last_error
                #             so we need to set it again here.
                node.last_error = msg
                node.save(task.context)

        if node.provision_state != states.DEPLOYWAIT:
            LOG.error(_('Node %s is not waiting to be deployed.') % node.uuid)
            return
        node.provision_state = states.DEPLOYING
        node.save(task.context)
        # remove cached keystone token immediately
        _destroy_token_file(node)

        params = self._get_deploy_info(node, **kwargs)
        ramdisk_error = kwargs.get('error')

        if ramdisk_error:
            LOG.error(
                _('Error returned from PXE deploy ramdisk: %s') %
                ramdisk_error)
            _set_failed_state(_('Failure in PXE deploy ramdisk.'))
            _destroy_images(driver_info, node.uuid)
            return

        LOG.info(
            _('Continuing deployment for node %(node)s, params '
              '%(params)s') % {
                  'node': node.uuid,
                  'params': params
              })

        try:
            deploy_utils.deploy(**params)
        except Exception as e:
            LOG.error(
                _('PXE deploy failed for instance %(instance)s. '
                  'Error: %(error)s') % {
                      'instance': node.instance_uuid,
                      'error': e
                  })
            _set_failed_state(_('PXE driver failed to continue deployment.'))
        else:
            LOG.info(_('Deployment to node %s done') % node.uuid)
            node.provision_state = states.ACTIVE
            node.target_provision_state = states.NOSTATE
            node.save(task.context)

            boot_from_pxe = (node.instance_info.get('kernel')
                             and node.instance_info.get('ramdisk'))

            if not boot_from_pxe:
                # Remove PXE boot configuration in order to boot from disk.
                pxe_utils.clean_up_pxe_config(task)
                neutron.update_neutron(task, None)

        _destroy_images(driver_info, node.uuid)
Esempio n. 15
0
 def take_over(self, task):
     dhcp_opts = pxe_utils.dhcp_options_for_instance()
     neutron.update_neutron(task, dhcp_opts)
Esempio n. 16
0
    def _continue_deploy(self, task, **kwargs):
        """Resume a deployment upon getting POST data from deploy ramdisk.

        This method raises no exceptions because it is intended to be
        invoked asynchronously as a callback from the deploy ramdisk.
        """
        node = task.node
        driver_info = _parse_driver_info(node)

        def _set_failed_state(msg):
            node.provision_state = states.DEPLOYFAIL
            node.target_provision_state = states.NOSTATE
            node.save(task.context)
            try:
                manager_utils.node_power_action(task, states.POWER_OFF)
            except Exception:
                msg = (_('Node %s failed to power off while handling deploy '
                         'failure. This may be a serious condition. Node '
                         'should be removed from Ironic or put in maintenance '
                         'mode until the problem is resolved.') % node.uuid)
                LOG.error(msg)
            finally:
                # NOTE(deva): node_power_action() erases node.last_error
                #             so we need to set it again here.
                node.last_error = msg
                node.save(task.context)

        if node.provision_state != states.DEPLOYWAIT:
            LOG.error(_('Node %s is not waiting to be deployed.') %
                      node.uuid)
            return
        node.provision_state = states.DEPLOYING
        node.save(task.context)
        # remove cached keystone token immediately
        _destroy_token_file(node)

        params = self._get_deploy_info(node, **kwargs)
        ramdisk_error = kwargs.get('error')

        if ramdisk_error:
            LOG.error(_('Error returned from PXE deploy ramdisk: %s')
                    % ramdisk_error)
            _set_failed_state(_('Failure in PXE deploy ramdisk.'))
            _destroy_images(driver_info, node.uuid)
            return

        LOG.info(_('Continuing deployment for node %(node)s, params '
                   '%(params)s') % {'node': node.uuid, 'params': params})

        try:
            deploy_utils.deploy(**params)
        except Exception as e:
            LOG.error(_('PXE deploy failed for instance %(instance)s. '
                        'Error: %(error)s') % {'instance': node.instance_uuid,
                                               'error': e})
            _set_failed_state(_('PXE driver failed to continue deployment.'))
        else:
            LOG.info(_('Deployment to node %s done') % node.uuid)
            node.provision_state = states.ACTIVE
            node.target_provision_state = states.NOSTATE
            node.save(task.context)

            boot_from_pxe = (node.instance_info.get('kernel') and
                             node.instance_info.get('ramdisk'))

            if not boot_from_pxe:
                # Remove PXE boot configuration in order to boot from disk.
                pxe_utils.clean_up_pxe_config(task)
                neutron.update_neutron(task, None)

        _destroy_images(driver_info, node.uuid)
Esempio n. 17
0
 def test_update_neutron_no_vif_data(self, mock_gnvi, mock_init, mock_wait_neutron):
     mock_gnvi.return_value = {}
     with task_manager.acquire(self.context, self.node.uuid) as task:
         neutron.update_neutron(task, self.node)
     self.assertFalse(mock_init.called)
     self.assertFalse(mock_wait_neutron.called)
Esempio n. 18
0
 def test_update_neutron_no_vif_data(self, mock_gnvi, mock_init):
     mock_gnvi.return_value = {}
     with task_manager.acquire(self.context,
                               self.node.uuid) as task:
         neutron.update_neutron(task, self.node)
     mock_init.assert_not_called()