@@ -20,6 +20,7 @@ import (
2020 "log"
2121 "net/http"
2222 "net/url"
23+ "sync"
2324
2425 "github.com/docker/docker/client"
2526
@@ -80,27 +81,52 @@ func (d *Deployer) Deploy(ctx context.Context, blueprintName string) (*Deploymen
8081 return nil , fmt .Errorf ("Deploy: %w" , err )
8182 }
8283 d .networkID = networkID
83- for _ , img := range images {
84+
85+ // deploy images in parallel
86+ var mu sync.Mutex // protects mutable values like the counter and errors
87+ var wg sync.WaitGroup
88+ wg .Add (len (images )) // ensure we wait until all images have deployed
89+ deployImg := func (img types.ImageSummary ) error {
90+ defer wg .Done ()
91+ mu .Lock ()
8492 d .Counter ++
93+ counter := d .Counter
94+ mu .Unlock ()
8595 contextStr := img .Labels ["complement_context" ]
8696 hsName := img .Labels ["complement_hs_name" ]
8797 asIDToRegistrationMap := asIDToRegistrationFromLabels (img .Labels )
8898
8999 // TODO: Make CSAPI port configurable
90100 deployment , err := deployImage (
91- d .Docker , img .ID , 8008 , fmt .Sprintf ("complement_%s_%s_%s_%d" , d .config .PackageNamespace , d .DeployNamespace , contextStr , d . Counter ),
101+ d .Docker , img .ID , 8008 , fmt .Sprintf ("complement_%s_%s_%s_%d" , d .config .PackageNamespace , d .DeployNamespace , contextStr , counter ),
92102 d .config .PackageNamespace , blueprintName , hsName , asIDToRegistrationMap , contextStr , networkID , d .config .SpawnHSTimeout )
93103 if err != nil {
94104 if deployment != nil && deployment .ContainerID != "" {
95105 // print logs to help debug
96106 printLogs (d .Docker , deployment .ContainerID , contextStr )
97107 }
98- return nil , fmt .Errorf ("Deploy: Failed to deploy image %+v : %w" , img , err )
108+ return fmt .Errorf ("Deploy: Failed to deploy image %+v : %w" , img , err )
99109 }
110+ mu .Lock ()
100111 d .log ("%s -> %s (%s)\n " , contextStr , deployment .BaseURL , deployment .ContainerID )
101112 dep .HS [hsName ] = * deployment
113+ mu .Unlock ()
114+ return nil
115+ }
116+
117+ var lastErr error
118+ for _ , img := range images {
119+ go func (i types.ImageSummary ) {
120+ err := deployImg (i )
121+ if err != nil {
122+ mu .Lock ()
123+ lastErr = err
124+ mu .Unlock ()
125+ }
126+ }(img )
102127 }
103- return dep , nil
128+ wg .Wait ()
129+ return dep , lastErr
104130}
105131
106132// Destroy a deployment. This will kill all running containers.
0 commit comments