def test_run_with_failing_deploy(self):
        """Check a worker keeps on running even if deploy() raises
        an exception.
        """
        history = []

        def fake_deploy(**params):
            history.append(params)
            # always fail
            raise Exception('test')

        self.stubs.Set(bmdh, 'deploy', fake_deploy)
        self.mox.StubOutWithMock(bm_db, 'bm_node_update')
        # update is called twice inside Worker.run
        for i in range(6):
            bm_db.bm_node_update(mox.IgnoreArg(), mox.IgnoreArg(),
                                 mox.IgnoreArg())
        self.mox.ReplayAll()

        params_list = [{'fake1': ''}, {'fake2': ''}, {'fake3': ''}]
        for (dep_id, params) in enumerate(params_list):
            bmdh.QUEUE.put((dep_id, params))
        self.wait_queue_empty(1)
        self.assertEqual(params_list, history)
        self.mox.VerifyAll()
Beispiel #2
0
    def activate_bootloader(self, context, node, instance, network_info):
        """Configure Tilera boot loader for an instance

        Kernel and ramdisk images are downloaded by cache_tftp_images,
        and stored in /tftpboot/{uuid}/

        This method writes the instances config file, and then creates
        symlinks for each MAC address in the instance.

        By default, the complete layout looks like this:

        /tftpboot/
            ./{uuid}/
                 kernel
            ./fs_node_id/
        """
        image_info = get_tftp_image_info(instance)
        (root_mb, swap_mb) = get_partition_sizes(instance)
        tilera_nfs_path = get_tilera_nfs_path(node['id'])
        image_file_path = get_image_file_path(instance)

        deployment_key = bm_utils.random_alnum(32)
        db.bm_node_update(context, node['id'],
                {'deploy_key': deployment_key,
                 'image_path': image_file_path,
                 'pxe_config_path': tilera_nfs_path,
                 'root_mb': root_mb,
                 'swap_mb': swap_mb})

        if os.path.exists(image_file_path) and \
           os.path.exists(tilera_nfs_path):
            utils.execute('mount', '-o', 'loop', image_file_path,
                tilera_nfs_path, run_as_root=True)
Beispiel #3
0
    def deactivate_bootloader(self, context, node, instance):
        """Delete Tilera bootloader images and config."""
        try:
            db.bm_node_update(
                context,
                node["id"],
                {"deploy_key": None, "image_path": None, "pxe_config_path": None, "root_mb": 0, "swap_mb": 0},
            )
        except exception.NodeNotFound:
            pass

        tilera_nfs_path = get_tilera_nfs_path(node["id"])

        if os.path.ismount(tilera_nfs_path):
            utils.execute("rpc.mountd", run_as_root=True)
            utils.execute("umount", "-f", tilera_nfs_path, run_as_root=True)

        try:
            image_info = get_tftp_image_info(instance)
        except exception.NovaException:
            pass
        else:
            for label in image_info.keys():
                (uuid, path) = image_info[label]
                bm_utils.unlink_without_raise(path)

        try:
            self._collect_mac_addresses(context, node)
        except db_exc.DBError:
            pass

        if os.path.exists(os.path.join(CONF.baremetal.tftp_root, instance["uuid"])):
            bm_utils.rmtree_without_raise(os.path.join(CONF.baremetal.tftp_root, instance["uuid"]))
    def test_run_with_failing_deploy(self):
        """Check a worker keeps on running even if deploy() raises
        an exception.
        """
        history = []

        def fake_deploy(**params):
            history.append(params)
            # always fail
            raise Exception('test')

        self.stubs.Set(bmdh, 'deploy', fake_deploy)
        self.mox.StubOutWithMock(bm_db, 'bm_node_update')
        # update is called twice inside Worker.run
        for i in range(6):
            bm_db.bm_node_update(mox.IgnoreArg(), mox.IgnoreArg(),
                                        mox.IgnoreArg())
        self.mox.ReplayAll()

        params_list = [{'fake1': ''}, {'fake2': ''}, {'fake3': ''}]
        for (dep_id, params) in enumerate(params_list):
            bmdh.QUEUE.put((dep_id, params))
        self.wait_queue_empty(1)
        self.assertEqual(params_list, history)
        self.mox.VerifyAll()
