diff --git a/internal/docker/builder.go b/internal/docker/builder.go index 4415fbca..24be3bdc 100644 --- a/internal/docker/builder.go +++ b/internal/docker/builder.go @@ -494,6 +494,48 @@ func printLogs(docker *client.Client, containerID, contextStr string) { log.Printf("============== %s : END LOGS ==============\n\n\n", contextStr) } +func printPortBindingsOfAllComplementContainers(docker *client.Client, contextStr string) { + ctx := context.Background() + + containers, err := docker.ContainerList(ctx, container.ListOptions{ + All: true, + Filters: label( + complementLabel, + ), + }) + if err != nil { + log.Printf("%s : Failed to list containers while trying to `printPortBindingsOfAllComplementContainers`: %s\n", contextStr, err) + return + } + + log.Printf("============== %s : START ALL COMPLEMENT DOCKER PORT BINDINGS ==============\n", contextStr) + + for _, container := range containers { + log.Printf("Container: %s: %s", container.ID, container.Names) + + inspectRes, err := docker.ContainerInspect(ctx, container.ID) + if err != nil { + log.Printf("%s : Failed to inspect container (%s) while trying to `printPortBindingsOfAllComplementContainers`: %s\n", contextStr, container.ID, err) + return + } + + // Print an example so it's easier to understand the output + log.Printf(" (host) -> (container)\n") + // Then print the actual port bindings + for containerPort, portBindings := range inspectRes.NetworkSettings.Ports { + hostPortBindingStrings := make([]string, len(portBindings)) + for portBindingIndex, portBinding := range portBindings { + hostPortBindingStrings[portBindingIndex] = fmt.Sprintf("%s:%s", portBinding.HostIP, portBinding.HostPort) + } + + log.Printf(" %s -> %s\n", strings.Join(hostPortBindingStrings, ", "), containerPort) + } + + } + + log.Printf("=============== %s : END ALL COMPLEMENT DOCKER PORT BINDINGS ===============\n\n\n", contextStr) +} + func endpoints(p nat.PortMap, csPort, ssPort int) (baseURL, fedBaseURL string, err error) { csapiPort := fmt.Sprintf("%d/tcp", csPort) csapiPortInfo, ok := p[nat.Port(csapiPort)] diff --git a/internal/docker/deployer.go b/internal/docker/deployer.go index c14e4d9a..6bd063ec 100644 --- a/internal/docker/deployer.go +++ b/internal/docker/deployer.go @@ -91,8 +91,9 @@ func (d *Deployer) CreateDirtyServer(hsName string) (*HomeserverDeployment, erro baseImageURI = uri } + containerName := fmt.Sprintf("complement_%s_dirty_%s", d.config.PackageNamespace, hsName) hsDeployment, err := deployImage( - d.Docker, baseImageURI, fmt.Sprintf("complement_%s_dirty_%s", d.config.PackageNamespace, hsName), + d.Docker, baseImageURI, containerName, d.config.PackageNamespace, "", hsName, nil, "dirty", networkName, d.config, ) @@ -101,6 +102,11 @@ func (d *Deployer) CreateDirtyServer(hsName string) (*HomeserverDeployment, erro // print logs to help debug printLogs(d.Docker, hsDeployment.ContainerID, "dirty") } + + // Give some context for what the port bindings look like the time of the failure. + // This gives better context for when `bind: address already in use` errors happen. + printPortBindingsOfAllComplementContainers(d.Docker, "While dirty deploying "+containerName) + return nil, fmt.Errorf("CreateDirtyServer: Failed to deploy image %v : %w", baseImageURI, err) } return hsDeployment, nil @@ -164,8 +170,9 @@ func (d *Deployer) Deploy(ctx context.Context, blueprintName string) (*Deploymen asIDToRegistrationMap := asIDToRegistrationFromLabels(img.Labels) // TODO: Make CSAPI port configurable + containerName := fmt.Sprintf("complement_%s_%s_%s_%d", d.config.PackageNamespace, d.DeployNamespace, contextStr, counter) deployment, err := deployImage( - d.Docker, img.ID, fmt.Sprintf("complement_%s_%s_%s_%d", d.config.PackageNamespace, d.DeployNamespace, contextStr, counter), + d.Docker, img.ID, containerName, d.config.PackageNamespace, blueprintName, hsName, asIDToRegistrationMap, contextStr, networkName, d.config, ) if err != nil { @@ -173,6 +180,11 @@ func (d *Deployer) Deploy(ctx context.Context, blueprintName string) (*Deploymen // print logs to help debug printLogs(d.Docker, deployment.ContainerID, contextStr) } + + // Give some context for what the port bindings look like the time of the failure. + // This gives better context for when `bind: address already in use` errors happen. + printPortBindingsOfAllComplementContainers(d.Docker, "While deploying "+containerName) + return fmt.Errorf("Deploy: Failed to deploy image %+v : %w", img, err) } mu.Lock()