MCPcopy Index your code
hub / github.com/coder/coder / convertDockerInspect

Function convertDockerInspect

agent/agentcontainers/containers_dockercli.go:396–499  ·  view source on GitHub ↗
(raw []byte)

Source from the content-addressed store, hash-verified

394}
395
396func convertDockerInspect(raw []byte) ([]codersdk.WorkspaceAgentContainer, []string, error) {
397 var warns []string
398 var ins []dockerInspect
399 if err := json.NewDecoder(bytes.NewReader(raw)).Decode(&ins); err != nil {
400 return nil, nil, xerrors.Errorf("decode docker inspect output: %w", err)
401 }
402 outs := make([]codersdk.WorkspaceAgentContainer, 0, len(ins))
403
404 // Say you have two containers:
405 // - Container A with Host IP 127.0.0.1:8000 mapped to container port 8001
406 // - Container B with Host IP [::1]:8000 mapped to container port 8001
407 // A request to localhost:8000 may be routed to either container.
408 // We don't know which one for sure, so we need to surface this to the user.
409 // Keep track of all host ports we see. If we see the same host port
410 // mapped to multiple containers on different host IPs, we need to
411 // warn the user about this.
412 // Note that we only do this for loopback or unspecified IPs.
413 // We'll assume that the user knows what they're doing if they bind to
414 // a specific IP address.
415 hostPortContainers := make(map[int][]string)
416
417 for _, in := range ins {
418 out := codersdk.WorkspaceAgentContainer{
419 CreatedAt: in.Created,
420 // Remove the leading slash from the container name
421 FriendlyName: strings.TrimPrefix(in.Name, "/"),
422 ID: in.ID,
423 Image: in.Config.Image,
424 Labels: in.Config.Labels,
425 Ports: make([]codersdk.WorkspaceAgentContainerPort, 0),
426 Running: in.State.Running,
427 Status: in.State.String(),
428 Volumes: make(map[string]string, len(in.Mounts)),
429 }
430
431 if in.NetworkSettings.Ports == nil {
432 in.NetworkSettings.Ports = make(map[string][]dockerInspectPort)
433 }
434 portKeys := maps.Keys(in.NetworkSettings.Ports)
435 // Sort the ports for deterministic output.
436 slices.Sort(portKeys)
437 // If we see the same port bound to both ipv4 and ipv6 loopback or unspecified
438 // interfaces to the same container port, there is no point in adding it multiple times.
439 loopbackHostPortContainerPorts := make(map[int]uint16, 0)
440 for _, pk := range portKeys {
441 for _, p := range in.NetworkSettings.Ports[pk] {
442 cp, network, err := convertDockerPort(pk)
443 if err != nil {
444 warns = append(warns, fmt.Sprintf("convert docker port: %s", err.Error()))
445 // Default network to "tcp" if we can't parse it.
446 network = "tcp"
447 }
448 hp, err := strconv.Atoi(p.HostPort)
449 if err != nil {
450 warns = append(warns, fmt.Sprintf("convert docker host port: %s", err.Error()))
451 continue
452 }
453 if hp > 65535 || hp < 1 { // invalid port

Callers 3

devcontainerEnvFunction · 0.85
ListMethod · 0.85
TestConvertDockerInspectFunction · 0.85

Calls 6

convertDockerPortFunction · 0.85
isLoopbackOrUnspecifiedFunction · 0.85
KeysMethod · 0.80
ErrorfMethod · 0.45
StringMethod · 0.45
ErrorMethod · 0.45

Tested by 1

TestConvertDockerInspectFunction · 0.68