Beispiel #5
0
    def activate_bootloader(self, context, node, instance):
        """Configure Tilera boot loader for an instance

        Kernel and ramdisk images are downloaded by cache_tftp_images,
        and stored in /tftpboot/{uuid}/

        This method writes the instances config file, and then creates
        symlinks for each MAC address in the instance.

        By default, the complete layout looks like this:

        /tftpboot/
            ./{uuid}/
                 kernel
            ./fs_node_id/
        """
        image_info = get_tftp_image_info(instance)
        (root_mb, swap_mb) = get_partition_sizes(instance)
        tilera_nfs_path = get_tilera_nfs_path(node['id'])
        image_file_path = get_image_file_path(instance)

        deployment_key = bm_utils.random_alnum(32)
        db.bm_node_update(context, node['id'],
                {'deploy_key': deployment_key,
                 'image_path': image_file_path,
                 'pxe_config_path': tilera_nfs_path,
                 'root_mb': root_mb,
                 'swap_mb': swap_mb})

        if os.path.exists(image_file_path) and \
           os.path.exists(tilera_nfs_path):
            utils.execute('mount', '-o', 'loop', image_file_path,
                tilera_nfs_path, run_as_root=True)
Beispiel #6
0
    def deactivate_bootloader(self, context, node, instance):
        """Delete PXE bootloader images and config."""
        try:
            db.bm_node_update(
                context,
                node["id"],
                {"deploy_key": None, "image_path": None, "pxe_config_path": None, "root_mb": 0, "swap_mb": 0},
            )
        except exception.NodeNotFound:
            pass

        # NOTE(danms): the flavor extra_specs do not need to be
        # present/correct at deactivate time, so pass something empty
        # to avoid an extra lookup
        flavor = dict(extra_specs={"baremetal:deploy_ramdisk_id": "ignore", "baremetal:deploy_kernel_id": "ignore"})
        try:
            image_info = get_tftp_image_info(instance, flavor)
        except exception.NovaException:
            pass
        else:
            for label in image_info.keys():
                (uuid, path) = image_info[label]
                bm_utils.unlink_without_raise(path)

        bm_utils.unlink_without_raise(get_pxe_config_file_path(instance))
        try:
            macs = self._collect_mac_addresses(context, node)
        except db_exc.DBError:
            pass
        else:
            for mac in macs:
                bm_utils.unlink_without_raise(get_pxe_mac_path(mac))

        bm_utils.rmtree_without_raise(os.path.join(CONF.baremetal.tftp_root, instance["uuid"]))
Beispiel #7
0
    def deactivate_bootloader(self, context, node, instance):
        """Delete PXE bootloader images and config."""
        try:
            db.bm_node_update(context, node['id'],
                    {'deploy_key': None,
                     'image_path': None,
                     'pxe_config_path': None,
                     'root_mb': 0,
                     'swap_mb': 0})
        except exception.NodeNotFound:
            pass

        try:
            image_info = get_tftp_image_info(instance)
        except exception.NovaException:
            pass
        else:
            for label in image_info.keys():
                (uuid, path) = image_info[label]
                bm_utils.unlink_without_raise(path)

        bm_utils.unlink_without_raise(get_pxe_config_file_path(instance))
        try:
            macs = self._collect_mac_addresses(context, node)
        except db_session.DBError:
            pass
        else:
            for mac in macs:
                bm_utils.unlink_without_raise(get_pxe_mac_path(mac))

        bm_utils.rmtree_without_raise(
                os.path.join(CONF.baremetal.tftp_root, instance['uuid']))
Beispiel #8
0
    def test_spawn_node_not_found(self):
        node = self._create_node()
        db.bm_node_update(self.context, node["node"]["id"], {"uuid": "hide-this-node"})

        self.assertRaises(exception.NovaException, self.driver.spawn, **node["spawn_params"])

        row = db.bm_node_get(self.context, node["node"]["id"])
        self.assertEqual(row["task_state"], None)
Beispiel #9
0
    def test_spawn_node_already_associated(self):
        node = self._create_node()
        db.bm_node_update(self.context, node["node"]["id"], {"instance_uuid": "1234-5678"})

        self.assertRaises(exception.NovaException, self.driver.spawn, **node["spawn_params"])

        row = db.bm_node_get(self.context, node["node"]["id"])
        self.assertEqual(row["task_state"], None)
Beispiel #10
0
 def test_node_in_use(self):
     self.instance['node'] = str(self.node_id)
     db.bm_node_update(self.context, self.node_id,
                       {'instance_uuid': 'something'})
     self.assertRaises(
             exception.NovaException,
             self.driver.spawn,
             **self.kwargs)
Beispiel #11
0
 def test_node_in_use(self):
     self.instance['system_metadata'] = [
         _system_metadata('node', str(self.node_id)),
     ]
     db.bm_node_update(self.context, self.node_id,
                       {'instance_uuid': 'something'})
     self.assertRaises(bm_driver.NodeInUse, self.driver.spawn,
                       **self.kwargs)
Beispiel #12
0
def _update_baremetal_state(context, node, instance, state):
    instance_uuid = None
    if instance:
        instance_uuid = instance['uuid']
    bmdb.bm_node_update(context, node['id'],
        {'instance_uuid': instance_uuid,
        'task_state': state,
        })
Beispiel #13
0
def _update_baremetal_state(context, node, instance, state):
    instance_uuid = None
    if instance:
        instance_uuid = instance['uuid']
    bmdb.bm_node_update(context, node['id'], {
        'instance_uuid': instance_uuid,
        'task_state': state,
    })
Beispiel #14
0
    def rebuild(self,
                context,
                instance,
                image_meta,
                injected_files,
                admin_password,
                bdms,
                detach_block_devices,
                attach_block_devices,
                network_info=None,
                recreate=False,
                block_device_info=None,
                preserve_ephemeral=False):
        """Destroy and re-make this instance.

        A 'rebuild' effectively purges all existing data from the system and
        remakes the VM with given 'metadata' and 'personalities'.

        :param context: Security context.
        :param instance: Instance object.
        :param image_meta: Image object returned by nova.image.glance that
                           defines the image from which to boot this instance.
        :param injected_files: User files to inject into instance.
        :param admin_password: Administrator password to set in instance.
        :param bdms: block-device-mappings to use for rebuild
        :param detach_block_devices: function to detach block devices. See
            nova.compute.manager.ComputeManager:_rebuild_default_impl for
            usage.
        :param attach_block_devices: function to attach block devices. See
            nova.compute.manager.ComputeManager:_rebuild_default_impl for
            usage.
        :param network_info:
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
        :param block_device_info: Information about block devices to be
                                  attached to the instance.
        :param recreate: True if instance should be recreated with same disk.
        :param preserve_ephemeral: True if the default ephemeral storage
                                   partition must be preserved on rebuild.
        """

        instance.task_state = task_states.REBUILD_SPAWNING
        instance.save(expected_task_state=[task_states.REBUILDING])

        node_uuid = self._require_node(instance)
        node = db.bm_node_get_by_node_uuid(context, node_uuid)
        db.bm_node_update(
            context, node['id'], {
                'task_state': baremetal_states.BUILDING,
                'preserve_ephemeral': preserve_ephemeral
            })
        self._spawn(node,
                    context,
                    instance,
                    image_meta,
                    injected_files,
                    admin_password,
                    network_info=network_info,
                    block_device_info=block_device_info)
Beispiel #15
0
    def activate_bootloader(self, context, node, instance, network_info):
        """Configure PXE boot loader for an instance

        Kernel and ramdisk images are downloaded by cache_tftp_images,
        and stored in /tftpboot/{uuid}/

        This method writes the instances config file, and then creates
        symlinks for each MAC address in the instance.

        By default, the complete layout looks like this:

        /tftpboot/
            ./{uuid}/
                 kernel
                 ramdisk
                 deploy_kernel
                 deploy_ramdisk
                 config
            ./pxelinux.cfg/
                 {mac} -> ../{uuid}/config
        """
        flavor = objects.Flavor.get_by_id(context, instance["instance_type_id"])
        image_info = get_tftp_image_info(instance, flavor)
        (root_mb, swap_mb, ephemeral_mb) = get_partition_sizes(instance)
        pxe_config_file_path = get_pxe_config_file_path(instance)
        image_file_path = get_image_file_path(instance)

        deployment_key = bm_utils.random_alnum(32)
        deployment_iscsi_iqn = "iqn-%s" % instance["uuid"]
        db.bm_node_update(
            context,
            node["id"],
            {
                "deploy_key": deployment_key,
                "image_path": image_file_path,
                "pxe_config_path": pxe_config_file_path,
                "root_mb": root_mb,
                "swap_mb": swap_mb,
                "ephemeral_mb": ephemeral_mb,
            },
        )
        pxe_config = build_pxe_config(
            node["id"],
            deployment_key,
            deployment_iscsi_iqn,
            image_info["deploy_kernel"][1],
            image_info["deploy_ramdisk"][1],
            image_info["kernel"][1],
            image_info["ramdisk"][1],
            network_info,
        )
        bm_utils.write_to_file(pxe_config_file_path, pxe_config)

        macs = self._collect_mac_addresses(context, node)
        for mac in macs:
            mac_path = get_pxe_mac_path(mac)
            bm_utils.unlink_without_raise(mac_path)
            bm_utils.create_link_without_raise(pxe_config_file_path, mac_path)
