Skip to content

Commit 4a794ec

Browse files
yuvipandajnywong
authored andcommitted
Simplify generated resource options
Based on 2i2c-org#6351 (comment) 1. Much more limited use of fractions - only for CPUs under 2. No fractions over that, everything is rounded to nearest whole number 2. The display name indicates how much CPU is guaranteed 3. The description indicates CPU limits with appropriate wording 4. Allow specifying multiple node types in one go, makes copy pasting easier. 5. No longer specify 'default: true', as first one is default now
1 parent 6c730af commit 4a794ec

File tree

1 file changed

+40
-25
lines changed

1 file changed

+40
-25
lines changed

deployer/commands/generate/resource_allocation/generate_choices.py

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import sys
44
from enum import Enum
55
from pathlib import Path
6+
from typing import List
67

78
import typer
89
from ruamel.yaml import YAML
@@ -66,12 +67,26 @@ def proportional_memory_strategy(
6667
# This makes sure we utilize all the memory on a node all the time.
6768
cpu_guarantee = (mem_limit / available_node_mem) * available_node_cpu
6869

69-
# Memory is in bytes, let's convert it to GB (with only 1 digit after .) to display
70-
mem_display = f"{mem_limit / 1024 / 1024 / 1024:.1f}"
71-
display_name = f"{mem_display} GB RAM, upto {cpu_display} CPUs"
70+
# Memory is in bytes, let's convert it to GB or MB (with no digits after 0) to display
71+
if mem_limit < 1024 * 1024 * 1024:
72+
mem_display = f"{mem_limit / 1024 / 1024:.0f} MB"
73+
else:
74+
mem_display = f"{mem_limit / 1024 / 1024 / 1024:.0f} GB"
75+
76+
if cpu_guarantee < 2:
77+
cpu_guarantee_display = f"~{cpu_guarantee:0.1f}"
78+
else:
79+
cpu_guarantee_display = f"~{cpu_guarantee:0.0f}"
80+
81+
display_name = f"{mem_display} RAM, {cpu_guarantee_display} CPUs"
82+
if cpu_guarantee != available_node_cpu:
83+
description = f"Upto ~{available_node_cpu:.0f} CPUs when available"
84+
else:
85+
description = f"~{available_node_cpu:.0f} CPUs always available"
7286

7387
choice = {
7488
"display_name": display_name,
89+
"description": description,
7590
"kubespawner_override": {
7691
# Guarantee and Limit are the same - this strategy has no oversubscription
7792
"mem_guarantee": int(mem_limit),
@@ -90,26 +105,23 @@ def proportional_memory_strategy(
90105
# Use the amount of RAM made available as a slug, to allow combining choices from
91106
# multiple instance types in the same profile. This does mean you can not have
92107
# the same RAM allocation from multiple node selectors. But that's a feature, not a bug.
93-
choices[f"mem_{mem_display.replace('.', '_')}"] = choice
108+
choice_key = f"mem_{mem_display.replace('.', '_').replace(' ', '_')}".lower()
109+
choices[choice_key] = choice
94110

95111
# Halve the mem_limit for the next choice
96112
mem_limit = mem_limit / 2
97113

98114
# Reverse the choices so the smallest one is first
99115
choices = dict(reversed(choices.items()))
100116

101-
# Make the smallest choice the default explicitly
102-
choices[list(choices.keys())[0]]["default"] = True
103-
104117
return choices
105118

106119

107120
@resource_allocation_app.command()
108121
def choices(
109-
instance_type: str = typer.Argument(
110-
..., help="Instance type to generate Resource Allocation options for"
122+
instance_specification: List[str] = typer.Argument(
123+
..., help="Instance type and number of choices to generate Resource Allocation options for. Specify as instance_type:count."
111124
),
112-
num_allocations: int = typer.Option(5, help="Number of choices to generate"),
113125
strategy: ResourceAllocationStrategies = typer.Option(
114126
ResourceAllocationStrategies.PROPORTIONAL_MEMORY_STRATEGY,
115127
help="Strategy to use for generating resource allocation choices choices",
@@ -121,19 +133,22 @@ def choices(
121133
"""
122134
with open(HERE / "node-capacity-info.json") as f:
123135
nodeinfo = json.load(f)
124-
125-
if instance_type not in nodeinfo:
126-
print(
127-
f"Capacity information about {instance_type} not available", file=sys.stderr
128-
)
129-
print("TODO: Provide information on how to update it", file=sys.stderr)
130-
sys.exit(1)
131-
132-
# Call appropriate function based on what strategy we want to use
133-
if strategy == ResourceAllocationStrategies.PROPORTIONAL_MEMORY_STRATEGY:
134-
choices = proportional_memory_strategy(
135-
instance_type, nodeinfo[instance_type], num_allocations
136-
)
137-
else:
138-
raise ValueError(f"Strategy {strategy} is not currently supported")
136+
choices = {}
137+
for instance_spec in instance_specification:
138+
instance_type, num_allocations = instance_spec.split(":", 2)
139+
140+
if instance_type not in nodeinfo:
141+
print(
142+
f"Capacity information about {instance_type} not available", file=sys.stderr
143+
)
144+
print("TODO: Provide information on how to update it", file=sys.stderr)
145+
sys.exit(1)
146+
147+
# Call appropriate function based on what strategy we want to use
148+
if strategy == ResourceAllocationStrategies.PROPORTIONAL_MEMORY_STRATEGY:
149+
choices.update(proportional_memory_strategy(
150+
instance_type, nodeinfo[instance_type], int(num_allocations)
151+
))
152+
else:
153+
raise ValueError(f"Strategy {strategy} is not currently supported")
139154
yaml.dump(choices, sys.stdout)

0 commit comments

Comments
 (0)