Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 12 additions & 24 deletions pkg/controller/dual-pods/inference-server.go
Original file line number Diff line number Diff line change
Expand Up @@ -631,11 +631,12 @@ func (ctl *controller) selectBestLauncherPod(
hasSleepingInstance := false
hasPortConflict := false
for _, inst := range insts.Instances {
instPort, err := getVLLMInstancePort(inst.Options)
instPort, err := getVLLMInstancePort(inst)
if err != nil {
logger.V(5).Info("Skipping launcher Pod because an instance has unparseable options",
logger.V(5).Info("Skipping launcher Pod because an instance has no usable inference port",
"name", launcherPod.Name,
"instanceID", inst.InstanceID,
"annotations", inst.Annotations,
"options", inst.Options,
"err", err)
hasPortConflict = true
Expand Down Expand Up @@ -705,8 +706,8 @@ func (ctl *controller) configInferenceServer(isc *fmav1alpha1.InferenceServerCon
GpuUUIDs: gpuUUIDs,
EnvVars: isc.Spec.ModelServerConfig.EnvVars,
Annotations: map[string]string{
"isc-name": isc.Name,
"inference-port": portS,
VllmConfigISCNameAnnotationKey: isc.Name,
VllmConfigInferencePortAnnotationKey: portS,
},
}
iscBytes, err := yaml.Marshal(isc.Spec.ModelServerConfig)
Expand All @@ -725,28 +726,15 @@ func (ctl *controller) configInferenceServer(isc *fmav1alpha1.InferenceServerCon
return &vllmCfg, nominalHash, nil
}

func getVLLMInstancePort(options string) (int32, error) {
parts := strings.Fields(options)
for idx, part := range parts {
if part == "--port" {
if idx+1 >= len(parts) {
return 0, fmt.Errorf("missing value for --port")
}
port, err := strconv.ParseInt(parts[idx+1], 10, 32)
if err != nil {
return 0, fmt.Errorf("parse --port value %q: %w", parts[idx+1], err)
}
return int32(port), nil
}
if value, ok := strings.CutPrefix(part, "--port="); ok {
port, err := strconv.ParseInt(value, 10, 32)
if err != nil {
return 0, fmt.Errorf("parse --port value %q: %w", value, err)
}
return int32(port), nil
func getVLLMInstancePort(inst InstanceState) (int32, error) {
if value, ok := inst.Annotations[VllmConfigInferencePortAnnotationKey]; ok {
port, err := strconv.ParseInt(value, 10, 32)
if err != nil {
return 0, fmt.Errorf("parse annotations[%s] value %q: %w", VllmConfigInferencePortAnnotationKey, value, err)
}
Comment on lines +731 to 734
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getVLLMInstancePort parses the annotation value as a signed 32-bit integer but does not validate that it’s a valid TCP port (e.g., 1–65535). Since this value is later used to avoid port conflicts and to form wake-up endpoints, consider rejecting non-positive or out-of-range ports (and possibly use ParseUint with an explicit upper bound) to prevent silent misbehavior when the annotation is malformed or user-specified port is invalid.

Suggested change
port, err := strconv.ParseInt(value, 10, 32)
if err != nil {
return 0, fmt.Errorf("parse annotations[%s] value %q: %w", VllmConfigInferencePortAnnotationKey, value, err)
}
port, err := strconv.ParseUint(value, 10, 16)
if err != nil {
return 0, fmt.Errorf("parse annotations[%s] value %q as TCP port: %w", VllmConfigInferencePortAnnotationKey, value, err)
}
if port == 0 {
return 0, fmt.Errorf("annotations[%s] value %q is not a valid TCP port", VllmConfigInferencePortAnnotationKey, value)
}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have bigger problems if we do not trust the instance annotations. Problems for later.

Copy link
Copy Markdown
Collaborator

@MikeSpreitzer MikeSpreitzer Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to put access control on all the access to the launcher's control port.

return int32(port), nil
}
return 0, fmt.Errorf("missing --port in options %q", options)
return 0, fmt.Errorf("missing annotations[%s]", VllmConfigInferencePortAnnotationKey)
}

func (ctl *controller) wakeupInstance(ctx context.Context, lClient *LauncherClient, instanceID string, instancePort int32) error {
Expand Down
5 changes: 5 additions & 0 deletions pkg/controller/dual-pods/launcherclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ type LauncherClient struct {
httpClient *http.Client
}

const (
VllmConfigISCNameAnnotationKey = "isc-name"
VllmConfigInferencePortAnnotationKey = "inference-port"
)

func NewLauncherClient(baseURL string) (*LauncherClient, error) {
parsedURL, err := url.Parse(baseURL)
if err != nil {
Expand Down
Loading