Beispiel #16
0
    def test_spawn_node_not_found(self):
        self._create_node()
        db.bm_node_update(self.context, self.node['id'], {'id': 9876})

        self.assertRaises(exception.NovaException, self.driver.spawn,
                          **self.spawn_params)

        row = db.bm_node_get(self.context, 9876)
        self.assertEqual(row['task_state'], None)
Beispiel #17
0
    def activate_bootloader(self, context, node, instance, network_info):
        """Configure PXE boot loader for an instance

        Kernel and ramdisk images are downloaded by cache_tftp_images,
        and stored in /tftpboot/{uuid}/

        This method writes the instances config file, and then creates
        symlinks for each MAC address in the instance.

        By default, the complete layout looks like this:

        /tftpboot/
            ./{uuid}/
                 kernel
                 ramdisk
                 deploy_kernel
                 deploy_ramdisk
                 config
            ./pxelinux.cfg/
                 {mac} -> ../{uuid}/config
        """
        flavor = flavor_obj.Flavor.get_by_id(context,
                                             instance['instance_type_id'])
        image_info = get_tftp_image_info(instance, flavor)
        (root_mb, swap_mb, ephemeral_mb) = get_partition_sizes(instance)
        pxe_config_file_path = get_pxe_config_file_path(instance)
        image_file_path = get_image_file_path(instance)

        deployment_key = bm_utils.random_alnum(32)
        deployment_iscsi_iqn = "iqn-%s" % instance['uuid']
        db.bm_node_update(
            context, node['id'], {
                'deploy_key': deployment_key,
                'image_path': image_file_path,
                'pxe_config_path': pxe_config_file_path,
                'root_mb': root_mb,
                'swap_mb': swap_mb,
                'ephemeral_mb': ephemeral_mb
            })
        pxe_config = build_pxe_config(
            node['id'],
            deployment_key,
            deployment_iscsi_iqn,
            image_info['deploy_kernel'][1],
            image_info['deploy_ramdisk'][1],
            image_info['kernel'][1],
            image_info['ramdisk'][1],
            network_info,
        )
        bm_utils.write_to_file(pxe_config_file_path, pxe_config)

        macs = self._collect_mac_addresses(context, node)
        for mac in macs:
            mac_path = get_pxe_mac_path(mac)
            bm_utils.unlink_without_raise(mac_path)
            bm_utils.create_link_without_raise(pxe_config_file_path, mac_path)
Beispiel #18
0
    def test_spawn_node_not_found(self):
        self._create_node()
        db.bm_node_update(self.context, self.node['id'],
                {'id': 9876})

        self.assertRaises(exception.NovaException,
                self.driver.spawn, **self.spawn_params)

        row = db.bm_node_get(self.context, 9876)
        self.assertEqual(row['task_state'], None)
Beispiel #19
0
def _update_state(context, node, instance, state):
    """Update the node state in baremetal DB

    If instance is not supplied, reset the instance_uuid field for this node.

    """
    values = {'task_state': state}
    if not instance:
        values['instance_uuid'] = None
    db.bm_node_update(context, node['id'], values)
Beispiel #20
0
    def test_spawn_node_not_found(self):
        node = self._create_node()
        db.bm_node_update(self.context, node['node']['id'],
                          {'uuid': 'hide-this-node'})

        self.assertRaises(exception.NovaException, self.driver.spawn,
                          **node['spawn_params'])

        row = db.bm_node_get(self.context, node['node']['id'])
        self.assertIsNone(row['task_state'])
