@@ -2,10 +2,15 @@ package framework
22
33import (
44 "context"
5+ "errors"
56 "fmt"
67 "github.com/docker/go-connections/nat"
78 "github.com/google/uuid"
89 tc "github.com/testcontainers/testcontainers-go"
10+ "os"
11+ "os/exec"
12+ "strings"
13+ "sync"
914)
1015
1116func GetHost (container tc.Container ) (string , error ) {
@@ -41,3 +46,76 @@ func DefaultTCLabels() map[string]string {
4146func DefaultTCName (name string ) string {
4247 return fmt .Sprintf ("%s-%s" , name , uuid .NewString ()[0 :5 ])
4348}
49+
50+ // BuildAndPublishLocalDockerImage runs Docker commands to set up a local registry, build an image, and push it.
51+ func BuildAndPublishLocalDockerImage (once * sync.Once , dockerfile string , buildContext string , imageName string ) error {
52+ var retErr error
53+ once .Do (func () {
54+ registryRunning := isContainerRunning ("local-registry" )
55+ if registryRunning {
56+ fmt .Println ("Local registry container is already running." )
57+ } else {
58+ L .Info ().Msg ("Starting local registry container..." )
59+ err := runCommand ("docker" , "run" , "-d" , "-p" , "5050:5000" , "--name" , "local-registry" , "registry:2" )
60+ if err != nil {
61+ retErr = fmt .Errorf ("failed to start local registry: %w" , err )
62+ }
63+ L .Info ().Msg ("Local registry started" )
64+ }
65+
66+ img := fmt .Sprintf ("localhost:5050/%s:latest" , imageName )
67+ L .Info ().Str ("DockerFile" , dockerfile ).Str ("Context" , buildContext ).Msg ("Building Docker image" )
68+ err := runCommand ("docker" , "build" , "-t" , fmt .Sprintf ("localhost:5050/%s:latest" , imageName ), "-f" , dockerfile , buildContext )
69+ if err != nil {
70+ retErr = fmt .Errorf ("failed to build Docker image: %w" , err )
71+ }
72+ L .Info ().Msg ("Docker image built successfully" )
73+
74+ L .Info ().Str ("Image" , img ).Msg ("Pushing Docker image to local registry" )
75+ fmt .Println ("Pushing Docker image to local registry..." )
76+ err = runCommand ("docker" , "push" , img )
77+ if err != nil {
78+ retErr = fmt .Errorf ("failed to push Docker image: %w" , err )
79+ }
80+ L .Info ().Msg ("Docker image pushed successfully" )
81+ })
82+ return retErr
83+ }
84+
85+ // isContainerRunning checks if a Docker container with the given name is running.
86+ func isContainerRunning (containerName string ) bool {
87+ cmd := exec .Command ("docker" , "ps" , "--filter" , fmt .Sprintf ("name=%s" , containerName ), "--format" , "{{.Names}}" )
88+ output , err := cmd .Output ()
89+ if err != nil {
90+ return false
91+ }
92+ return strings .Contains (string (output ), containerName )
93+ }
94+
95+ // runCommand executes a command and prints the output.
96+ func runCommand (name string , args ... string ) error {
97+ cmd := exec .Command (name , args ... )
98+ cmd .Stdout = os .Stdout
99+ cmd .Stderr = os .Stderr
100+ return cmd .Run ()
101+ }
102+
103+ // RebuildDockerImage rebuilds docker image if necessary
104+ func RebuildDockerImage (once * sync.Once , dockerfile string , buildContext string , imageName string ) (string , error ) {
105+ if os .Getenv (EnvVarDockerImagesBuild ) == "true" {
106+ if dockerfile == "" {
107+ return "" , errors .New ("docker_file path must be provided" )
108+ }
109+ if buildContext == "" {
110+ return "" , errors .New ("docker_ctx path must be provided" )
111+ }
112+ if imageName == "" {
113+ return "" , errors .New ("docker_image_name must be provided" )
114+ }
115+ if err := BuildAndPublishLocalDockerImage (once , dockerfile , buildContext , imageName ); err != nil {
116+ return "" , err
117+ }
118+ return fmt .Sprintf ("localhost:5050/%s:latest" , imageName ), nil
119+ }
120+ return "" , nil
121+ }
0 commit comments