def _compute_storage_score(self, disks):
        best_effort = False

        if not disks:
            return self.MAX_SCORE, []

        selector = DatastoreSelector.init_datastore_selector(
            self._datastore_manager, self._placeable_datastores())

        disks_placement = DisksPlacement(disks, selector)
        # Place constraint disks first
        place_result = self._constrainted_placement.place(disks_placement)
        if place_result.result == PlaceResultCode.NO_SUCH_RESOURCE:
            raise NoSuchResourceException(
                ResourceType.DISK,
                "Disk placement failed.")
        elif place_result.result == \
                PlaceResultCode.NOT_ENOUGH_DATASTORE_CAPACITY:
            raise NotEnoughDatastoreCapacityException()

        # Try optimal for unconstrainted disks first
        place_result = self._optimal_placement.place(
            place_result.disks_placement)

        if place_result.result == \
                PlaceResultCode.NOT_ENOUGH_DATASTORE_CAPACITY:
            # If it doesn't work then try best effort
            place_result = self._best_effort_placement.place(
                place_result.disks_placement)
            best_effort = True

        # Still NOT_ENOUGH_SYSTEM_RESOURCE then have to give up.
        if place_result.result == \
                PlaceResultCode.NOT_ENOUGH_DATASTORE_CAPACITY:
            raise NotEnoughDatastoreCapacityException()

        # Congrat! Successful placement.

        # Count reserved storage
        free = place_result.disks_placement.selector.total_free_space()
        total = place_result.disks_placement.selector.total_space()
        ratio = float(total-free+self._storage_reserved()) / total

        # If we find an optimal data store (that contains the image needed)
        # and the the data stores will not cross the free space threshold,
        # on admitting the VM, return a high score, so data store score will
        # not be used, if at all.
        if (ratio < self.FREESPACE_THRESHOLD and
                not best_effort):
            return self.MAX_SCORE, place_result.disks_placement.placement_list

        # Compute score
        score = self._score(ratio, True, ResourceType.DATASTORE)

        # If an optimal placement could not be achieved reduce the score for
        # this host
        if best_effort:
            score /= self.NOT_OPTIMAL_DIVIDE_FACTOR

        return score, place_result.disks_placement.placement_list
Exemple #2
0
    def test_constraint_place_engine_constraint_violated(self):
        # Create constraint place engine
        image_datastore = "ds1"
        image_datastores = [{"name": image_datastore, "used_for_vms": True}]
        option = PlacementOption(1, 1, image_datastores)
        ds_map = {image_datastore: DatastoreInfo(5, 0)}
        ds_mgr = self.create_datastore_manager(ds_map, image_datastores)
        engine = ConstraintDiskPlaceEngine(ds_mgr, option)
        ds = engine.placeable_datastores()
        selector = DatastoreSelector.init_datastore_selector(ds_mgr, ds)

        # Try place
        disks = [
            Disk(disk_id="ds1",
                 capacity_gb=1,
                 constraints=[
                     ResourceConstraint(ResourceConstraintType.DATASTORE,
                                        ["ds2"])
                 ]),
        ]
        place_result = engine.place(DisksPlacement(disks, selector))

        # Verify place result
        assert_that(place_result.result,
                    equal_to(PlaceResultCode.NO_SUCH_RESOURCE))
    def test_optimal_place_engine(self, result, ratio, disk_sizes,
                                  use_image_ds):
        # Create optimal place engine
        image_datastore = "datastore_id_1"
        image_datastores = [{"name": image_datastore,
                             "used_for_vms": use_image_ds}]
        option = PlacementOption(1, 1, image_datastores)
        ds_map = {"datastore_id_1": DatastoreInfo(1 * 1024, 0),
                  "datastore_id_2": DatastoreInfo(2 * 1024, 0),
                  "datastore_id_3": DatastoreInfo(3 * 1024, 0)}
        ds_mgr = self.create_datastore_manager(ds_map, image_datastore)

        engine = OptimalPlaceEngine(ds_mgr, option)
        ds = engine.placeable_datastores()
        selector = DatastoreSelector.init_datastore_selector(ds_mgr, ds)
        disks_placement = DisksPlacement(self.create_disks(disk_sizes),
                                         selector)

        # Verify place result
        place_result = engine.place(disks_placement)
        assert_that(place_result.result, equal_to(result))
        assert_that(place_result.disks_placement.selector.ratio(),
                    equal_to(ratio))

        # Verify placements
        if disk_sizes and place_result.result == PlaceResultCode.OK:
            placement_list = place_result.disks_placement.placement_list
            assert_that(placement_list, has_length(1))
            assert_that(placement_list[0].type,
                        equal_to(AgentResourcePlacement.DISK))
            assert_that(placement_list[0].container_id,
                        equal_to("datastore_id_3"))
    def test_best_effort_place_engine(self, result, ratio, disk_sizes, places,
                                      use_image_ds):
        # Create best effort place engine
        image_datastore = "ds1"
        image_datastores = [{"name": image_datastore,
                             "used_for_vms": use_image_ds}]
        option = PlacementOption(1, 1, image_datastores)
        ds_map = {image_datastore: DatastoreInfo(10, 0),
                  "ds2": DatastoreInfo(20, 0),
                  "ds3": DatastoreInfo(30, 0)}
        ds_mgr = self.create_datastore_manager(ds_map, image_datastore)
        engine = BestEffortPlaceEngine(ds_mgr, option)
        ds = engine.placeable_datastores()
        selector = DatastoreSelector.init_datastore_selector(ds_mgr, ds)
        disks_placement = DisksPlacement(self.create_disks(disk_sizes),
                                         selector)

        # Try place
        place_result = engine.place(disks_placement)

        # Verify place result
        assert_that(place_result.result, equal_to(result))

        # Verify placements
        if disk_sizes and place_result.result == PlaceResultCode.OK:
            assert_that(place_result.disks_placement.selector.ratio(),
                        equal_to(ratio))
            for i, place in enumerate(places):
                placement_list = place_result.disks_placement.placement_list
                assert_that(placement_list[0].type,
                            equal_to(AgentResourcePlacement.DISK))
                assert_that(placement_list[i].container_id,
                            equal_to(place))
    def _compute_storage_score(self, disks):
        best_effort = False

        if not disks:
            return self.MAX_SCORE, []

        selector = DatastoreSelector.init_datastore_selector(
            self._datastore_manager, self._placeable_datastores())

        disks_placement = DisksPlacement(disks, selector)
        # Place constraint disks first
        place_result = self._constrainted_placement.place(disks_placement)
        if place_result.result == PlaceResultCode.NO_SUCH_RESOURCE:
            raise NoSuchResourceException(ResourceType.DISK,
                                          "Disk placement failed.")
        elif place_result.result == \
                PlaceResultCode.NOT_ENOUGH_DATASTORE_CAPACITY:
            raise NotEnoughDatastoreCapacityException()

        # Try optimal for unconstrainted disks first
        place_result = self._optimal_placement.place(
            place_result.disks_placement)

        if place_result.result == \
                PlaceResultCode.NOT_ENOUGH_DATASTORE_CAPACITY:
            # If it doesn't work then try best effort
            place_result = self._best_effort_placement.place(
                place_result.disks_placement)
            best_effort = True

        # Still NOT_ENOUGH_SYSTEM_RESOURCE then have to give up.
        if place_result.result == \
                PlaceResultCode.NOT_ENOUGH_DATASTORE_CAPACITY:
            raise NotEnoughDatastoreCapacityException()

        # Congrat! Successful placement.

        # Count reserved storage
        free = place_result.disks_placement.selector.total_free_space()
        total = place_result.disks_placement.selector.total_space()
        ratio = float(total - free + self._storage_reserved()) / total

        # If we find an optimal data store (that contains the image needed)
        # and the the data stores will not cross the free space threshold,
        # on admitting the VM, return a high score, so data store score will
        # not be used, if at all.
        if (ratio < self.FREESPACE_THRESHOLD and not best_effort):
            return self.MAX_SCORE, place_result.disks_placement.placement_list

        # Compute score
        score = self._score(ratio, True, ResourceType.DATASTORE)

        # If an optimal placement could not be achieved reduce the score for
        # this host
        if best_effort:
            score /= self.NOT_OPTIMAL_DIVIDE_FACTOR

        return score, place_result.disks_placement.placement_list