Beispiel #21
0
    def test_spawn_node_not_found(self):
        node = self._create_node()
        db.bm_node_update(self.context, node['node']['id'],
                {'uuid': 'hide-this-node'})

        self.assertRaises(exception.NovaException,
                self.driver.spawn, **node['spawn_params'])

        row = db.bm_node_get(self.context, node['node']['id'])
        self.assertIsNone(row['task_state'])
Beispiel #22
0
    def test_spawn_node_already_associated(self):
        node = self._create_node()
        db.bm_node_update(self.context, node['node']['id'],
                {'instance_uuid': '1234-5678'})

        self.assertRaises(exception.NovaException,
                self.driver.spawn, **node['spawn_params'])

        row = db.bm_node_get(self.context, node['node']['id'])
        self.assertIsNone(row['task_state'])
Beispiel #23
0
def _update_state(context, node, instance, state):
    """Update the node state in baremetal DB

    If instance is not supplied, reset the instance_uuid field for this node.

    """
    values = {'task_state': state}
    if not instance:
        values['instance_uuid'] = None
    db.bm_node_update(context, node['id'], values)
Beispiel #24
0
    def test_spawn_node_already_associated(self):
        node = self._create_node()
        db.bm_node_update(self.context, node['node']['id'],
                          {'instance_uuid': '1234-5678'})

        self.assertRaises(exception.NovaException, self.driver.spawn,
                          **node['spawn_params'])

        row = db.bm_node_get(self.context, node['node']['id'])
        self.assertIsNone(row['task_state'])
Beispiel #25
0
    def test_spawn_node_in_use(self):
        self._create_node()
        db.bm_node_update(self.context, self.node['id'],
                {'instance_uuid': '1234-5678'})

        self.assertRaises(exception.NovaException,
                self.driver.spawn, **self.spawn_params)

        row = db.bm_node_get(self.context, self.node['id'])
        self.assertEqual(row['task_state'], None)
Beispiel #26
0
 def test_node_in_use(self):
     self.instance['system_metadata'] = [
             _system_metadata('node', str(self.node_id)),
             ]
     db.bm_node_update(self.context, self.node_id,
                       {'instance_uuid': 'something'})
     self.assertRaises(
             bm_driver.NodeInUse,
             self.driver.spawn,
             **self.kwargs)
Beispiel #27
0
    def test_spawn_node_in_use(self):
        self._create_node()
        db.bm_node_update(self.context, self.node['id'],
                {'instance_uuid': '1234-5678'})

        self.assertRaises(exception.NovaException,
                self.driver.spawn, **self.spawn_params)

        row = db.bm_node_get(self.context, self.node['id'])
        self.assertEqual(row['task_state'], None)
Beispiel #28
0
    def activate_bootloader(self, context, node, instance, network_info):
        """Configure PXE boot loader for an instance

        Kernel and ramdisk images are downloaded by cache_tftp_images,
        and stored in /tftpboot/{uuid}/

        This method writes the instances config file, and then creates
        symlinks for each MAC address in the instance.

        By default, the complete layout looks like this:

        /tftpboot/
            ./{uuid}/
                 kernel
                 ramdisk
                 deploy_kernel
                 deploy_ramdisk
                 config
            ./pxelinux.cfg/
                 {mac} -> ../{uuid}/config
        """
        instance_type = self.virtapi.flavor_get(
            context, instance['instance_type_id'])
        image_info = get_tftp_image_info(instance, instance_type)
        (root_mb, swap_mb, ephemeral_mb) = get_partition_sizes(instance)
        pxe_config_file_path = get_pxe_config_file_path(instance)
        image_file_path = get_image_file_path(instance)

        deployment_key = bm_utils.random_alnum(32)
        deployment_iscsi_iqn = "iqn-%s" % instance['uuid']
        db.bm_node_update(context, node['id'],
                {'deploy_key': deployment_key,
                 'image_path': image_file_path,
                 'pxe_config_path': pxe_config_file_path,
                 'root_mb': root_mb,
                 'swap_mb': swap_mb,
                 'ephemeral_mb': ephemeral_mb})
        pxe_config = build_pxe_config(
                    node['id'],
                    deployment_key,
                    deployment_iscsi_iqn,
                    image_info['deploy_kernel'][1],
                    image_info['deploy_ramdisk'][1],
                    image_info['kernel'][1],
                    image_info['ramdisk'][1],
                    network_info,
                )
        bm_utils.write_to_file(pxe_config_file_path, pxe_config)

        macs = self._collect_mac_addresses(context, node)
        for mac in macs:
            mac_path = get_pxe_mac_path(mac)
            bm_utils.unlink_without_raise(mac_path)
            bm_utils.create_link_without_raise(pxe_config_file_path, mac_path)
    def rebuild(self, context, instance, image_meta, injected_files,
                admin_password, bdms, detach_block_devices,
                attach_block_devices, network_info=None, recreate=False,
                block_device_info=None, preserve_ephemeral=False):
        """Destroy and re-make this instance.

        A 'rebuild' effectively purges all existing data from the system and
        remakes the VM with given 'metadata' and 'personalities'.

        :param context: Security context.
        :param instance: Instance object.
        :param image_meta: Image object returned by nova.image.glance that
                           defines the image from which to boot this instance.
        :param injected_files: User files to inject into instance.
        :param admin_password: Administrator password to set in instance.
        :param bdms: block-device-mappings to use for rebuild
        :param detach_block_devices: function to detach block devices. See
            nova.compute.manager.ComputeManager:_rebuild_default_impl for
            usage.
        :param attach_block_devices: function to attach block devices. See
            nova.compute.manager.ComputeManager:_rebuild_default_impl for
            usage.
        :param network_info:
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
        :param block_device_info: Information about block devices to be
                                  attached to the instance.
        :param recreate: True if instance should be recreated with same disk.
        :param preserve_ephemeral: True if the default ephemeral storage
                                   partition must be preserved on rebuild.
        """

        instance.task_state = task_states.REBUILD_SPAWNING
        instance.save(expected_task_state=[task_states.REBUILDING])

        node_uuid = self._require_node(instance)
        node = db.bm_node_get_by_node_uuid(context, node_uuid)
        db.bm_node_update(
            context, node['id'],
            {'task_state': baremetal_states.BUILDING,
             'preserve_ephemeral': preserve_ephemeral}
        )
        self._spawn(node, context, instance, image_meta, injected_files,
                    admin_password, network_info=network_info,
                    block_device_info=block_device_info)
