While implementing the hostname
constraint, I’d like to also implement host randomization options in the python xir model.
This is useful from an experimental point of view and from an operational point of view to distribute the wear and tear across the nodes more evenly as well.
I’m thinking of something like passing a list of metrics to sort by.
Here are some example metrics:
- Cost
- Hostname
- PercentAllocated
It’s also possible to divide costs further down, currently it is the aggregate of CPU, Disk, and Network that the node’s specs have (aka does not consider what’s allocated already on it).
So, if you wanted the current algorithm (as the unit tests would want), you’d pass something along the lines of:
net = Network("test", hostsorting==[LowestCost, LowestHostname])
where things are sorted first by lowest cost, and if their costs are equal, then you compare the hostnames, leading to a not very random selection.
Later on, the realization algorithm iterates through this sorted list of hosts and tries provisioning each guest onto each host until it’s successful (which means that the host has enough raw resources to rlz on).
If we allow for other selections than that, if you wanted just randomization using the lowest cost nodes, you’d pass:
hostsorting==[LowestCost]
This should probably be the default if the list is nil
(which is different than the empty list).
If you wanted to place them actually anywhere, you’d pass:
hostsorting==[]
(Whether we allow this is a separate consideration)
If you wanted to “try” to place as much of it on as few as possible nodes, you could pass:
hostsorting==[LowestCost, LowestPercentAllocated]
The backend algorithm is pretty simple:
# Each node will have a random unique number assigned to it as node.index
def compare(node_a, node_b):
for metric in metrics:
# metric(node_a, node_b) can return:
# - EQUAL
# - LESSTHAN
# - GREATERTHAN
if metric(node_a, node_b) is not EQUAL:
return metric(noda_a, node_b)
return node_a.index < node_b.index ? LESSTHAN : GREATERTHAN
Is this overly complicated on the user end? As in, does this expose too much of the internals? Should we just have user pass a single enum value instead, where each option maps onto one of these lists?
Should LowestCost
be implicitly the first element of each list? In other words, should that always be the dominant metric to sort by?
We will probably need a new uint64list constraint object to do this?
With the hostname
constraint, then you’re able to reproduce any specific realization, at least in terms of node selection, for debugging purposes.
Although, it might be easier to pass something like a dictionary of guestname
→ hostname
to the net initialization and to have the CLI be able of producing such a dictionary.