Exemple #6
0
    def test_constraint_place_engine(self):
        # Create constraint place engine
        image_datastore = "ds1"
        image_datastores = [{"name": image_datastore, "used_for_vms": True}]
        option = PlacementOption(1, 1, image_datastores)
        ds_map = {
            image_datastore: DatastoreInfo(10, 0),
            "ds2": DatastoreInfo(20, 0),
            "ds3": DatastoreInfo(30, 0)
        }
        ds_mgr = self.create_datastore_manager(ds_map, image_datastore)
        engine = ConstraintDiskPlaceEngine(ds_mgr, option)
        ds = engine.placeable_datastores()
        selector = DatastoreSelector.init_datastore_selector(ds_mgr, ds)

        # Try place
        disks = [
            Disk(disk_id="disk", capacity_gb=5, constraints=[]),
            Disk(disk_id="disk-in-ds1",
                 capacity_gb=5,
                 constraints=[
                     ResourceConstraint(ResourceConstraintType.DATASTORE,
                                        ["ds1"])
                 ]),
            Disk(disk_id="disk-in-ds2",
                 capacity_gb=5,
                 constraints=[
                     ResourceConstraint(ResourceConstraintType.DATASTORE,
                                        ["ds2"])
                 ]),
            Disk(disk_id="disk-in-ds3",
                 capacity_gb=5,
                 constraints=[
                     ResourceConstraint(ResourceConstraintType.DATASTORE,
                                        ["ds3"])
                 ]),
            Disk(capacity_gb=5, constraints=[]),
        ]
        disks_placement = DisksPlacement(disks, selector)
        place_result = engine.place(disks_placement)

        # Verify place result
        assert_that(place_result.result, equal_to(PlaceResultCode.OK))

        # Verify placement list and unplaced list
        disks_placement = place_result.disks_placement
        assert_that(disks_placement.placement_list, has_length(3))
        assert_that(disks_placement.disks, has_length(2))
        assert_that([d.resource_id for d in disks_placement.placement_list],
                    contains_inanyorder("disk-in-ds1", "disk-in-ds2",
                                        "disk-in-ds3"))
        for placement in disks_placement.placement_list:
            assert_that(placement.type, equal_to(AgentResourcePlacement.DISK))
            assert_that("disk-in-" + placement.container_id,
                        equal_to(placement.resource_id))
    def test_constraint_place_engine(self):
        # Create constraint place engine
        image_datastore = "ds1"
        image_datastores = [{"name": image_datastore,
                             "used_for_vms": True}]
        option = PlacementOption(1, 1, image_datastores)
        ds_map = {image_datastore: DatastoreInfo(10, 0),
                  "ds2": DatastoreInfo(20, 0),
                  "ds3": DatastoreInfo(30, 0)}
        ds_mgr = self.create_datastore_manager(ds_map, image_datastore)
        engine = ConstraintDiskPlaceEngine(ds_mgr, option)
        ds = engine.placeable_datastores()
        selector = DatastoreSelector.init_datastore_selector(ds_mgr, ds)

        # Try place
        disks = [
            Disk(disk_id="disk", capacity_gb=5, constraints=[]),
            Disk(disk_id="disk-in-ds1", capacity_gb=5, constraints=[
                ResourceConstraint(
                    ResourceConstraintType.DATASTORE, ["ds1"])]),
            Disk(disk_id="disk-in-ds2", capacity_gb=5, constraints=[
                ResourceConstraint(
                    ResourceConstraintType.DATASTORE, ["ds2"])]),
            Disk(disk_id="disk-in-ds3", capacity_gb=5, constraints=[
                ResourceConstraint(
                    ResourceConstraintType.DATASTORE, ["ds3"])]),
            Disk(capacity_gb=5, constraints=[]),
        ]
        disks_placement = DisksPlacement(disks, selector)
        place_result = engine.place(disks_placement)

        # Verify place result
        assert_that(place_result.result, equal_to(PlaceResultCode.OK))

        # Verify placement list and unplaced list
        disks_placement = place_result.disks_placement
        assert_that(disks_placement.placement_list, has_length(3))
        assert_that(disks_placement.disks, has_length(2))
        assert_that([d.resource_id for d in disks_placement.placement_list],
                    contains_inanyorder("disk-in-ds1", "disk-in-ds2",
                                        "disk-in-ds3"))
        for placement in disks_placement.placement_list:
            assert_that(placement.type,
                        equal_to(AgentResourcePlacement.DISK))
            assert_that("disk-in-" + placement.container_id,
                        equal_to(placement.resource_id))
    def test_constraint_place_engine_constraint_violated(self):
        # Create constraint place engine
        image_datastore = "ds1"
        image_datastores = [{"name": image_datastore,
                             "used_for_vms": True}]
        option = PlacementOption(1, 1, image_datastores)
        ds_map = {image_datastore: DatastoreInfo(5, 0)}
        ds_mgr = self.create_datastore_manager(ds_map, image_datastores)
        engine = ConstraintDiskPlaceEngine(ds_mgr, option)
        ds = engine.placeable_datastores()
        selector = DatastoreSelector.init_datastore_selector(ds_mgr, ds)

        # Try place
        disks = [
            Disk(disk_id="ds1", capacity_gb=1, constraints=[ResourceConstraint(
                 ResourceConstraintType.DATASTORE, ["ds2"])]),
        ]
        place_result = engine.place(DisksPlacement(disks, selector))

        # Verify place result
        assert_that(place_result.result,
                    equal_to(PlaceResultCode.NO_SUCH_RESOURCE))
