quota

package
v0.0.0-...-e5d423c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package quota provides resource quota enforcement for StreamSpace users and groups.

The quota system prevents resource exhaustion and enforces fair usage limits. It supports per-user quotas, per-group quotas, and platform-wide defaults.

Quota types:

  • Session count: Maximum concurrent sessions
  • CPU per session: Maximum CPU cores per individual session
  • Memory per session: Maximum RAM per individual session
  • Total CPU: Maximum total CPU across all sessions
  • Total memory: Maximum total RAM across all sessions
  • Storage: Maximum persistent storage per user
  • GPU: Maximum GPU count per session

Quota hierarchy (most restrictive wins):

  1. User-specific quotas (user_quotas table)
  2. Group quotas (all groups user belongs to)
  3. Platform defaults (defined in code)

Example limits:

  • Free tier: 5 sessions, 2 CPU/session, 4 GiB/session, 50 GiB storage
  • Pro tier: 20 sessions, 4 CPU/session, 8 GiB/session, 500 GiB storage
  • Enterprise: Custom limits per organization

Enforcement points:

  • Session creation (CheckSessionCreation)
  • Resource requests (ValidateResourceRequest)
  • Storage allocation (checked separately)

Example usage:

enforcer := quota.NewEnforcer(userDB, groupDB)

