Documentation
¶
Index ¶
- Constants
- func FindFlavorInGroups(flavorName string, flavorGroups map[string]compute.FlavorGroupFeature) (groupName string, flavor *compute.FlavorInGroup, err error)
- func GlobalRequestIDFromContext(ctx context.Context) string
- func HostFreeCapacity(hostReservations []v1alpha1.Reservation, hv hv1.Hypervisor) map[hv1.ResourceName]resource.Quantity
- func HostHasCapacityForReservation(allReservations []v1alpha1.Reservation, hv hv1.Hypervisor, ...) bool
- func IndexReservationByHost(ctx context.Context, mcl *multicluster.Client) (err error)
- func RequestIDFromContext(ctx context.Context) string
- func UnusedReservationCapacity(res *v1alpha1.Reservation, ignoreAllocations bool) map[hv1.ResourceName]resource.Quantity
- func WithGlobalRequestID(ctx context.Context, id string) context.Context
- func WithRequestID(ctx context.Context, id string) context.Context
- type ContextKey
- type DBVMSource
- func (s *DBVMSource) GetDeletedVMInfo(ctx context.Context, vmUUID string) (*DeletedVMInfo, error)
- func (s *DBVMSource) GetVM(ctx context.Context, vmUUID string) (*VM, error)
- func (s *DBVMSource) IsServerActive(ctx context.Context, vmUUID string) (bool, error)
- func (s *DBVMSource) ListVMs(ctx context.Context) ([]VM, error)
- func (s *DBVMSource) ListVMsByProject(ctx context.Context, projectID string) ([]VM, error)
- func (s *DBVMSource) ListVMsOnHypervisors(ctx context.Context, hypervisorList *hv1.HypervisorList, ...) ([]VM, error)
- type DeletedVMInfo
- type FlavorGroupKnowledgeClient
- type HypervisorDiffHandler
- func (h *HypervisorDiffHandler) Create(_ context.Context, _ event.TypedCreateEvent[*hv1.Hypervisor], ...)
- func (h *HypervisorDiffHandler) Delete(_ context.Context, _ event.TypedDeleteEvent[*hv1.Hypervisor], ...)
- func (h *HypervisorDiffHandler) Generic(_ context.Context, _ event.TypedGenericEvent[*hv1.Hypervisor], ...)
- func (h *HypervisorDiffHandler) Update(ctx context.Context, e event.TypedUpdateEvent[*hv1.Hypervisor], ...)
- type Monitor
- type ScheduleReservationRequest
- type ScheduleReservationResponse
- type SchedulerClient
- type VM
- type VMSource
Constants ¶
const DefaultHTTPTimeout = 30 * time.Second
DefaultHTTPTimeout is the default timeout for HTTP requests to the scheduler API.
const IdxReservationByHost = "reservations.host"
IdxReservationByHost is the field index key for looking up Reservations by host. Both Spec.TargetHost and Status.Host are indexed so reservations in transit (TargetHost != Status.Host) are found via either field. All reservation types are included.
Variables ¶
This section is empty.
Functions ¶
func FindFlavorInGroups ¶
func FindFlavorInGroups(flavorName string, flavorGroups map[string]compute.FlavorGroupFeature) (groupName string, flavor *compute.FlavorInGroup, err error)
FindFlavorInGroups searches all flavor groups for a flavor by name. Returns the flavor group name and flavor details, or an error if the flavor is not found in any group.
func GlobalRequestIDFromContext ¶
GlobalRequestIDFromContext retrieves the global request ID from the context. Returns empty string if not set.
func HostFreeCapacity ¶
func HostFreeCapacity(hostReservations []v1alpha1.Reservation, hv hv1.Hypervisor) map[hv1.ResourceName]resource.Quantity
HostFreeCapacity computes the remaining free capacity on hv after subtracting hv.Status.Allocation and UnusedReservationCapacity for all reservations on this host. Negative values indicate over-subscription for that resource. Returns nil when the hypervisor has no capacity data. Reservations not targeting this host (via Spec.TargetHost or Status.Host) are ignored.
func HostHasCapacityForReservation ¶
func HostHasCapacityForReservation(allReservations []v1alpha1.Reservation, hv hv1.Hypervisor, res *v1alpha1.Reservation) bool
HostHasCapacityForReservation reports whether hv has sufficient remaining capacity to absorb res moving to it — i.e. whether the unfilled portion of res's slot fits alongside everything already committed on the host.
- Start from EffectiveCapacity (or Capacity when EffectiveCapacity is nil).
- Subtract hv.Status.Allocation (VMs physically running on this host).
- For each other reservation assigned to this host (via Spec.TargetHost or Status.Host), subtract its UnusedReservationCapacity.
- Check that the remainder is ≥ UnusedReservationCapacity(res): the unfilled portion of res's slot. Confirmed VMs in res already appear in hv.Status.Allocation (step 2), so comparing against the full slot would count them twice.
res itself is excluded from step 3 to avoid subtracting its own block from free capacity. Returns false when the hypervisor has no capacity data.
func IndexReservationByHost ¶
func IndexReservationByHost(ctx context.Context, mcl *multicluster.Client) (err error)
IndexReservationByHost registers the shared host index on the multicluster client. Safe to call multiple times — registration happens only once.
func RequestIDFromContext ¶
RequestIDFromContext retrieves the request ID from the context. Returns empty string if not set.
func UnusedReservationCapacity ¶
func UnusedReservationCapacity(res *v1alpha1.Reservation, ignoreAllocations bool) map[hv1.ResourceName]resource.Quantity
UnusedReservationCapacity returns the resources a Reservation should block on its host(s). This is the single source of truth used by both the capacity controller and filter_has_enough_capacity to ensure consistent accounting.
CommittedResourceReservations: confirmed VMs already appear in hv.Status.Allocation, so blocking the full slot would double-count them. The effective block is: max(slot − confirmedVMs, specOnlyVMs), clamped to zero. Skipped (full slot used) when ignoreAllocations is true or when mid-migration (TargetHost != Status.Host).
FailoverReservations: always block the full Spec.Resources.
func WithGlobalRequestID ¶
WithGlobalRequestID returns a new context with the global request ID set. GlobalRequestID identifies the overall reconciliation context.
Types ¶
type ContextKey ¶
type ContextKey string
ContextKey is the type for context keys used in request tracking.
const ( // GlobalRequestIDKey is the context key for the global request ID. GlobalRequestIDKey ContextKey = "globalRequestID" // RequestIDKey is the context key for the request ID. RequestIDKey ContextKey = "requestID" )
type DBVMSource ¶
type DBVMSource struct {
NovaReader external.NovaReaderInterface
}
DBVMSource implements VMSource by reading directly from the database. This is the preferred implementation as it avoids the size limitations of Knowledge CRDs.
func NewDBVMSource ¶
func NewDBVMSource(novaReader external.NovaReaderInterface) *DBVMSource
NewDBVMSource creates a new DBVMSource.
func (*DBVMSource) GetDeletedVMInfo ¶
func (s *DBVMSource) GetDeletedVMInfo(ctx context.Context, vmUUID string) (*DeletedVMInfo, error)
GetDeletedVMInfo returns metadata about a deleted VM from the deleted_servers table.
func (*DBVMSource) GetVM ¶
GetVM returns a specific VM by UUID. Returns nil, nil if the VM is not found.
func (*DBVMSource) IsServerActive ¶
IsServerActive returns true if the server exists in the servers table and is not DELETED.
func (*DBVMSource) ListVMs ¶
func (s *DBVMSource) ListVMs(ctx context.Context) ([]VM, error)
ListVMs returns all VMs across all projects by joining server and flavor data.
func (*DBVMSource) ListVMsByProject ¶
ListVMsByProject returns all VMs for a specific project, querying only that project's servers.
func (*DBVMSource) ListVMsOnHypervisors ¶
func (s *DBVMSource) ListVMsOnHypervisors( ctx context.Context, hypervisorList *hv1.HypervisorList, trustHypervisorLocation bool, ) ([]VM, error)
ListVMsOnHypervisors returns VMs that are on the given hypervisors.
type DeletedVMInfo ¶
type DeletedVMInfo struct {
ProjectID string
AvailabilityZone string
FlavorName string
RAMMiB uint64
VCPUs uint64
}
DeletedVMInfo contains the metadata needed to compute resource decrements for a deleted VM.
type FlavorGroupKnowledgeClient ¶
FlavorGroupKnowledgeClient accesses flavor group data from Knowledge CRDs.
func (*FlavorGroupKnowledgeClient) Get ¶
Get retrieves the flavor groups Knowledge CRD and returns it if ready. Returns nil, nil if not ready yet.
func (*FlavorGroupKnowledgeClient) GetAllFlavorGroups ¶
func (c *FlavorGroupKnowledgeClient) GetAllFlavorGroups(ctx context.Context, knowledgeCRD *v1alpha1.Knowledge) (map[string]compute.FlavorGroupFeature, error)
GetAllFlavorGroups returns all flavor groups as a map. If knowledgeCRD is provided, uses it directly. Otherwise fetches the Knowledge CRD.
type HypervisorDiffHandler ¶
type HypervisorDiffHandler struct {
// OnUpdate is called with (ctx, oldHV, newHV) on every Hypervisor Update event.
OnUpdate func(ctx context.Context, oldHV, newHV *hv1.Hypervisor) error
}
HypervisorDiffHandler is a typed event handler that calls a callback on HV Update events. Create and Delete events are no-ops; a periodic full reconcile is expected to correct any drift.
func (*HypervisorDiffHandler) Create ¶
func (h *HypervisorDiffHandler) Create(_ context.Context, _ event.TypedCreateEvent[*hv1.Hypervisor], _ workqueue.TypedRateLimitingInterface[reconcile.Request])
func (*HypervisorDiffHandler) Delete ¶
func (h *HypervisorDiffHandler) Delete(_ context.Context, _ event.TypedDeleteEvent[*hv1.Hypervisor], _ workqueue.TypedRateLimitingInterface[reconcile.Request])
func (*HypervisorDiffHandler) Generic ¶
func (h *HypervisorDiffHandler) Generic(_ context.Context, _ event.TypedGenericEvent[*hv1.Hypervisor], _ workqueue.TypedRateLimitingInterface[reconcile.Request])
func (*HypervisorDiffHandler) Update ¶
func (h *HypervisorDiffHandler) Update(ctx context.Context, e event.TypedUpdateEvent[*hv1.Hypervisor], _ workqueue.TypedRateLimitingInterface[reconcile.Request])
type Monitor ¶
type Monitor struct {
// Client for the kubernetes API.
client.Client
// contains filtered or unexported fields
}
Monitor for reservations metrics.
func NewMonitor ¶
func (*Monitor) Collect ¶
func (m *Monitor) Collect(ch chan<- prometheus.Metric)
Collect the metrics on-demand and send them to Prometheus.
func (*Monitor) Describe ¶
func (m *Monitor) Describe(ch chan<- *prometheus.Desc)
Describe the metrics for Prometheus.
type ScheduleReservationRequest ¶
type ScheduleReservationRequest struct {
// InstanceUUID is the unique identifier for the reservation (usually the reservation name).
InstanceUUID string
// ProjectID is the OpenStack project ID.
ProjectID string
// FlavorName is the name of the flavor.
FlavorName string
// FlavorExtraSpecs are extra specifications for the flavor.
FlavorExtraSpecs map[string]string
// MemoryMB is the memory in MB.
MemoryMB uint64
// VCPUs is the number of virtual CPUs.
VCPUs uint64
// EligibleHosts is the list of hosts that can be considered for placement.
EligibleHosts []api.ExternalSchedulerHost
// IgnoreHosts is a list of hosts to ignore during scheduling.
// This is used for failover reservations to avoid placing on the same host as the VMs.
IgnoreHosts []string
// Pipeline is the name of the pipeline to execute.
// If empty, the default pipeline will be used.
Pipeline string
// AvailabilityZone is the availability zone to schedule in.
// This is used by the filter_correct_az filter to ensure hosts are in the correct AZ.
AvailabilityZone string
// SchedulerHints are hints passed to the scheduler pipeline.
// Used to set _nova_check_type for evacuation intent detection.
SchedulerHints map[string]any
// ImageProperties are Glance-style image properties (e.g., "img_hv_type", "hypervisor_type")
// forwarded on Spec.Data.Image.Data.Properties.Data. Optional; when empty the outgoing
// request leaves the image field at its zero value. Used by FilterImagePropertiesStep.
ImageProperties map[string]any
}
ScheduleReservationRequest contains the parameters for scheduling a reservation.
type ScheduleReservationResponse ¶
type ScheduleReservationResponse struct {
// Hosts is the ordered list of hosts that the reservation can be placed on.
// The first host is the best choice.
Hosts []string
}
ScheduleReservationResponse contains the result of scheduling a reservation.
type SchedulerClient ¶
type SchedulerClient struct {
// URL of the external scheduler API.
URL string
// HTTP client to use for requests.
HTTPClient *http.Client
}
SchedulerClient is a client for the external scheduler API. It can be used by both the ReservationReconciler and FailoverReservationController.
func NewSchedulerClient ¶
func NewSchedulerClient(url string) *SchedulerClient
NewSchedulerClient creates a new SchedulerClient with a default timeout.
func (*SchedulerClient) ScheduleReservation ¶
func (c *SchedulerClient) ScheduleReservation(ctx context.Context, req ScheduleReservationRequest, opts scheduling.Options) (*ScheduleReservationResponse, error)
ScheduleReservation calls the external scheduler API to find a host for a reservation. The context should contain GlobalRequestID and RequestID for logging (use WithGlobalRequestID/WithRequestID).
type VM ¶
type VM struct {
// UUID is the unique identifier of the VM.
UUID string
// Name is the display name of the VM in Nova.
Name string
// Status is the Nova status of the VM (e.g. ACTIVE, SHUTOFF).
Status string
// FlavorName is the name of the flavor used by the VM.
FlavorName string
// ProjectID is the OpenStack project ID that owns the VM.
ProjectID string
// CurrentHypervisor is the hypervisor where the VM is currently running.
CurrentHypervisor string
// AvailabilityZone is the availability zone where the VM is located.
// This is used to ensure failover reservations are created in the same AZ.
AvailabilityZone string
// CreatedAt is the ISO 8601 timestamp when the VM was created in Nova.
// Used by the quota controller to distinguish new VMs from migrations.
CreatedAt string
// Resources contains the VM's resource allocations (e.g., "memory", "vcpus").
Resources map[string]resource.Quantity
// FlavorExtraSpecs contains the flavor's extra specifications (e.g., traits, capabilities).
// This is used by filters like filter_has_requested_traits and filter_capabilities.
FlavorExtraSpecs map[string]string
// DiskGB is the flavor's root disk size in GiB.
DiskGB uint64
// OSType is the operating system type pre-computed from Glance image properties.
// "unknown" when not found or for volume-booted instances.
OSType string
}
VM represents a virtual machine managed by the reservation system.
type VMSource ¶
type VMSource interface {
// ListVMs returns all VMs across all projects.
ListVMs(ctx context.Context) ([]VM, error)
// ListVMsByProject returns all VMs belonging to a specific project.
ListVMsByProject(ctx context.Context, projectID string) ([]VM, error)
// ListVMsOnHypervisors returns VMs that are on the given hypervisors.
// If trustHypervisorLocation is true, uses hypervisor CRD as source of truth for VM location.
// If trustHypervisorLocation is false, uses postgres as source of truth but filters to VMs on known hypervisors.
ListVMsOnHypervisors(ctx context.Context, hypervisorList *hv1.HypervisorList, trustHypervisorLocation bool) ([]VM, error)
// GetVM returns a specific VM by UUID.
// Returns nil, nil if the VM is not found.
GetVM(ctx context.Context, vmUUID string) (*VM, error)
// IsServerActive returns true if the server exists in the servers table and is not DELETED.
// Returns false if not found. Used by quota controller to determine if a removed HV instance was deleted vs migrated.
IsServerActive(ctx context.Context, vmUUID string) (bool, error)
// GetDeletedVMInfo returns metadata about a deleted VM (from deleted_servers table),
// including resolved flavor resources. Returns nil, nil if not found.
GetDeletedVMInfo(ctx context.Context, vmUUID string) (*DeletedVMInfo, error)
}
VMSource provides VMs managed by the reservation system. This interface allows swapping the implementation when a VM CRD arrives.