Exemple #9
0
    def test_optimal_place_engine(self, result, ratio, disk_sizes,
                                  use_image_ds):
        # Create optimal place engine
        image_datastore = "datastore_id_1"
        image_datastores = [{
            "name": image_datastore,
            "used_for_vms": use_image_ds
        }]
        option = PlacementOption(1, 1, image_datastores)
        ds_map = {
            "datastore_id_1": DatastoreInfo(1 * 1024, 0),
            "datastore_id_2": DatastoreInfo(2 * 1024, 0),
            "datastore_id_3": DatastoreInfo(3 * 1024, 0)
        }
        ds_mgr = self.create_datastore_manager(ds_map, image_datastore)

        engine = OptimalPlaceEngine(ds_mgr, option)
        ds = engine.placeable_datastores()
        selector = DatastoreSelector.init_datastore_selector(ds_mgr, ds)
        disks_placement = DisksPlacement(self.create_disks(disk_sizes),
                                         selector)

        # Verify place result
        place_result = engine.place(disks_placement)
        assert_that(place_result.result, equal_to(result))
        assert_that(place_result.disks_placement.selector.ratio(),
                    equal_to(ratio))

        # Verify placements
        if disk_sizes and place_result.result == PlaceResultCode.OK:
            placement_list = place_result.disks_placement.placement_list
            assert_that(placement_list, has_length(1))
            assert_that(placement_list[0].type,
                        equal_to(AgentResourcePlacement.DISK))
            assert_that(placement_list[0].container_id,
                        equal_to("datastore_id_3"))
Exemple #10
0
    def test_best_effort_place_engine(self, result, ratio, disk_sizes, places,
                                      use_image_ds):
        # Create best effort place engine
        image_datastore = "ds1"
        image_datastores = [{
            "name": image_datastore,
            "used_for_vms": use_image_ds
        }]
        option = PlacementOption(1, 1, image_datastores)
        ds_map = {
            image_datastore: DatastoreInfo(10, 0),
            "ds2": DatastoreInfo(20, 0),
            "ds3": DatastoreInfo(30, 0)
        }
        ds_mgr = self.create_datastore_manager(ds_map, image_datastore)
        engine = BestEffortPlaceEngine(ds_mgr, option)
        ds = engine.placeable_datastores()
        selector = DatastoreSelector.init_datastore_selector(ds_mgr, ds)
        disks_placement = DisksPlacement(self.create_disks(disk_sizes),
                                         selector)

        # Try place
        place_result = engine.place(disks_placement)

        # Verify place result
        assert_that(place_result.result, equal_to(result))

        # Verify placements
        if disk_sizes and place_result.result == PlaceResultCode.OK:
            assert_that(place_result.disks_placement.selector.ratio(),
                        equal_to(ratio))
            for i, place in enumerate(places):
                placement_list = place_result.disks_placement.placement_list
                assert_that(placement_list[0].type,
                            equal_to(AgentResourcePlacement.DISK))
                assert_that(placement_list[i].container_id, equal_to(place))