mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-10-28 07:41:27 +00:00
feat(nodes): remote ingress via Traefik file provider
Remote replicas publish an ephemeral host port; the agent reports the assigned binding back in the create_container result and the backend renders a per-service file-provider config into TRAEFIK_DYNAMIC_DIR pointing Traefik at the node's mesh IP + port. Routes are rewritten on every remote reconcile and removed on teardown or local placement. Also: RetireService retires remote leftovers when a service returns to local placement; remove_container is idempotent agent-side; tombstoned replicas skip remove dispatch; the domains-stay-local ceiling is gone. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
4458de56b0
commit
c3a35081d0
13 files changed
+374
-39
No files matched your search
@@ -272,7 +272,12 @@ func executeCommand(item command) (string, error) {
|
||||
case "restart_container":
|
||||
return runDocker("restart", commandTarget(item.Payload))
|
||||
case "remove_container":
|
||||
return runDocker("rm", "-f", commandTarget(item.Payload))
|
||||
out, err := runDocker("rm", "-f", commandTarget(item.Payload))
|
||||
// A missing container is the desired end state — report success.
|
||||
if err != nil && strings.Contains(out, "No such container") {
|
||||
return out, nil
|
||||
}
|
||||
return out, err
|
||||
case "prune":
|
||||
return dockerPrune(item.Payload)
|
||||
case "system_df":
|
||||
@@ -460,7 +465,25 @@ func createContainer(payload map[string]interface{}) (string, error) {
|
||||
logs, _ := runDocker("logs", "--tail", "5", name)
|
||||
return "", fmt.Errorf("container %s is %q after start: %s", name, state, logs)
|
||||
}
|
||||
return name, nil
|
||||
// Report the real host port bindings — ephemeral publishes pick a port
|
||||
// the server can't guess, and remote ingress needs the actual mapping.
|
||||
hostPorts := map[string]string{}
|
||||
portsJSON, _ := runDocker("inspect", "-f", "{{json .NetworkSettings.Ports}}", name)
|
||||
var bindings map[string][]struct {
|
||||
HostIP string `json:"HostIp"`
|
||||
HostPort string `json:"HostPort"`
|
||||
}
|
||||
if json.Unmarshal([]byte(portsJSON), &bindings) == nil {
|
||||
for cport, addrs := range bindings {
|
||||
for _, a := range addrs {
|
||||
if a.HostPort != "" && a.HostPort != "0" {
|
||||
hostPorts[cport] = a.HostPort
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
out, _ := json.Marshal(map[string]interface{}{"name": name, "host_ports": hostPorts})
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
// registryHostOf mirrors the server's registryHost: first path segment with
|
||||
|
||||
Reference in new issue
Block a user