Browse code

Bug 1312230 - fix image import command to reflect the actual status

Maciej Szulik authored on 2016/09/08 21:03:05
Showing 3 changed files
... ...
@@ -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