Beispiel #30
0
    def deactivate_bootloader(self, context, node, instance):
        """Delete PXE bootloader images and config."""
        try:
            db.bm_node_update(
                context, node['id'], {
                    'deploy_key': None,
                    'image_path': None,
                    'pxe_config_path': None,
                    'root_mb': 0,
                    'swap_mb': 0
                })
        except exception.NodeNotFound:
            pass

        # NOTE(danms): the instance_type extra_specs do not need to be
        # present/correct at deactivate time, so pass something empty
        # to avoid an extra lookup
        instance_type = dict(
            extra_specs={
                'baremetal:deploy_ramdisk_id': 'ignore',
                'baremetal:deploy_kernel_id': 'ignore'
            })
        try:
            image_info = get_tftp_image_info(instance, instance_type)
        except exception.NovaException:
            pass
        else:
            for label in image_info.keys():
                (uuid, path) = image_info[label]
                bm_utils.unlink_without_raise(path)

        bm_utils.unlink_without_raise(get_pxe_config_file_path(instance))
        try:
            macs = self._collect_mac_addresses(context, node)
        except db_exc.DBError:
            pass
        else:
            for mac in macs:
                bm_utils.unlink_without_raise(get_pxe_mac_path(mac))

        bm_utils.rmtree_without_raise(
            os.path.join(CONF.baremetal.tftp_root, instance['uuid']))
    def test_run_calls_deploy(self):
        """Check all queued requests are passed to deploy()."""
        history = []

        def fake_deploy(**params):
            history.append(params)

        self.stubs.Set(bmdh, "deploy", fake_deploy)
        self.mox.StubOutWithMock(bm_db, "bm_node_update")
        # update is called twice inside Worker.run
        for i in range(6):
            bm_db.bm_node_update(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
        self.mox.ReplayAll()

        params_list = [{"fake1": ""}, {"fake2": ""}, {"fake3": ""}]
        for (dep_id, params) in enumerate(params_list):
            bmdh.QUEUE.put((dep_id, params))
        self.wait_queue_empty(1)
        self.assertEqual(params_list, history)
        self.mox.VerifyAll()
    def test_run_calls_deploy(self):
        """Check all queued requests are passed to deploy()."""
        history = []

        def fake_deploy(**params):
            history.append(params)

        self.stubs.Set(bmdh, 'deploy', fake_deploy)
        self.mox.StubOutWithMock(bm_db, 'bm_node_update')
        # update is called twice inside Worker.run
        for i in range(6):
            bm_db.bm_node_update(mox.IgnoreArg(), mox.IgnoreArg(),
                                 mox.IgnoreArg())
        self.mox.ReplayAll()

        params_list = [{'fake1': ''}, {'fake2': ''}, {'fake3': ''}]
        for (dep_id, params) in enumerate(params_list):
            bmdh.QUEUE.put((dep_id, params))
        self.wait_queue_empty(1)
        self.assertEqual(params_list, history)
        self.mox.VerifyAll()
 def run(self):
     while not self.stop:
         try:
             # Set timeout to check self.stop periodically
             (node_id, params) = QUEUE.get(block=True,
                                           timeout=self.queue_timeout)
         except Queue.Empty:
             pass
         else:
             # Requests comes here from BareMetalDeploy.post()
             LOG.info(
                 _('start deployment for node %(node_id)s, '
                   'params %(params)s'), {
                       'node_id': node_id,
                       'params': params
                   })
             context = nova_context.get_admin_context()
             try:
                 db.bm_node_update(
                     context, node_id,
                     {'task_state': baremetal_states.DEPLOYING})
                 deploy(**params)
             except Exception:
                 LOG.exception(_('deployment to node %s failed'), node_id)
                 db.bm_node_update(
                     context, node_id,
                     {'task_state': baremetal_states.DEPLOYFAIL})
             else:
                 LOG.info(_('deployment to node %s done'), node_id)
                 db.bm_node_update(
                     context, node_id,
                     {'task_state': baremetal_states.DEPLOYDONE})
 def run(self):
     while not self.stop:
         try:
             # Set timeout to check self.stop periodically
             (node_id, params) = QUEUE.get(block=True,
                                                 timeout=self.queue_timeout)
         except Queue.Empty:
             pass
         else:
             # Requests comes here from BareMetalDeploy.post()
             LOG.info(_('start deployment for node %(node_id)s, '
                        'params %(params)s') % locals())
             context = nova_context.get_admin_context()
             try:
                 db.bm_node_update(context, node_id,
                       {'task_state': baremetal_states.DEPLOYING})
                 deploy(**params)
             except Exception:
                 LOG.exception(_('deployment to node %s failed') % node_id)
                 db.bm_node_update(context, node_id,
                       {'task_state': baremetal_states.DEPLOYFAIL})
             else:
                 LOG.info(_('deployment to node %s done') % node_id)
                 db.bm_node_update(context, node_id,
                       {'task_state': baremetal_states.DEPLOYDONE})
Beispiel #35
0
    def test_activate_node(self):
        self._create_node()
        self.instance['uuid'] = 'fake-uuid'
        self.flags(pxe_deploy_timeout=1, group='baremetal')

        db.bm_node_update(self.context, 1, {
            'task_state': baremetal_states.DEPLOYING,
            'instance_uuid': 'fake-uuid'
        })

        # test timeout
        self.assertRaises(exception.InstanceDeployFailure,
                          self.driver.activate_node, self.context, self.node,
                          self.instance)

        # test DEPLOYDONE
        db.bm_node_update(self.context, 1,
                          {'task_state': baremetal_states.DEPLOYDONE})
        self.driver.activate_node(self.context, self.node, self.instance)

        # test no deploy -- state is just ACTIVE
        db.bm_node_update(self.context, 1,
                          {'task_state': baremetal_states.ACTIVE})
        self.driver.activate_node(self.context, self.node, self.instance)

        # test node gone
        db.bm_node_destroy(self.context, 1)
        self.assertRaises(exception.InstanceDeployFailure,
                          self.driver.activate_node, self.context, self.node,
                          self.instance)
Beispiel #36
0
    def test_activate_node(self):
        self._create_node()
        self.instance['uuid'] = 'fake-uuid'
        self.flags(pxe_deploy_timeout=1, group='baremetal')

        db.bm_node_update(self.context, 1,
                {'task_state': baremetal_states.DEPLOYING,
                 'instance_uuid': 'fake-uuid'})

        # test timeout
        self.assertRaises(exception.InstanceDeployFailure,
                self.driver.activate_node,
                self.context, self.node, self.instance)

        # test DEPLOYDONE
        db.bm_node_update(self.context, 1,
                {'task_state': baremetal_states.DEPLOYDONE})
        self.driver.activate_node(self.context, self.node, self.instance)

        # test no deploy -- state is just ACTIVE
        db.bm_node_update(self.context, 1,
                {'task_state': baremetal_states.ACTIVE})
        self.driver.activate_node(self.context, self.node, self.instance)

        # test node gone
        db.bm_node_destroy(self.context, 1)
        self.assertRaises(exception.InstanceDeployFailure,
                self.driver.activate_node,
                self.context, self.node, self.instance)
Beispiel #37
0
    def deactivate_bootloader(self, context, node, instance):
        """Delete Tilera bootloader images and config."""
        try:
            db.bm_node_update(
                context, node['id'], {
                    'deploy_key': None,
                    'image_path': None,
                    'pxe_config_path': None,
                    'root_mb': 0,
                    'swap_mb': 0
                })
        except exception.NodeNotFound:
            pass

        tilera_nfs_path = get_tilera_nfs_path(node['id'])

        if os.path.ismount(tilera_nfs_path):
            utils.execute('rpc.mountd', run_as_root=True)
            utils.execute('umount', '-f', tilera_nfs_path, run_as_root=True)

        try:
            image_info = get_tftp_image_info(instance)
        except exception.NovaException:
            pass
        else:
            for label in image_info.keys():
                (uuid, path) = image_info[label]
                bm_utils.unlink_without_raise(path)

        try:
            self._collect_mac_addresses(context, node)
        except db_exc.DBError:
            pass

        if os.path.exists(
                os.path.join(CONF.baremetal.tftp_root, instance['uuid'])):
            bm_utils.rmtree_without_raise(
                os.path.join(CONF.baremetal.tftp_root, instance['uuid']))
Beispiel #38
0
    def activate_bootloader(self, context, node, instance, network_info):
        """Configure Tilera boot loader for an instance

        Kernel and ramdisk images are downloaded by cache_tftp_images,
        and stored in /tftpboot/{uuid}/

        This method writes the instances config file, and then creates
        symlinks for each MAC address in the instance.

        By default, the complete layout looks like this::

            /tftpboot/
                ./{uuid}/
                     kernel
                ./fs_node_id/

        """
        get_tftp_image_info(instance)
        (root_mb, swap_mb) = get_partition_sizes(instance)
        tilera_nfs_path = get_tilera_nfs_path(node["id"])
        image_file_path = get_image_file_path(instance)

        deployment_key = bm_utils.random_alnum(32)
        db.bm_node_update(
            context,
            node["id"],
            {
                "deploy_key": deployment_key,
                "image_path": image_file_path,
                "pxe_config_path": tilera_nfs_path,
                "root_mb": root_mb,
                "swap_mb": swap_mb,
            },
        )

        if os.path.exists(image_file_path) and os.path.exists(tilera_nfs_path):
            utils.execute("mount", "-o", "loop", image_file_path, tilera_nfs_path, run_as_root=True)
Beispiel #39
0
    def test_activate_node(self):
        self._create_node()
        self.instance["uuid"] = "fake-uuid"

        db.bm_node_update(self.context, 1, {"task_state": baremetal_states.DEPLOYING, "instance_uuid": "fake-uuid"})

        # test DEPLOYDONE
        db.bm_node_update(self.context, 1, {"task_state": baremetal_states.DEPLOYDONE})
        self.driver.activate_node(self.context, self.node, self.instance)

        # test no deploy -- state is just ACTIVE
        db.bm_node_update(self.context, 1, {"task_state": baremetal_states.ACTIVE})
        self.driver.activate_node(self.context, self.node, self.instance)

        # test node gone
        db.bm_node_destroy(self.context, 1)
        self.assertRaises(
            exception.InstanceDeployFailure, self.driver.activate_node, self.context, self.node, self.instance
        )
Beispiel #40
0
 def update_2prepared(context, node, instance, state):
     row = db.bm_node_get(context, node['id'])
     self.assertEqual(row['task_state'], baremetal_states.BUILDING)
     db.bm_node_update(context, node['id'],
                       {'task_state': baremetal_states.PREPARED})
Beispiel #41
0
 def update_2prepared(context, node, instance, state):
     row = db.bm_node_get(context, node['id'])
     self.assertEqual(row['task_state'], baremetal_states.BUILDING)
     db.bm_node_update(
         context, node['id'],
         {'task_state': baremetal_states.PREPARED})