// Check if user can create session
err := enforcer.CheckSessionCreation(ctx, "user1", 1000, 2048, 0, currentUsage)
if quota.IsQuotaExceeded(err) {
    return errors.New("quota exceeded")
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatResourceQuantity

func FormatResourceQuantity(value int64, resourceType string) string

FormatResourceQuantity formats a resource value back to Kubernetes format

func GetDefaultResources

func GetDefaultResources(category string) (cpu, memory string)

GetDefaultResources returns default resource requests based on template category

func IsQuotaExceeded

func IsQuotaExceeded(err error) bool

IsQuotaExceeded checks if an error is a quota exceeded error

func ParseGPURequest

func ParseGPURequest(gpuStr string) (int, error)

ParseGPURequest parses a GPU request from a string

func ParseResourceQuantity

func ParseResourceQuantity(quantity string, resourceType string) (int64, error)

ParseResourceQuantity parses a Kubernetes resource quantity string (e.g., "2000m", "4Gi")

Types

type Enforcer

type Enforcer struct {
	// contains filtered or unexported fields
}

Enforcer enforces resource quotas for users and groups.

The enforcer:

  • Retrieves quotas from database (user and group tables)
  • Calculates effective limits (most restrictive)
  • Validates resource requests against limits
  • Checks current usage before allowing new sessions

Thread safety:

  • Enforcer is stateless and safe for concurrent use
  • Database queries may run concurrently

Example:

enforcer := NewEnforcer(userDB, groupDB)
limits, _ := enforcer.GetUserLimits(ctx, "user1")
fmt.Printf("Max sessions: %d\n", limits.MaxSessions)

func NewEnforcer

func NewEnforcer(userDB *db.UserDB, groupDB *db.GroupDB) *Enforcer

NewEnforcer creates a new quota enforcer instance.

The enforcer is stateless and can be shared across goroutines.

Example:

enforcer := NewEnforcer(userDB, groupDB)
err := enforcer.CheckSessionCreation(ctx, username, cpu, memory, gpu, usage)

func (*Enforcer) CalculateUsage

func (e *Enforcer) CalculateUsage(pods []corev1.Pod) *Usage

CalculateUsage calculates current resource usage from a list of pods

func (*Enforcer) CheckSessionCreation

func (e *Enforcer) CheckSessionCreation(ctx context.Context, username string, requestedCPU, requestedMemory int64, requestedGPU int, currentUsage *Usage) error

CheckSessionCreation validates if a user can create a new session with the requested resources

func (*Enforcer) GetUserLimits

func (e *Enforcer) GetUserLimits(ctx context.Context, username string) (*Limits, error)

GetUserLimits retrieves the resource limits for a user It combines user-specific limits with group limits (taking the most restrictive)

func (*Enforcer) ValidateResourceRequest

func (e *Enforcer) ValidateResourceRequest(cpuStr, memoryStr string) (cpu, memory int64, err error)

ValidateResourceRequest validates that a resource request is within acceptable bounds

type Limits

type Limits struct {
	// MaxSessions is the maximum number of concurrent sessions.
	// Example: 5 (free tier), 20 (pro tier), 100 (enterprise)
	MaxSessions int `json:"max_sessions"`

	// MaxCPUPerSession is the maximum CPU per individual session (millicores).
	// Example: 2000 (2 CPU cores)
	MaxCPUPerSession int64 `json:"max_cpu_per_session"`

	// MaxMemoryPerSession is the maximum memory per individual session (MiB).
	// Example: 4096 (4 GiB)
	MaxMemoryPerSession int64 `json:"max_memory_per_session"`

	// MaxTotalCPU is the maximum total CPU across all sessions (millicores).
	// Example: 8000 (8 CPU cores total across all sessions)
	MaxTotalCPU int64 `json:"max_total_cpu"`

	// MaxTotalMemory is the maximum total memory across all sessions (MiB).
	// Example: 16384 (16 GiB total across all sessions)
	MaxTotalMemory int64 `json:"max_total_memory"`

	// MaxStorage is the maximum persistent storage per user (GiB).
	// Example: 50 (50 GiB for home directory)
	MaxStorage int64 `json:"max_storage"`

	// MaxGPUPerSession is the maximum GPU count per individual session.
	// Example: 1 (one GPU per session), 0 (no GPU access)
	MaxGPUPerSession int `json:"max_gpu_per_session"`
}

Limits represents resource quotas for a user or group.

Limits can be set at multiple levels:

  • Per-user: Stored in user_quotas table
  • Per-group: Stored in group_quotas table
  • Platform default: Defined in GetUserLimits()

When a user belongs to multiple groups, the most restrictive limit is applied for each resource type.

Units:

  • CPU: Millicores (1000m = 1 CPU core)
  • Memory: MiB (mebibytes, 1024 MiB = 1 GiB)
  • Storage: GiB (gibibytes)
  • GPU: Integer count

Example:

limits := &Limits{
    MaxSessions: 10,
    MaxCPUPerSession: 2000,      // 2 CPU cores
    MaxMemoryPerSession: 4096,   // 4 GiB
    MaxTotalCPU: 8000,           // 8 CPU cores total
    MaxTotalMemory: 16384,       // 16 GiB total
    MaxStorage: 100,             // 100 GiB
    MaxGPUPerSession: 1,
}

type QuotaExceededError

type QuotaExceededError struct {
	Message string
	Limit   interface{}
	Current interface{}
}

QuotaExceededError represents a quota exceeded error

func (*QuotaExceededError) Error

func (e *QuotaExceededError) Error() string

type Usage

type Usage struct {
	// ActiveSessions is the count of currently running sessions.
	// Calculated from pods with status.phase == Running
	ActiveSessions int `json:"active_sessions"`

	// TotalCPU is the total CPU requests across all sessions (millicores).
	// Sum of container.resources.requests.cpu
	TotalCPU int64 `json:"total_cpu"`

	// TotalMemory is the total memory requests across all sessions (MiB).
	// Sum of container.resources.requests.memory
	TotalMemory int64 `json:"total_memory"`

	// TotalStorage is the total persistent storage in use (GiB).
	// Sum of PVC sizes
	TotalStorage int64 `json:"total_storage"`

	// TotalGPU is the total GPU count across all sessions.
	// Sum of container.resources.requests["nvidia.com/gpu"]
	TotalGPU int `json:"total_gpu"`
}

Usage represents current resource consumption for a user.

This is calculated from:

  • Running Kubernetes pods (for sessions, CPU, memory, GPU)
  • Persistent volume claims (for storage)

Usage is checked before creating new sessions to enforce quotas.

Example:

usage := &Usage{
    ActiveSessions: 3,
    TotalCPU: 6000,       // 6 CPU cores in use
    TotalMemory: 12288,   // 12 GiB in use
    TotalStorage: 45,     // 45 GiB in use
    TotalGPU: 2,          // 2 GPUs in use
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL