Pulling was broken because the upstream URL was wrong.
Clayton Coleman authored on 2016/05/04 02:55:35... | ... |
@@ -8,6 +8,7 @@ import ( |
8 | 8 |
"strings" |
9 | 9 |
|
10 | 10 |
docker "github.com/fsouza/go-dockerclient" |
11 |
+ "github.com/golang/glog" |
|
11 | 12 |
"github.com/spf13/cobra" |
12 | 13 |
|
13 | 14 |
"k8s.io/kubernetes/pkg/credentialprovider" |
... | ... |
@@ -111,5 +112,22 @@ func (o *DockerbuildOptions) Run() error { |
111 | 111 |
e.Directory = o.Directory |
112 | 112 |
e.Tag = o.Tag |
113 | 113 |
e.AuthFn = o.Keyring.Lookup |
114 |
- return e.Build(f, o.Arguments) |
|
114 |
+ e.LogFn = func(format string, args ...interface{}) { |
|
115 |
+ if glog.V(2) { |
|
116 |
+ glog.Infof("Builder: "+format, args...) |
|
117 |
+ } else { |
|
118 |
+ fmt.Fprintf(e.ErrOut, "# %s\n", fmt.Sprintf(format, args...)) |
|
119 |
+ } |
|
120 |
+ } |
|
121 |
+ return stripLeadingError(e.Build(f, o.Arguments)) |
|
122 |
+} |
|
123 |
+ |
|
124 |
+func stripLeadingError(err error) error { |
|
125 |
+ if err == nil { |
|
126 |
+ return err |
|
127 |
+ } |
|
128 |
+ if strings.HasPrefix(err.Error(), "Error: ") { |
|
129 |
+ return fmt.Errorf(strings.TrimPrefix(err.Error(), "Error: ")) |
|
130 |
+ } |
|
131 |
+ return err |
|
115 | 132 |
} |
... | ... |
@@ -32,6 +32,9 @@ type ClientExecutor struct { |
32 | 32 |
Excludes []string |
33 | 33 |
// Tag is an optional value to tag the resulting built image. |
34 | 34 |
Tag string |
35 |
+ // AllowPull when set will pull images that are not present on |
|
36 |
+ // the daemon. |
|
37 |
+ AllowPull bool |
|
35 | 38 |
|
36 | 39 |
Out, ErrOut io.Writer |
37 | 40 |
|
... | ... |
@@ -51,6 +54,8 @@ type ClientExecutor struct { |
51 | 51 |
AuthFn func(name string) ([]docker.AuthConfiguration, bool) |
52 | 52 |
// HostConfig is used to start the container (if necessary). |
53 | 53 |
HostConfig *docker.HostConfig |
54 |
+ // LogFn is an optional command to log information to the end user |
|
55 |
+ LogFn func(format string, args ...interface{}) |
|
54 | 56 |
} |
55 | 57 |
|
56 | 58 |
// NewClientExecutor creates a client executor. |
... | ... |
@@ -162,6 +167,9 @@ func (e *ClientExecutor) Build(r io.Reader, args map[string]string) error { |
162 | 162 |
return err |
163 | 163 |
} |
164 | 164 |
glog.V(4).Infof("step: %s", step.Original) |
165 |
+ if e.LogFn != nil { |
|
166 |
+ e.LogFn(step.Original) |
|
167 |
+ } |
|
165 | 168 |
if err := b.Run(step, e); err != nil { |
166 | 169 |
return err |
167 | 170 |
} |
... | ... |
@@ -172,8 +180,14 @@ func (e *ClientExecutor) Build(r io.Reader, args map[string]string) error { |
172 | 172 |
if len(e.Tag) > 0 { |
173 | 173 |
repository, tag = docker.ParseRepositoryTag(e.Tag) |
174 | 174 |
glog.V(4).Infof("Committing built container %s as image %q: %#v", e.Container.ID, e.Tag, config) |
175 |
+ if e.LogFn != nil { |
|
176 |
+ e.LogFn("Committing changes to %s ...", e.Tag) |
|
177 |
+ } |
|
175 | 178 |
} else { |
176 | 179 |
glog.V(4).Infof("Committing built container %s: %#v", e.Container.ID, config) |
180 |
+ if e.LogFn != nil { |
|
181 |
+ e.LogFn("Committing changes ...") |
|
182 |
+ } |
|
177 | 183 |
} |
178 | 184 |
|
179 | 185 |
image, err := e.Client.CommitContainer(docker.CommitContainerOptions{ |
... | ... |
@@ -187,6 +201,9 @@ func (e *ClientExecutor) Build(r io.Reader, args map[string]string) error { |
187 | 187 |
} |
188 | 188 |
e.Image = image |
189 | 189 |
glog.V(4).Infof("Committed %s to %s", e.Container.ID, e.Image.ID) |
190 |
+ if e.LogFn != nil { |
|
191 |
+ e.LogFn("Done") |
|
192 |
+ } |
|
190 | 193 |
return nil |
191 | 194 |
} |
192 | 195 |
|
... | ... |
@@ -214,7 +231,7 @@ func (e *ClientExecutor) CreateScratchImage() (string, error) { |
214 | 214 |
if _, err := io.ReadFull(rand.Reader, random); err != nil { |
215 | 215 |
return "", err |
216 | 216 |
} |
217 |
- name := fmt.Sprintf("scratch-%s", base64.URLEncoding.EncodeToString(random)) |
|
217 |
+ name := fmt.Sprintf("scratch-%s", strings.TrimRight(base64.URLEncoding.EncodeToString(random), "=")) |
|
218 | 218 |
|
219 | 219 |
buf := &bytes.Buffer{} |
220 | 220 |
w := tar.NewWriter(buf) |
... | ... |
@@ -243,27 +260,29 @@ func (e *ClientExecutor) LoadImage(from string) (*docker.Image, error) { |
243 | 243 |
return nil, err |
244 | 244 |
} |
245 | 245 |
|
246 |
- var registry string |
|
247 |
- repository, tag := docker.ParseRepositoryTag(from) |
|
248 |
- if parts := strings.SplitN(repository, "/", 2); len(parts) > 1 { |
|
249 |
- registry, repository = parts[0], parts[1] |
|
246 |
+ if !e.AllowPull { |
|
247 |
+ glog.V(4).Info("image %s did not exist", from) |
|
248 |
+ return nil, docker.ErrNoSuchImage |
|
250 | 249 |
} |
251 | 250 |
|
251 |
+ repository, _ := docker.ParseRepositoryTag(from) |
|
252 |
+ |
|
253 |
+ glog.V(4).Infof("attempting to pull %s with auth from repository %s", from, repository) |
|
254 |
+ |
|
252 | 255 |
// TODO: we may want to abstract looping over multiple credentials |
253 | 256 |
auth, _ := e.AuthFn(repository) |
254 | 257 |
if len(auth) == 0 { |
255 | 258 |
auth = append(auth, docker.AuthConfiguration{}) |
256 | 259 |
} |
257 | 260 |
|
261 |
+ if e.LogFn != nil { |
|
262 |
+ e.LogFn("Image %s was not found, pulling ...", from) |
|
263 |
+ } |
|
264 |
+ |
|
258 | 265 |
var lastErr error |
259 | 266 |
for _, config := range auth { |
260 | 267 |
// TODO: handle IDs? |
261 |
- err = e.Client.PullImage(docker.PullImageOptions{ |
|
262 |
- Registry: registry, |
|
263 |
- Repository: repository, |
|
264 |
- Tag: tag, |
|
265 |
- }, config) |
|
266 |
- if err == nil { |
|
268 |
+ if err = e.Client.PullImage(docker.PullImageOptions{Repository: from}, config); err == nil { |
|
267 | 269 |
break |
268 | 270 |
} |
269 | 271 |
lastErr = err |