@@ -2,10 +2,13 @@ package docker
22
33import (
44 "os"
5+ "strings"
56
67 "context"
78
9+ "github.com/docker/distribution/reference"
810 "github.com/docker/docker/pkg/term"
11+ "github.com/docker/docker/registry"
912
1013 "github.com/covexo/devspace/pkg/util/log"
1114 "github.com/docker/cli/cli/command/image/build"
@@ -21,16 +24,15 @@ import (
2124 "github.com/docker/docker/pkg/jsonmessage"
2225)
2326
24- var isMinikubeVar * bool
25-
2627// Builder holds the necessary information to build and push docker images
2728type Builder struct {
2829 RegistryURL string
2930 ImageName string
3031 ImageTag string
3132
32- imageURL string
33- client client.CommonAPIClient
33+ imageURL string
34+ authConfig * types.AuthConfig
35+ client client.CommonAPIClient
3436}
3537
3638// NewBuilder creates a new docker Builder instance
@@ -49,16 +51,36 @@ func NewBuilder(registryURL, imageName, imageTag string, preferMinikube bool) (*
4951 }
5052 }
5153
54+ imageURL := imageName + ":" + imageTag
55+ if registryURL != "" {
56+ // Check if it's the official registry or not
57+ ref , err := reference .ParseNormalizedNamed (registryURL )
58+ if err != nil {
59+ return nil , err
60+ }
61+
62+ repoInfo , err := registry .ParseRepositoryInfo (ref )
63+ if err != nil {
64+ return nil , err
65+ }
66+
67+ if repoInfo .Index .Official == false {
68+ imageURL = registryURL + "/" + imageName + ":" + imageTag
69+ }
70+ }
71+
5272 return & Builder {
5373 RegistryURL : registryURL ,
5474 ImageName : imageName ,
5575 ImageTag : imageTag ,
56- imageURL : registryURL + "/" + imageName + ":" + imageTag ,
76+ imageURL : imageURL ,
5777 client : cli ,
5878 }, nil
5979}
6080
6181// BuildImage builds a dockerimage with the docker cli
82+ // contextPath is the absolute path to the context path
83+ // dockerfilePath is the absolute path to the dockerfile WITHIN the contextPath
6284func (b * Builder ) BuildImage (contextPath , dockerfilePath string , options * types.ImageBuildOptions ) error {
6385 if options == nil {
6486 options = & types.ImageBuildOptions {}
@@ -76,7 +98,7 @@ func (b *Builder) BuildImage(contextPath, dockerfilePath string, options *types.
7698 }
7799
78100 if err := build .ValidateContextDirectory (contextDir , excludes ); err != nil {
79- return errors .Errorf ("error checking context: '%s'. " , err )
101+ return errors .Errorf ("Error checking context: '%s'" , err )
80102 }
81103
82104 // And canonicalize dockerfile name to a platform-independent one
@@ -105,7 +127,7 @@ func (b *Builder) BuildImage(contextPath, dockerfilePath string, options *types.
105127 AuthConfigs : authConfigs ,
106128 })
107129 if err != nil {
108- return errors . Wrap ( err , "docker build" )
130+ return err
109131 }
110132 defer response .Body .Close ()
111133
@@ -118,36 +140,75 @@ func (b *Builder) BuildImage(contextPath, dockerfilePath string, options *types.
118140 return nil
119141}
120142
121- // Authenticate authenticates the cli with a remote registry
122- func (b * Builder ) Authenticate (user , password string ) error {
123- return nil
124- }
143+ // Authenticate authenticates the client with a remote registry
144+ func (b * Builder ) Authenticate (user , password string , checkCredentialsStore bool ) error {
145+ ctx := context .Background ()
146+ authServer := getOfficialServer (ctx , b .client )
147+ serverAddress := b .RegistryURL
125148
126- // PushImage pushes an image to the specified registry
127- func (b * Builder ) PushImage () error {
128- /*if isMinikube() {
129- err := pushImageMinikube(buildtag)
149+ if serverAddress == "" {
150+ serverAddress = authServer
151+ } else {
152+ ref , err := reference .ParseNormalizedNamed (serverAddress )
153+ if err != nil {
154+ return err
155+ }
130156
131- if err == nil {
132- return nil
157+ repoInfo , err := registry .ParseRepositoryInfo (ref )
158+ if err != nil {
159+ return err
133160 }
134161
135- // Fallback to normal docker cli if minikube failed
162+ if repoInfo .Index .Official {
163+ serverAddress = authServer
164+ }
136165 }
137166
138- ctx := context.Background()
139- dockerArgs := []string{"push", buildtag}
167+ authConfig , err := getDefaultAuthConfig (b .client , checkCredentialsStore , serverAddress , serverAddress == authServer )
168+ if err != nil || authConfig .Username == "" || authConfig .Password == "" {
169+ authConfig .Username = strings .TrimSpace (user )
170+ authConfig .Password = strings .TrimSpace (password )
171+ }
140172
141- cmd := exec.CommandContext(ctx, "docker", dockerArgs...)
173+ response , err := b .client .RegistryLogin (ctx , * authConfig )
174+ if err != nil {
175+ return err
176+ }
177+
178+ if response .IdentityToken != "" {
179+ authConfig .Password = ""
180+ authConfig .IdentityToken = response .IdentityToken
181+ }
182+
183+ b .authConfig = authConfig
184+ return nil
185+ }
186+
187+ // PushImage pushes an image to the specified registry
188+ func (b * Builder ) PushImage () error {
189+ ctx := context .Background ()
190+ ref , err := reference .ParseNormalizedNamed (b .imageURL )
191+ if err != nil {
192+ return err
193+ }
142194
143- cmd.Stdout = log.GetInstance()
144- cmd.Stderr = log.GetInstance()
195+ encodedAuth , err := encodeAuthToBase64 (* b .authConfig )
196+ if err != nil {
197+ return err
198+ }
145199
146- err := cmd.Run()
200+ out , err := b .client .ImagePush (ctx , reference .FamiliarString (ref ), types.ImagePushOptions {
201+ RegistryAuth : encodedAuth ,
202+ })
203+ if err != nil {
204+ return err
205+ }
147206
207+ fd , _ := term .GetFdInfo (os .Stdout )
208+ err = jsonmessage .DisplayJSONMessagesStream (out , log .GetInstance (), fd , false , nil )
148209 if err != nil {
149210 return err
150- }*/
211+ }
151212
152213 return nil
153214}
0 commit comments