def test_register_parser() -> None:
    class SimpleConstraint(BaseNodeConstraint):
        def __init__(self, name: str = "defaultname") -> None:
            self.name = name

        def satisfied_by_node(self, node: Node) -> SatisfiedResult:
            return SatisfiedResult("success")

        def to_dict(self) -> Dict:
            return {"custom-parser": self.name}

        @staticmethod
        def from_dict(d: Dict) -> "SimpleConstraint":
            assert "custom-parser" in d
            return SimpleConstraint(d["custom-parser"])

        def __str__(self) -> str:
            return "SimpleConstraint({})".format(self.name)

        def __eq__(self, other: object) -> bool:
            if not isinstance(other, SimpleConstraint):
                return False
            return self.name == other.name

    register_parser("custom-parser", SimpleConstraint.from_dict)

    assert get_constraints([{"custom-parser": "a"}]) == [SimpleConstraint("a")]
示例#2
0
    def __init__(
        self,
        name: Optional[Union[str, ht.JobId]] = None,
        constraints: Any = None,
        iterations: int = 1,
        node_count: int = 0,
        colocated: bool = False,
        packing_strategy: Optional[PackingStrategyType] = None,
        executing_hostnames: Optional[List[ht.Hostname]] = None,
    ) -> None:
        if not name:
            global _default_job_id
            _default_job_id = _default_job_id + 1
            name = ht.JobId(str(_default_job_id))

        _check_type(name=name, type=str)

        if packing_strategy is not None:
            assert PackingStrategy.is_valid(
                packing_strategy), "Invalid packing_strategy {}".format(
                    packing_strategy)
            self.__packing_strategy = packing_strategy
        elif node_count > 0:
            self.__packing_strategy = PackingStrategy.SCATTER
        else:
            self.__packing_strategy = PackingStrategy.PACK

        self.__name = ht.JobId(name)

        _check_type(iterations=iterations, type=int)

        self.__iterations = iterations
        self.__iterations_remaining = iterations

        _check_type(node_count=node_count, type=int)
        self.__node_count = node_count
        self.__nodes_remaining = node_count

        _check_type(colocated=colocated, type=bool)
        self.__colocated = colocated
        self.__metadata: Dict[str, Any] = {}

        if constraints is None:
            constraints = []

        if not isinstance(constraints, list):
            constraints = [constraints]

        self._constraints = get_constraints(constraints)

        def update_assignment_id(constraints: Iterable[Any]) -> None:
            for constraint in constraints:
                assert constraint is not None
                if hasattr(constraint, "assignment_id"):
                    constraint.assignment_id = self.name
                update_assignment_id(constraint.get_children())

        update_assignment_id(self._constraints)

        self.__executing_hostnames = executing_hostnames or []
 def __init__(
     self,
     name: str,
     constraints: Optional[List[Constraint]] = None,
     members: Optional[List[str]] = None,
 ) -> None:
     self.name = name
     self.constraints = get_constraints(constraints or [])
     self.members: List[str] = members or []
示例#4
0
def _mpi_job(job_name="1", nodes=1, placeby="pg", resources=None):
    resources = resources or {"ncpus": 2}
    constraints = get_constraints([resources])
    constraints.append(InAPlacementGroup())
    constraints.append(ExclusiveNode())
    return Job(
        job_name,
        constraints=constraints,
        node_count=nodes,
        colocated=True,
    )
示例#5
0
def _parse_contraint(constraint_expr: str) -> List[NodeConstraint]:
    try:
        constraint_parsed = json.loads(constraint_expr)
    except Exception as e:
        print(
            "Could not parse constraint as json '{}' - {}".format(constraint_expr, e),
            file=sys.stderr,
        )
        sys.exit(1)

    if not isinstance(constraint_parsed, list):
        constraint_parsed = [constraint_parsed]

    return get_constraints(constraint_parsed)
示例#6
0
def validate_default_hostgroups(
    config: Dict, ge_env: GridEngineEnvironment, warn: WarnFunction,
) -> bool:
    default_hostgroups = config.get("gridengine", {}).get("default_hostgroups", [])
    failure = False
    for dh in default_hostgroups:
        # ensure it is a {"select": {}, "hostgroups": []} expression
        if set(list(dh.keys())) != set(["select", "hostgroups"]):
            warn(
                "    Invalid entry in gridengine.default_hostgroups. Expected select and hostgroups as keys. %s",
                dh,
            )
            failure = True
            continue

        try:
            constraints.get_constraints(dh["select"])
        except Exception as e:
            warn("     Invalid select constraint: %s - %s", dh["select"], e)
            failure = True
            continue

        hostgroups = dh["hostgroups"]
        if isinstance(hostgroups, str):
            hostgroups = [hostgroups]

        for hg in hostgroups:
            if hg not in ge_env.hostgroups:
                warn(
                    "    Unknown hostgroup %s. See gridengine.default_hostgroups - %s",
                    hg,
                    dh,
                )
                failure = True

    return not failure
def read_hostgroups(autoscale_config: Dict, qbin: QBin) -> List[Hostgroup]:
    # map each host (lowercase) to its set of hostgroups
    ret: List[Hostgroup] = []

    hg_config = autoscale_config.get("gridengine", {}).get("hostgroups", {})

    for hg_name in qbin.qconf(["-shgrpl"]).split():
        members = qbin.qconf(["-shgrp_resolved", hg_name]).split()
        members = [h.split(".")[0].lower() for h in members]
        constraints = hg_config.get(hg_name, {}).get("constraints", []) or []

        if not isinstance(constraints, list):
            constraints = [constraints]

        parsed_constraints = constraintslib.get_constraints(constraints)
        hostgroup = Hostgroup(hg_name, parsed_constraints, members)
        ret.append(hostgroup)

    return ret
示例#8
0
def get_node_hostgroups(config: Dict, node: Node) -> List[str]:
    hostgroups_expr = node.metadata.get("gridengine_hostgroups")

    if not hostgroups_expr:
        hostgroups_expr = node.software_configuration.get(
            "gridengine_hostgroups")

    if not hostgroups_expr:
        default_hostgroups = config.get("gridengine",
                                        {}).get("default_hostgroups", [])
        for dh in default_hostgroups:
            if "select" not in dh:
                logging.warning(
                    "Missing key 'select' in gridengine.default_hostgroups %s",
                    dh)
                continue
            if "hostgroups" not in dh:
                logging.warning(
                    "Missing key 'hostgroups' in gridengine.default_hostgroups %s",
                    dh)
                continue
            constraint_list = constraints.get_constraints(dh["select"])
            satisfied = True
            for c in constraint_list:
                if not c.satisfied_by_node(node):
                    satisfied = False
                    break
            if satisfied:
                hostgroups = dh["hostgroups"]
                if isinstance(hostgroups, str):
                    hostgroups = [hostgroups]

                hostgroups_expr = " ".join(hostgroups)
                # set it in metadata so we can output it in the cli
                node.metadata["gridengine_hostgroups"] = hostgroups_expr

    if hostgroups_expr:
        return re.split(",| +", hostgroups_expr)
    return []
示例#9
0
 def add_constraint(self, constraint: typing.Any) -> None:
     if not isinstance(constraint, list):
         constraint = [constraint]
     parsed_cons = get_constraints(constraint)
     self._constraints.extend(parsed_cons)
def test_memory() -> None:
    c = get_constraints([{"memgb": 1}])
    node = SchedulerNode("test", {"memgb": 4.0})
    m = minimum_space(c, node)
    assert isinstance(m, int)
    assert m == 4