SealSkin

quota

Limits on what a user may run and the record of what they ran.

  • Session limit. session_limit counts a user's sessions on every node, as the nodes last reported them; a node that is away counts with what it last said, so losing sight of a node never frees a slot.
  • Session size. session_cpus and session_memory_mb cap each session's container, below whatever the app or its template asks for.
  • Session length. session_hours ends a session that old.
  • Allowance. allowance_hours per allowance_period (day, week, or month, in UTC) is spent by session time, weighted by the cost of the pool the session runs in (gpu_cost for a GPU session), so an hour on a GPU node can cost more than an hour of office work. A user out of allowance starts nothing new; a pool with stop_when_spent also ends what runs.
  • Storage. storage_limit, in gigabytes, stops new uploads and persistent launches once the user's directories on the node hold that much.

Each node adds up the time of its own sessions and writes it to cluster/usage/<day>/<node id>.yml every usage_flush_seconds, an object no other node writes. What is spent is the sum over the nodes, plus this node's time not yet written.

attributelogger
= logging.getLogger(__name__)
attributeUSAGEdict[str, dict[str, dict[str, float]]]
= {}
func_today() -> str

Return today's date in UTC.

Returns

str
func_usage_dir(day='') -> str

Return the directory of the usage records, or of one day's.

paramdaystr
= ''

Returns

str
funcperiod_days(period) -> list[str]

Return the dates, in UTC, of the day, week (from Monday), or month running now.

paramperiodstr

Returns

list[str]
funcload() -> None

Read the usage records of the running month; a day gone by is read once.

Returns

None
functick() -> None

Add the time since the last tick to every running session's user.

Returns

None
funcflush() -> None

Write this node's usage of the days it changed.

Returns

None
funcused_hours(username, period) -> float

Return the weighted hours a user spent in the running period, on every node.

paramusernamestr
paramperiodstr

Returns

float
funcallowance(user) -> dict[str, Any] | None

Return a user's allowance and what is spent of it, or None for a user with none.

paramuserdict[str, Any]

Returns

dict[str, typing.Any] | None
funclimited(user) -> bool

Whether a user has a session limit or an allowance, so their launches have to be counted.

paramuserdict[str, Any]

Returns

bool
funccheck_launch(user) -> None

Refuse a launch that would take a user past the session limit or the allowance.

The other nodes are asked for their sessions first, so the count is as fresh as they can make it.

paramuserdict[str, Any]

Returns

None
func_bytes(value) -> int | None

Parse a Docker memory size (512m, 4g, a byte count) into bytes.

paramvalueAny

Returns

int | None
funccap_resources(overrides, effective_settings) -> None

Lower a launch's CPU and memory to the user's session_cpus and session_memory_mb.

paramoverridesdict[str, Any]

Docker run options of the launch, changed in place.

parameffective_settingsdict[str, Any] | None

The user's effective settings.

Returns

None
funcstorage_used(username) -> int

Return the bytes under a user's storage directory on this node, measured at most once a minute.

paramusernamestr

Returns

int
funccheck_storage(user) -> None

Refuse to add to the storage of a user who is at their storage_limit.

paramuserdict[str, Any]

Returns

None
funcoverdue() -> list[tuple[str, str]]

Return the sessions on this node to end now, each with the reason.

That is a session older than its user's session_hours, and, in a pool with stop_when_spent, one whose user is out of allowance.

Returns

list[tuple[str, str]]