@@ -12,22 +12,22 @@ import (
1212 "strconv"
1313 "strings"
1414 "time"
15-
15+
1616 "github.com/loft-sh/devspace/pkg/devspace/pipeline/env"
1717 "mvdan.cc/sh/v3/expand"
18-
18+
1919 devspacecontext "github.com/loft-sh/devspace/pkg/devspace/context"
2020 command2 "github.com/loft-sh/utils/pkg/command"
21-
21+
2222 cliconfig "github.com/docker/cli/cli/config"
23+ "github.com/docker/docker/api/types/build"
2324 "github.com/loft-sh/devspace/pkg/devspace/build/builder/helper"
2425 "github.com/loft-sh/devspace/pkg/devspace/config/versions/latest"
2526 dockerpkg "github.com/loft-sh/devspace/pkg/devspace/docker"
2627 "github.com/loft-sh/devspace/pkg/devspace/kubectl"
2728 logpkg "github.com/loft-sh/devspace/pkg/util/log"
2829 "github.com/pkg/errors"
2930 "k8s.io/client-go/tools/clientcmd"
30- "github.com/docker/docker/api/types/build"
3131)
3232
3333// EngineName is the name of the building engine
@@ -49,7 +49,7 @@ func NewBuilder(ctx devspacecontext.Context, imageConf *latest.Image, imageTags
4949 return nil , err
5050 }
5151 }
52-
52+
5353 return & Builder {
5454 helper : helper .NewBuildHelper (ctx , EngineName , imageConf , imageTags ),
5555 skipPush : skipPush ,
@@ -68,23 +68,23 @@ func (b *Builder) ShouldRebuild(ctx devspacecontext.Context, forceRebuild bool)
6868 imageCache , _ := ctx .Config ().LocalCache ().GetImageCache (b .helper .ImageConf .Name )
6969 imageName := imageCache .ResolveImage () + ":" + imageCache .Tag
7070 rebuild , err := b .helper .ShouldRebuild (ctx , forceRebuild )
71-
71+
7272 // Check if image is present in local docker daemon
7373 if ! rebuild && err == nil && b .helper .ImageConf .BuildKit .InCluster == nil {
7474 if b .skipPushOnLocalKubernetes && ctx .KubeClient () != nil && kubectl .IsLocalKubernetes (ctx .KubeClient ()) {
7575 dockerClient , err := dockerpkg .NewClientWithMinikube (ctx .Context (), ctx .KubeClient (), b .helper .ImageConf .BuildKit .PreferMinikube == nil || * b .helper .ImageConf .BuildKit .PreferMinikube , ctx .Log ())
7676 if err != nil {
7777 return false , err
7878 }
79-
79+
8080 found , err := b .helper .IsImageAvailableLocally (ctx , dockerClient )
8181 if ! found && err == nil {
8282 ctx .Log ().Infof ("Rebuild image %s because it was not found in local docker daemon" , imageName )
8383 return true , nil
8484 }
8585 }
8686 }
87-
87+
8888 return rebuild , err
8989}
9090
@@ -93,32 +93,32 @@ func (b *Builder) ShouldRebuild(ctx devspacecontext.Context, forceRebuild bool)
9393// dockerfilePath is the absolute path to the dockerfile WITHIN the contextPath
9494func (b * Builder ) BuildImage (ctx devspacecontext.Context , contextPath , dockerfilePath string , entrypoint []string , cmd []string ) error {
9595 buildKitConfig := b .helper .ImageConf .BuildKit
96-
96+
9797 // create the builder
9898 builder , err := ensureBuilder (ctx .Context (), ctx .WorkingDir (), ctx .Environ (), ctx .KubeClient (), buildKitConfig , ctx .Log ())
9999 if err != nil {
100100 return err
101101 }
102-
102+
103103 // create the context stream
104104 body , writer , _ , buildOptions , err := b .helper .CreateContextStream (contextPath , dockerfilePath , entrypoint , cmd , ctx .Log ())
105105 defer writer .Close ()
106106 if err != nil {
107107 return err
108108 }
109-
109+
110110 // We skip pushing when it is the minikube client
111111 usingLocalKubernetes := ctx .KubeClient () != nil && kubectl .IsLocalKubernetes (ctx .KubeClient ())
112112 if b .skipPushOnLocalKubernetes && usingLocalKubernetes {
113113 b .skipPush = true
114114 }
115-
115+
116116 // Should we use the minikube docker daemon?
117117 useMinikubeDocker := false
118118 if ctx .KubeClient () != nil && kubectl .IsMinikubeKubernetes (ctx .KubeClient ()) && (buildKitConfig .PreferMinikube == nil || * buildKitConfig .PreferMinikube ) {
119119 useMinikubeDocker = true
120120 }
121-
121+
122122 // Should we build with cli?
123123 skipPush := b .skipPush || b .helper .ImageConf .SkipPush
124124 return buildWithCLI (ctx .Context (), ctx .WorkingDir (), ctx .Environ (), body , writer , ctx .KubeClient (), builder , buildKitConfig , * buildOptions , useMinikubeDocker , skipPush , ctx .Log ())
@@ -129,14 +129,14 @@ func buildWithCLI(ctx context.Context, dir string, environ expand.Environ, conte
129129 if len (imageConf .Command ) > 0 {
130130 command = imageConf .Command
131131 }
132-
132+
133133 args := []string {"build" }
134134 if options .BuildArgs != nil {
135135 for k , v := range options .BuildArgs {
136136 if v == nil {
137137 continue
138138 }
139-
139+
140140 args = append (args , "--build-arg" , k + "=" + * v )
141141 }
142142 }
@@ -167,9 +167,9 @@ func buildWithCLI(ctx context.Context, dir string, environ expand.Environ, conte
167167 return err
168168 }
169169 defer os .Remove (tempFile )
170-
170+
171171 args = append (args , "--builder" , builder )
172-
172+
173173 // TODO: find a better solution than this
174174 // we wait here a little bit, otherwise it might be possible that we get issues during
175175 // parallel image building, as it seems that docker buildx has problems if the
@@ -178,14 +178,14 @@ func buildWithCLI(ctx context.Context, dir string, environ expand.Environ, conte
178178 time .Sleep (time .Millisecond * time .Duration (rand .Intn (3000 )+ 500 ))
179179 }
180180 args = append (args , imageConf .Args ... )
181-
181+
182182 args = append (args , "-" )
183-
183+
184184 log .Infof ("Execute BuildKit command with: %s %s" , strings .Join (command , " " ), strings .Join (args , " " ))
185185 completeArgs := []string {}
186186 completeArgs = append (completeArgs , command [1 :]... )
187187 completeArgs = append (completeArgs , args ... )
188-
188+
189189 var (
190190 minikubeEnv map [string ]string
191191 err error
@@ -200,7 +200,7 @@ func buildWithCLI(ctx context.Context, dir string, environ expand.Environ, conte
200200 if err != nil {
201201 return err
202202 }
203-
203+
204204 if skipPush && kubeClient != nil && kubectl .GetKindContext (kubeClient .CurrentContext ()) != "" {
205205 // Load image if it is a kind-context
206206 for _ , tag := range options .Tags {
@@ -214,7 +214,7 @@ func buildWithCLI(ctx context.Context, dir string, environ expand.Environ, conte
214214 log .Info ("Image loaded to kind cluster" )
215215 }
216216 }
217-
217+
218218 return nil
219219}
220220
@@ -240,27 +240,27 @@ func ensureBuilder(ctx context.Context, workingDir string, environ expand.Enviro
240240 } else if kubeClient == nil {
241241 return "" , fmt .Errorf ("cannot build in cluster wth build kit without a correct kubernetes context" )
242242 }
243-
243+
244244 namespace := kubeClient .Namespace ()
245245 if imageConf .InCluster .Namespace != "" {
246246 namespace = imageConf .InCluster .Namespace
247247 }
248-
248+
249249 name := "devspace-" + namespace
250250 if imageConf .InCluster .Name != "" {
251251 name = imageConf .InCluster .Name
252252 }
253-
253+
254254 // check if we should skip
255255 if imageConf .InCluster .NoCreate {
256256 return name , nil
257257 }
258-
258+
259259 command := []string {"docker" , "buildx" }
260260 if len (imageConf .Command ) > 0 {
261261 command = imageConf .Command
262262 }
263-
263+
264264 args := []string {"create" , "--driver" , "kubernetes" , "--driver-opt" , "namespace=" + namespace , "--name" , name }
265265 if imageConf .InCluster .Rootless {
266266 args = append (args , "--driver-opt" , "rootless=true" )
@@ -274,38 +274,38 @@ func ensureBuilder(ctx context.Context, workingDir string, environ expand.Enviro
274274 if len (imageConf .InCluster .CreateArgs ) > 0 {
275275 args = append (args , imageConf .InCluster .CreateArgs ... )
276276 }
277-
277+
278278 completeArgs := []string {}
279279 completeArgs = append (completeArgs , command [1 :]... )
280280 completeArgs = append (completeArgs , args ... )
281-
281+
282282 // check if builder already exists
283283 builderPath := filepath .Join (getConfigStorePath (), "instances" , name )
284284 _ , err := os .Stat (builderPath )
285285 if err == nil {
286286 if imageConf .InCluster .NoRecreate {
287287 return name , nil
288288 }
289-
289+
290290 // update the builder if necessary
291291 b , err := os .ReadFile (builderPath )
292292 if err != nil {
293293 log .Warnf ("Error reading builder %s: %v" , builderPath , err )
294294 return name , nil
295295 }
296-
296+
297297 // parse builder config
298298 ng := & NodeGroup {}
299299 err = json .Unmarshal (b , ng )
300300 if err != nil {
301301 log .Warnf ("Error decoding builder %s: %v" , builderPath , err )
302302 return name , nil
303303 }
304-
304+
305305 // check for: correct driver name, driver opts
306306 if strings .ToLower (ng .Driver ) == "kubernetes" && len (ng .Nodes ) == 1 {
307307 node := ng .Nodes [0 ]
308-
308+
309309 // check driver options
310310 namespaceCorrect := node .DriverOpts ["namespace" ] == namespace
311311 if node .DriverOpts ["rootless" ] == "" {
@@ -314,28 +314,28 @@ func ensureBuilder(ctx context.Context, workingDir string, environ expand.Enviro
314314 rootlessCorrect := strconv .FormatBool (imageConf .InCluster .Rootless ) == node .DriverOpts ["rootless" ]
315315 imageCorrect := imageConf .InCluster .Image == node .DriverOpts ["image" ]
316316 nodeSelectorCorrect := imageConf .InCluster .NodeSelector == node .DriverOpts ["nodeselector" ]
317-
317+
318318 // if builder up to date, exit here
319319 if namespaceCorrect && rootlessCorrect && imageCorrect && nodeSelectorCorrect {
320320 return name , nil
321321 }
322322 }
323-
323+
324324 // recreate the builder
325325 log .Infof ("Recreate BuildKit builder because builder options differ" )
326-
326+
327327 // create a temporary kube context
328328 tempFile , err := tempKubeContextFromClient (kubeClient )
329329 if err != nil {
330330 return "" , err
331331 }
332332 defer os .Remove (tempFile )
333-
333+
334334 // prepare the command
335335 rmArgs := []string {}
336336 rmArgs = append (rmArgs , command [1 :]... )
337337 rmArgs = append (rmArgs , "rm" , name )
338-
338+
339339 // execute the command
340340 out , err := command2 .CombinedOutput (ctx , workingDir , env .NewVariableEnvProvider (environ , map [string ]string {
341341 "KUBECONFIG" : tempFile ,
@@ -344,10 +344,10 @@ func ensureBuilder(ctx context.Context, workingDir string, environ expand.Enviro
344344 log .Warnf ("error deleting BuildKit builder: %s => %v" , string (out ), err )
345345 }
346346 }
347-
347+
348348 // create the builder
349349 log .Infof ("Create BuildKit builder with: %s %s" , strings .Join (command , " " ), strings .Join (args , " " ))
350-
350+
351351 // This is necessary because docker would otherwise save the used kube config
352352 // which we don't want because we will override it with our own temp kube config
353353 // during building.
@@ -359,7 +359,7 @@ func ensureBuilder(ctx context.Context, workingDir string, environ expand.Enviro
359359 return "" , fmt .Errorf ("error creating BuildKit builder: %s => %v" , string (out ), err )
360360 }
361361 }
362-
362+
363363 return name , nil
364364}
365365
@@ -370,7 +370,7 @@ func getConfigStorePath() string {
370370 if buildxConfig := os .Getenv ("BUILDX_CONFIG" ); buildxConfig != "" {
371371 return buildxConfig
372372 }
373-
373+
374374 stderr := & bytes.Buffer {}
375375 configFile := cliconfig .LoadDefaultConfigFile (stderr )
376376 buildxConfig := filepath .Join (filepath .Dir (configFile .Filename ), "buildx" )
@@ -385,21 +385,21 @@ func tempKubeContextFromClient(kubeClient kubectl.Client) (string, error) {
385385 if ! kubeClient .IsInCluster () {
386386 rawConfig .CurrentContext = kubeClient .CurrentContext ()
387387 }
388-
388+
389389 bytes , err := clientcmd .Write (rawConfig )
390390 if err != nil {
391391 return "" , err
392392 }
393-
393+
394394 tempFile , err := os .CreateTemp ("" , "" )
395395 if err != nil {
396396 return "" , err
397397 }
398-
398+
399399 _ , err = tempFile .Write (bytes )
400400 if err != nil {
401401 return "" , errors .Wrap (err , "error writing to file" )
402402 }
403-
403+
404404 return tempFile .Name (), nil
405405}
0 commit comments