... | ... |
@@ -116,7 +116,7 @@ func NewCommandCLI(name, fullName string, in io.Reader, out, errout io.Writer) * |
116 | 116 |
cmd.NewCmdNewBuild(fullName, f, in, out), |
117 | 117 |
cmd.NewCmdStartBuild(fullName, f, in, out), |
118 | 118 |
cmd.NewCmdCancelBuild(cmd.CancelBuildRecommendedCommandName, fullName, f, in, out), |
119 |
- cmd.NewCmdImportImage(fullName, f, out), |
|
119 |
+ cmd.NewCmdImportImage(fullName, f, out, errout), |
|
120 | 120 |
cmd.NewCmdTag(fullName, f, out), |
121 | 121 |
}, |
122 | 122 |
}, |
... | ... |
@@ -8,6 +8,7 @@ import ( |
8 | 8 |
|
9 | 9 |
kapi "k8s.io/kubernetes/pkg/api" |
10 | 10 |
"k8s.io/kubernetes/pkg/api/errors" |
11 |
+ "k8s.io/kubernetes/pkg/api/unversioned" |
|
11 | 12 |
"k8s.io/kubernetes/pkg/fields" |
12 | 13 |
kctl "k8s.io/kubernetes/pkg/kubectl" |
13 | 14 |
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" |
... | ... |
@@ -32,7 +33,7 @@ spec.Tags may have tag and image information imported.` |
32 | 32 |
) |
33 | 33 |
|
34 | 34 |
// NewCmdImportImage implements the OpenShift cli import-image command. |
35 |
-func NewCmdImportImage(fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { |
|
35 |
+func NewCmdImportImage(fullName string, f *clientcmd.Factory, out, errout io.Writer) *cobra.Command { |
|
36 | 36 |
opts := &ImportImageOptions{} |
37 | 37 |
cmd := &cobra.Command{ |
38 | 38 |
Use: "import-image IMAGESTREAM[:TAG]", |
... | ... |
@@ -41,7 +42,7 @@ func NewCmdImportImage(fullName string, f *clientcmd.Factory, out io.Writer) *co |
41 | 41 |
Example: fmt.Sprintf(importImageExample, fullName), |
42 | 42 |
SuggestFor: []string{"image"}, |
43 | 43 |
Run: func(cmd *cobra.Command, args []string) { |
44 |
- kcmdutil.CheckErr(opts.Complete(f, cmd, args, fullName, out)) |
|
44 |
+ kcmdutil.CheckErr(opts.Complete(f, cmd, args, fullName, out, errout)) |
|
45 | 45 |
kcmdutil.CheckErr(opts.Validate(cmd)) |
46 | 46 |
kcmdutil.CheckErr(opts.Run()) |
47 | 47 |
}, |
... | ... |
@@ -72,13 +73,14 @@ type ImportImageOptions struct { |
72 | 72 |
|
73 | 73 |
// helpers |
74 | 74 |
out io.Writer |
75 |
+ errout io.Writer |
|
75 | 76 |
osClient client.Interface |
76 | 77 |
isClient client.ImageStreamInterface |
77 | 78 |
} |
78 | 79 |
|
79 | 80 |
// Complete turns a partially defined ImportImageOptions into a solvent structure |
80 | 81 |
// which can be validated and used for aa import. |
81 |
-func (o *ImportImageOptions) Complete(f *clientcmd.Factory, cmd *cobra.Command, args []string, commandName string, out io.Writer) error { |
|
82 |
+func (o *ImportImageOptions) Complete(f *clientcmd.Factory, cmd *cobra.Command, args []string, commandName string, out, errout io.Writer) error { |
|
82 | 83 |
o.CommandName = commandName |
83 | 84 |
|
84 | 85 |
if len(args) > 0 { |
... | ... |
@@ -102,6 +104,7 @@ func (o *ImportImageOptions) Complete(f *clientcmd.Factory, cmd *cobra.Command, |
102 | 102 |
o.osClient = osClient |
103 | 103 |
o.isClient = osClient.ImageStreams(namespace) |
104 | 104 |
o.out = out |
105 |
+ o.errout = errout |
|
105 | 106 |
|
106 | 107 |
return nil |
107 | 108 |
} |
... | ... |
@@ -147,7 +150,11 @@ func (o *ImportImageOptions) Run() error { |
147 | 147 |
case err != nil: |
148 | 148 |
return err |
149 | 149 |
default: |
150 |
- fmt.Fprint(o.out, "The import completed successfully.\n\n") |
|
150 |
+ if wasError(result) { |
|
151 |
+ fmt.Fprintf(o.errout, "The import completed with errors.\n\n") |
|
152 |
+ } else { |
|
153 |
+ fmt.Fprint(o.out, "The import completed successfully.\n\n") |
|
154 |
+ } |
|
151 | 155 |
|
152 | 156 |
// optimization, use the image stream returned by the call |
153 | 157 |
d := describe.ImageStreamDescriber{Interface: o.osClient} |
... | ... |
@@ -205,6 +212,18 @@ func (o *ImportImageOptions) Run() error { |
205 | 205 |
return nil |
206 | 206 |
} |
207 | 207 |
|
208 |
+func wasError(isi *imageapi.ImageStreamImport) bool { |
|
209 |
+ for _, image := range isi.Status.Images { |
|
210 |
+ if image.Status.Status == unversioned.StatusFailure { |
|
211 |
+ return true |
|
212 |
+ } |
|
213 |
+ } |
|
214 |
+ if isi.Status.Repository != nil && isi.Status.Repository.Status.Status == unversioned.StatusFailure { |
|
215 |
+ return true |
|
216 |
+ } |
|
217 |
+ return false |
|
218 |
+} |
|
219 |
+ |
|
208 | 220 |
// TODO: move to image/api as a helper |
209 | 221 |
type importError struct { |
210 | 222 |
annotation string |
... | ... |
@@ -7,6 +7,7 @@ import ( |
7 | 7 |
"github.com/spf13/cobra" |
8 | 8 |
|
9 | 9 |
kapi "k8s.io/kubernetes/pkg/api" |
10 |
+ "k8s.io/kubernetes/pkg/api/unversioned" |
|
10 | 11 |
|
11 | 12 |
"github.com/openshift/origin/pkg/client/testclient" |
12 | 13 |
imageapi "github.com/openshift/origin/pkg/image/api" |
... | ... |
@@ -373,6 +374,44 @@ func TestCreateImageImport(t *testing.T) { |
373 | 373 |
} |
374 | 374 |
} |
375 | 375 |
|
376 |
+func TestWasError(t *testing.T) { |
|
377 |
+ testCases := map[string]struct { |
|
378 |
+ isi *imageapi.ImageStreamImport |
|
379 |
+ expected bool |
|
380 |
+ }{ |
|
381 |
+ "no error": { |
|
382 |
+ isi: &imageapi.ImageStreamImport{}, |
|
383 |
+ expected: false, |
|
384 |
+ }, |
|
385 |
+ "error importing images": { |
|
386 |
+ isi: &imageapi.ImageStreamImport{ |
|
387 |
+ Status: imageapi.ImageStreamImportStatus{ |
|
388 |
+ Images: []imageapi.ImageImportStatus{ |
|
389 |
+ {Status: unversioned.Status{Status: unversioned.StatusFailure}}, |
|
390 |
+ }, |
|
391 |
+ }, |
|
392 |
+ }, |
|
393 |
+ expected: true, |
|
394 |
+ }, |
|
395 |
+ "error importing repository": { |
|
396 |
+ isi: &imageapi.ImageStreamImport{ |
|
397 |
+ Status: imageapi.ImageStreamImportStatus{ |
|
398 |
+ Repository: &imageapi.RepositoryImportStatus{ |
|
399 |
+ Status: unversioned.Status{Status: unversioned.StatusFailure}, |
|
400 |
+ }, |
|
401 |
+ }, |
|
402 |
+ }, |
|
403 |
+ expected: true, |
|
404 |
+ }, |
|
405 |
+ } |
|
406 |
+ |
|
407 |
+ for name, test := range testCases { |
|
408 |
+ if a, e := wasError(test.isi), test.expected; a != e { |
|
409 |
+ t.Errorf("%s: expected %v, got %v", name, e, a) |
|
410 |
+ } |
|
411 |
+ } |
|
412 |
+} |
|
413 |
+ |
|
376 | 414 |
func listEqual(actual, expected []imageapi.ImageImportSpec) bool { |
377 | 415 |
if len(actual) != len(expected) { |
378 | 416 |
return false |