1d45f232c6
Funciones impuras para gestión de contenedores: docker_build_image, docker_compose_up/down, docker_volume_create/list/remove, generate_dockerfile, write_dockerfile, go_build_binary, health_check_http, deploy_app y stop_app. Todas con tests unitarios donde aplica. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
52 lines
1.5 KiB
Go
52 lines
1.5 KiB
Go
package infra
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
// DockerBuildImage construye una imagen Docker desde un directorio con Dockerfile.
|
|
// Retorna el image ID de la imagen construida.
|
|
func DockerBuildImage(contextDir, tag string, buildArgs map[string]string) (string, error) {
|
|
args := []string{"build", "-t", tag}
|
|
|
|
for k, v := range buildArgs {
|
|
args = append(args, "--build-arg", k+"="+v)
|
|
}
|
|
|
|
args = append(args, contextDir)
|
|
|
|
out, err := exec.Command("docker", args...).CombinedOutput()
|
|
if err != nil {
|
|
return "", fmt.Errorf("docker build %s: %s", tag, strings.TrimSpace(string(out)))
|
|
}
|
|
|
|
// Extraer el image ID de la ultima linea de output
|
|
// docker build imprime "Successfully built <id>" o con BuildKit "writing image sha256:<id>"
|
|
lines := strings.Split(strings.TrimSpace(string(out)), "\n")
|
|
for i := len(lines) - 1; i >= 0; i-- {
|
|
line := strings.TrimSpace(lines[i])
|
|
if strings.Contains(line, "Successfully built ") {
|
|
parts := strings.Fields(line)
|
|
return parts[len(parts)-1], nil
|
|
}
|
|
if strings.Contains(line, "sha256:") {
|
|
// BuildKit: extraer sha256:...
|
|
idx := strings.Index(line, "sha256:")
|
|
id := line[idx:]
|
|
if sp := strings.IndexAny(id, " \t,"); sp != -1 {
|
|
id = id[:sp]
|
|
}
|
|
return id, nil
|
|
}
|
|
}
|
|
|
|
// Si no encontramos el ID en el output, inspeccionar por tag
|
|
inspectOut, err2 := exec.Command("docker", "inspect", "--format", "{{.Id}}", tag).Output()
|
|
if err2 != nil {
|
|
return tag, nil
|
|
}
|
|
return strings.TrimSpace(string(inspectOut)), nil
|
|
}
|