Skip to content
Snippets Groups Projects
Verified Commit 68694509 authored by Renato Alves's avatar Renato Alves :seedling:
Browse files

ENH qs - Distinguish allocation from usage

Allows providing accurate availability based on system allocation
parent e5b65c65
No related branches found
No related tags found
No related merge requests found
......@@ -52,12 +52,14 @@ def collect(funcargs):
parsetypes = {
"num_proc": float,
"cpu": float,
"slots": int,
"slots_used": int,
"mem_total": mem_parser,
"h_vmem": mem_parser,
}
cmd = ["ssh", "-oBatchMode=yes", target,
"qhost -F num_proc,cpu,mem_total,h_vmem -xml"]
"qhost -q -F num_proc,cpu,mem_total,h_vmem -xml"]
p = Popen(cmd, stdout=PIPE, stderr=PIPE)
try:
out, err = p.communicate(timeout=args.timeout)
......@@ -84,11 +86,20 @@ def collect(funcargs):
cluster[nodename] = OrderedDict()
# Host level values
for attr in node.getElementsByTagName("resourcevalue"):
attrname = attr.attributes["name"].value
value = parsetypes[attrname](attr.firstChild.nodeValue)
cluster[nodename][attrname] = value
# Host's queue level values (mostly info about slots)
for queue in node.getElementsByTagName("queue"):
for attr in queue.getElementsByTagName("queuevalue"):
attrname = attr.attributes["name"].value
if attrname in parsetypes:
value = parsetypes[attrname](attr.firstChild.nodeValue)
cluster[nodename][attrname] = value
for node in cluster:
# Ignore nodes without information
if not cluster[node]:
......@@ -137,7 +148,8 @@ def format_table(data, full_output=False, best_target=False):
global_totals = {
"cpu": 0,
"cpu_free": 0,
"slots": 0,
"slots_free": 0,
"mem": 0,
"mem_free": 0,
"usage": -1,
......@@ -146,12 +158,13 @@ def format_table(data, full_output=False, best_target=False):
cluster_totals = {}
header = ("Host", "CPU", "CPU-Free", "MEM", "MEM-Free", "Usage %", "Avail %", "Rank")
header = ("Host", "CPU (real)", "CPU-Free", "MEM", "MEM-Free", "Usage %", "Avail %", "Rank")
for i, cluster in enumerate(data):
totals = {
"cpu": 0,
"cpu_free": 0,
"slots": 0,
"slots_free": 0,
"mem": 0,
"mem_free": 0,
"usage": -1,
......@@ -160,7 +173,7 @@ def format_table(data, full_output=False, best_target=False):
}
if full_output:
table.append((cluster.center(15, "="),) + ("=" * 8,) * 7)
table.append((cluster.center(15, "="),) + ("=" * 12,) + ("=" * 9,) * 6)
table.append(header)
elif i == 0:
table.append(header)
......@@ -172,7 +185,10 @@ def format_table(data, full_output=False, best_target=False):
try:
cpu = int(round(values["num_proc"]))
# cpu_free is used only to calculate system use vs allocation
cpu_free = int(round(cpu - (cpu * values["cpu"] / 100)))
slots = int(round(values["slots"]))
slots_free = slots - int(round(values["slots_used"]))
mem = int(round(values["mem_total"]))
mem_free = int(round(values["h_vmem"]))
except KeyError as e:
......@@ -182,8 +198,8 @@ def format_table(data, full_output=False, best_target=False):
usable_hosts += 1
usage = ((1 - (cpu_free / cpu)) + (1 - (mem_free / mem))) / 0.02
avail = min(cpu_free / cpu, mem_free / mem) * 100
rank = rank_score(cpu_free, mem_free, avail / 100)
avail = min(slots_free / slots, mem_free / mem) * 100
rank = rank_score(slots_free, mem_free, avail / 100)
usage = limit(usage, 0, 100)
avail = limit(avail, 0, 100)
......@@ -192,14 +208,17 @@ def format_table(data, full_output=False, best_target=False):
host = host.rsplit('.', 1)[0]
if full_output:
table.append((host, cpu, cpu_free,
table.append((host,
"{} ({})".format(slots, cpu),
slots_free,
human_readable(mem), human_readable(mem_free),
"{:.2f}".format(usage),
"{:.2f}".format(avail),
"{:.2f}".format(rank)))
totals["cpu"] += cpu
totals["cpu_free"] += cpu_free
totals["slots"] += slots
totals["slots_free"] += slots_free
totals["mem"] += mem
totals["mem_free"] += mem_free
totals["rank"] += rank
......@@ -221,14 +240,17 @@ def format_table(data, full_output=False, best_target=False):
else:
total_title = cluster
table.append((total_title, totals["cpu"], totals["cpu_free"],
table.append((total_title,
"{} ({})".format(totals["slots"], totals["cpu"]),
totals["slots_free"],
human_readable(totals["mem"]), human_readable(totals["mem_free"]),
"{:.2f}".format(totals["usage"]),
"{:.2f}".format(totals["avail"]),
"{:.2f}".format(totals["rank"])))
global_totals["cpu"] += totals["cpu"]
global_totals["cpu_free"] += totals["cpu_free"]
global_totals["slots"] += totals["slots"]
global_totals["slots_free"] += totals["slots_free"]
global_totals["mem"] += totals["mem"]
global_totals["mem_free"] += totals["mem_free"]
......@@ -242,9 +264,10 @@ def format_table(data, full_output=False, best_target=False):
cluster_totals[cluster] = totals
table.append(("-" * 15,) + ("-" * 8,) * 7)
table.append(("-" * 15,) + ("-" * 12,) + ("-" * 9,) * 6)
table.append(("GLOBAL",
global_totals["cpu"], global_totals["cpu_free"],
"{} ({})".format(global_totals["slots"], global_totals["cpu"]),
global_totals["slots_free"],
human_readable(global_totals["mem"]),
human_readable(global_totals["mem_free"]),
"{:.2f}".format(global_totals["usage"]),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment