@@ -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,34 @@ func NewBuilder(registryURL, imageName, imageTag string, preferMinikube bool) (*
4951 }
5052 }
5153
54+ // Check if it's the official registry or not
55+ ref , err := reference .ParseNormalizedNamed (registryURL )
56+ if err != nil {
57+ return nil , err
58+ }
59+
60+ repoInfo , err := registry .ParseRepositoryInfo (ref )
61+ if err != nil {
62+ return nil , err
63+ }
64+
65+ imageURL := registryURL + "/" + imageName + ":" + imageTag
66+ if repoInfo .Index .Official {
67+ imageURL = imageName + ":" + imageTag
68+ }
69+
5270 return & Builder {
5371 RegistryURL : registryURL ,
5472 ImageName : imageName ,
5573 ImageTag : imageTag ,
56- imageURL : registryURL + "/" + imageName + ":" + imageTag ,
74+ imageURL : imageURL ,
5775 client : cli ,
5876 }, nil
5977}
6078
6179// BuildImage builds a dockerimage with the docker cli
80+ // contextPath is the absolute path to the context path
81+ // dockerfilePath is the absolute path to the dockerfile WITHIN the contextPath
6282func (b * Builder ) BuildImage (contextPath , dockerfilePath string , options * types.ImageBuildOptions ) error {
6383 if options == nil {
6484 options = & types.ImageBuildOptions {}
@@ -76,7 +96,7 @@ func (b *Builder) BuildImage(contextPath, dockerfilePath string, options *types.
7696 }
7797
7898 if err := build .ValidateContextDirectory (contextDir , excludes ); err != nil {
79- return errors .Errorf ("error checking context: '%s'. " , err )
99+ return errors .Errorf ("Error checking context: '%s'" , err )
80100 }
81101
82102 // And canonicalize dockerfile name to a platform-independent one
@@ -105,7 +125,7 @@ func (b *Builder) BuildImage(contextPath, dockerfilePath string, options *types.
105125 AuthConfigs : authConfigs ,
106126 })
107127 if err != nil {
108- return errors . Wrap ( err , "docker build" )
128+ return err
109129 }
110130 defer response .Body .Close ()
111131
@@ -118,36 +138,70 @@ func (b *Builder) BuildImage(contextPath, dockerfilePath string, options *types.
118138 return nil
119139}
120140
121- // Authenticate authenticates the cli with a remote registry
122- func (b * Builder ) Authenticate (user , password string ) error {
123- return nil
124- }
141+ // Authenticate authenticates the client with a remote registry
142+ func (b * Builder ) Authenticate (user , password string , checkCredentialsStore bool ) error {
143+ ctx := context .Background ()
144+ serverAddress := b .RegistryURL
145+ ref , err := reference .ParseNormalizedNamed (serverAddress )
146+ if err != nil {
147+ return err
148+ }
125149
126- // PushImage pushes an image to the specified registry
127- func ( b * Builder ) PushImage () error {
128- /*if isMinikube() {
129- err := pushImageMinikube(buildtag)
150+ repoInfo , err := registry . ParseRepositoryInfo ( ref )
151+ if err != nil {
152+ return err
153+ }
130154
131- if err == nil {
132- return nil
133- }
155+ authServer := getOfficialServer (ctx , b .client )
156+ if repoInfo .Index .Official {
157+ serverAddress = authServer
158+ }
134159
135- // Fallback to normal docker cli if minikube failed
160+ authConfig , err := getDefaultAuthConfig (b .client , checkCredentialsStore , serverAddress , serverAddress == authServer )
161+ if err != nil || authConfig .Username == "" || authConfig .Password == "" {
162+ authConfig .Username = strings .TrimSpace (user )
163+ authConfig .Password = strings .TrimSpace (password )
136164 }
137165
138- ctx := context.Background()
139- dockerArgs := []string{"push", buildtag}
166+ response , err := b .client .RegistryLogin (ctx , * authConfig )
167+ if err != nil {
168+ return err
169+ }
140170
141- cmd := exec.CommandContext(ctx, "docker", dockerArgs...)
171+ if response .IdentityToken != "" {
172+ authConfig .Password = ""
173+ authConfig .IdentityToken = response .IdentityToken
174+ }
142175
143- cmd.Stdout = log.GetInstance()
144- cmd.Stderr = log.GetInstance()
176+ b .authConfig = authConfig
177+ return nil
178+ }
145179
146- err := cmd.Run()
180+ // PushImage pushes an image to the specified registry
181+ func (b * Builder ) PushImage () error {
182+ ctx := context .Background ()
183+ ref , err := reference .ParseNormalizedNamed (b .imageURL )
184+ if err != nil {
185+ return err
186+ }
147187
188+ encodedAuth , err := encodeAuthToBase64 (* b .authConfig )
148189 if err != nil {
149190 return err
150- }*/
191+ }
192+
193+ out , err := b .client .ImagePush (ctx , reference .FamiliarString (ref ), types.ImagePushOptions {
194+ RegistryAuth : encodedAuth ,
195+ })
196+ if err != nil {
197+ return err
198+ }
199+
200+ fd , _ := term .GetFdInfo (os .Stdout )
201+ err = jsonmessage .DisplayJSONMessagesStream (out , log .GetInstance (), fd , false , nil )
202+ if err != nil {
203+ return err
204+ }
151205
152206 return nil
153207}
0 commit comments