-
Notifications
You must be signed in to change notification settings - Fork 244
feat: add hub-managed port pool for agent containers #298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
0346899
04e8d05
a0d14ea
3903982
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -816,6 +816,22 @@ func (m *AgentManager) Start(ctx context.Context, opts api.StartOptions) (*api.A | |||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // Allocate ports from the pool if available | ||||||||||||||||||||||||||||||||
| var allocatedPorts []int | ||||||||||||||||||||||||||||||||
| if m.PortPool != nil { | ||||||||||||||||||||||||||||||||
| // Release any previously allocated ports for this agent name. | ||||||||||||||||||||||||||||||||
| // This handles the restart case (stop + start) where the old | ||||||||||||||||||||||||||||||||
| // ports were never freed because the previous run didn't go | ||||||||||||||||||||||||||||||||
| // through Delete. Release is idempotent — a no-op if the name | ||||||||||||||||||||||||||||||||
| // has no allocation. | ||||||||||||||||||||||||||||||||
| m.PortPool.Release(opts.Name) | ||||||||||||||||||||||||||||||||
| ports, err := m.PortPool.Allocate(opts.Name, m.PortPool.PerAgent()) | ||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||
| return nil, fmt.Errorf("port allocation failed: %w", err) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| allocatedPorts = ports | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+821
to
+833
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When an agent container is recreated or restarted, the existing container is deleted via To prevent this resource leak, release any existing ports for the agent name from the pool before allocating new ones.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Already addressed — Release is called before Allocate in the Start path to handle the restart case where old ports were not freed. |
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| runCfg := runtime.RunConfig{ | ||||||||||||||||||||||||||||||||
| Name: containerName(projectName, opts.Name), | ||||||||||||||||||||||||||||||||
| Template: template, | ||||||||||||||||||||||||||||||||
|
|
@@ -890,6 +906,13 @@ func (m *AgentManager) Start(ctx context.Context, opts api.StartOptions) (*api.A | |||||||||||||||||||||||||||||||
| MetadataInterception: hasMetadataInterception(agentEnv), | ||||||||||||||||||||||||||||||||
| ExtraHosts: mergeExtraHosts(opts.ExtraHosts, runtime.BridgeExtraHosts(m.Runtime.Name(), agentEnv)), | ||||||||||||||||||||||||||||||||
| NetworkMode: dockerNetworkMode, | ||||||||||||||||||||||||||||||||
| AllocatedPorts: allocatedPorts, | ||||||||||||||||||||||||||||||||
| PortHostURL: func() string { | ||||||||||||||||||||||||||||||||
| if m.PortPool != nil { | ||||||||||||||||||||||||||||||||
| return m.PortPool.HostURL() | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| return "" | ||||||||||||||||||||||||||||||||
| }(), | ||||||||||||||||||||||||||||||||
| Labels: func() map[string]string { | ||||||||||||||||||||||||||||||||
| l := map[string]string{ | ||||||||||||||||||||||||||||||||
| "scion.agent": "true", | ||||||||||||||||||||||||||||||||
|
|
@@ -919,6 +942,9 @@ func (m *AgentManager) Start(ctx context.Context, opts api.StartOptions) (*api.A | |||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| id, err := m.Runtime.Run(ctx, runCfg) | ||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||
| if m.PortPool != nil { | ||||||||||||||||||||||||||||||||
| m.PortPool.Release(opts.Name) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| // Provisioning writes agent-info.json in "created" state before the | ||||||||||||||||||||||||||||||||
| // runtime launch. If the launch itself fails, keep the provisioned | ||||||||||||||||||||||||||||||||
| // workspace but flip the local state to "error" so list/status do not | ||||||||||||||||||||||||||||||||
|
|
@@ -948,6 +974,9 @@ func (m *AgentManager) Start(ctx context.Context, opts api.StartOptions) (*api.A | |||||||||||||||||||||||||||||||
| // Try to get logs for diagnosis | ||||||||||||||||||||||||||||||||
| logs, _ := m.Runtime.GetLogs(ctx, id) | ||||||||||||||||||||||||||||||||
| _ = m.Runtime.Delete(ctx, id) | ||||||||||||||||||||||||||||||||
| if m.PortPool != nil { | ||||||||||||||||||||||||||||||||
| m.PortPool.Release(opts.Name) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| return nil, fmt.Errorf("container started but exited immediately (status: %s). Container logs:\n%s", a.ContainerStatus, logs) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| a.Detached = detached | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If
pp.HostURLis configured with a trailing slash (e.g.,http://35.232.118.211/), the constructed agent port URLs will contain an invalid double-slash/colon sequence (e.g.,http://35.232.118.211/:8000).Trimming any trailing slashes from the host URL during initialization ensures that the constructed URLs are always valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Already addressed —
strings.TrimRight(pp.HostURL, "/")is applied when creating the PortPool in server_foreground.go (see commit 0da4a06).