in src/hpc/autoscale/job/demandprinter.py [0:0]
def print_demand(self, demand_result: DemandResult) -> None:
rows = []
columns = self.column_names
if not columns:
columns = self._get_all_columns(demand_result.compute_nodes)
if self.output_format == "json":
columns = [c for c in columns if c not in ["hostname_required"]]
else:
columns = [
c
for c in columns
if c not in ["available", "node", "hostname_required"]
]
columns = ["job_ids" if c == "assigned_job_ids" else c for c in columns]
if "name" in columns:
columns.remove("name")
columns.insert(0, "name")
short_columns = [c.split("@")[0] for c in columns]
long_columns = [c.split("@")[-1] for c in columns]
# sort by private ip or the node name
def sort_by_ip_or_name(node: Node) -> Any:
if node.private_ip:
return tuple(map(int, node.private_ip.split(".")))
name_toks = node.name.split("-")
if name_toks[-1].isdigit():
node_index = int(name_toks[-1])
nodearray_ord = [ord(x) for x in node.nodearray]
# 2**31 to make these come after private ips
# then nodearray name, then index
return tuple([2**31] + nodearray_ord + [node_index])
return tuple([-1] + name_toks)
ordered_nodes = sorted(demand_result.compute_nodes, key=sort_by_ip_or_name)
for node in ordered_nodes:
row: List[str] = []
rows.append(row)
for column in long_columns:
# TODO justify - this is a printing function, so this value could be lots of things etc.
value: Any = None
is_from_available = column.startswith("*")
is_ratio = column.startswith("/")
is_slice = "[" in column
if is_from_available or is_ratio:
column = column[1:]
def _slice(v: str) -> str:
return v
slice = _slice
if is_slice:
slice_expr = column[column.index("[") :]
column = column.split("[")[0]
# TODO maybe parse this instead of eval-ing a lambda
if self.long:
slice = lambda v: v # noqa: E731
else:
slice = eval(
"lambda v: v%s if v is not None else v" % slice_expr
)
if column == "hostname":
hostname = node.hostname
if not node.exists or not hostname:
if node.private_ip:
hostname = Hostname(str(node.private_ip))
else:
hostname = Hostname("tbd")
value = hostname
elif column == "hostname_required":
continue
elif column == "job_ids":
value = node.assignments
elif hasattr(node, column):
value = getattr(node, column)
else:
if is_from_available:
value = node.available.get(column)
elif is_ratio:
value = "{}/{}".format(
node.available.get(column), node.resources.get(column)
)
elif column in node.resources:
value = node.resources.get(column)
else:
value = node.metadata.get(column)
if value is None:
buckets = demand_result.buckets_by_id.get(node.bucket_id, [])
if buckets:
bucket = buckets[0]
if hasattr(bucket, column):
value = getattr(bucket, column)
if value is None:
value = self.__defaults.get(column)
# convert sets to lists, as sets are not json serializable
if isinstance(value, set):
value = list(value)
elif isinstance(value, datetime):
value = value.isoformat()
# for json, we support lists, null, numbers etc.
# for table* we will output a string for every value.
if self.output_format != "json":
if isinstance(value, list):
value = ",".join(sorted(value))
elif isinstance(value, set):
value = ",".join(sorted(list(value)))
elif value is None:
value = ""
elif isinstance(value, float):
value = "{:.1f}".format(value)
elif not isinstance(value, str):
value = str(value)
else:
if hasattr(value, "to_json"):
value = value.to_json()
elif hasattr(value, "keys"):
value = dict(value)
row.append(slice(value))
# remove / and slice expressions
stripped_short_names = [c.lstrip("/").split("[")[0] for c in short_columns]
if self.output_format != "json":
stripped_short_names = [x.upper() for x in stripped_short_names]
print_rows(stripped_short_names, rows, self.stream, self.output_format)