Skip to content

Commit 8183c53

Browse files
author
Jan Wozniak
committed
oc import-image: remove legacy code using annotations
fixes #13214
1 parent 84c76c1 commit 8183c53

File tree

2 files changed

+35
-148
lines changed

2 files changed

+35
-148
lines changed

hack/import-restrictions.json

-1
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,6 @@
509509
"github.com/openshift/origin/pkg/project/registry/projectrequest/delegated",
510510
"github.com/openshift/origin/pkg/project/util",
511511
"github.com/openshift/origin/pkg/quota/apis/quota",
512-
"github.com/openshift/origin/pkg/quota/util",
513512
"github.com/openshift/origin/pkg/route/apis/route",
514513
"github.com/openshift/origin/pkg/route/apis/route/validation",
515514
"github.com/openshift/origin/pkg/route/generator",

pkg/oc/cli/cmd/importimage.go

+35-147
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,21 @@ import (
44
"fmt"
55
"io"
66
"strings"
7-
"time"
87

98
"github.com/spf13/cobra"
109

1110
"k8s.io/apimachinery/pkg/api/errors"
1211
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13-
"k8s.io/apimachinery/pkg/fields"
14-
"k8s.io/apimachinery/pkg/watch"
1512
"k8s.io/kubernetes/pkg/api/legacyscheme"
1613
kapi "k8s.io/kubernetes/pkg/apis/core"
1714
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
1815
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
19-
kprinters "k8s.io/kubernetes/pkg/printers"
2016

2117
imageapiv1 "github.com/openshift/api/image/v1"
2218
imageapi "github.com/openshift/origin/pkg/image/apis/image"
2319
imageclientinternal "github.com/openshift/origin/pkg/image/generated/internalclientset"
2420
imageclient "github.com/openshift/origin/pkg/image/generated/internalclientset/typed/image/internalversion"
2521
"github.com/openshift/origin/pkg/oc/cli/describe"
26-
quotautil "github.com/openshift/origin/pkg/quota/util"
2722
)
2823

2924
var (
@@ -170,53 +165,36 @@ func (o *ImportImageOptions) Run() error {
170165
return err
171166
}
172167

173-
// Attempt the new, direct import path
174168
result, err := o.imageClient.ImageStreamImports(isi.Namespace).Create(isi)
175-
err = TransformUnsupportedError(err)
176-
switch {
177-
case err == imageapi.ErrImageStreamImportUnsupported:
178-
case err != nil:
169+
if err != nil {
179170
return err
180-
default:
181-
if o.DryRun {
182-
if wasError(result) {
183-
fmt.Fprintf(o.errout, "The dry-run import completed with errors.\n\n")
184-
} else {
185-
fmt.Fprint(o.out, "The dry-run import completed successfully.\n\n")
186-
}
171+
}
172+
173+
if o.DryRun {
174+
if wasError(result) {
175+
fmt.Fprintf(o.errout, "The dry-run import completed with errors.\n\n")
187176
} else {
188-
if wasError(result) {
189-
fmt.Fprintf(o.errout, "The import completed with errors.\n\n")
190-
} else {
191-
fmt.Fprint(o.out, "The import completed successfully.\n\n")
192-
}
177+
fmt.Fprint(o.out, "The dry-run import completed successfully.\n\n")
193178
}
194-
195-
if result.Status.Import != nil {
196-
// TODO: dry-run doesn't return an image stream, so we have to display partial results
197-
info, err := describe.DescribeImageStream(result.Status.Import)
198-
if err != nil {
199-
return err
200-
}
201-
fmt.Fprintln(o.out, info)
179+
} else {
180+
if wasError(result) {
181+
fmt.Fprintf(o.errout, "The import completed with errors.\n\n")
182+
} else {
183+
fmt.Fprint(o.out, "The import completed successfully.\n\n")
202184
}
185+
}
203186

204-
if repo := result.Status.Repository; repo != nil {
205-
for _, image := range repo.Images {
206-
if image.Image != nil {
207-
info, err := describe.DescribeImage(image.Image, imageapi.JoinImageStreamTag(stream.Name, image.Tag))
208-
if err != nil {
209-
fmt.Fprintf(o.errout, "error: tag %s failed: %v\n", image.Tag, err)
210-
} else {
211-
fmt.Fprintln(o.out, info)
212-
}
213-
} else {
214-
fmt.Fprintf(o.errout, "error: repository tag %s failed: %v\n", image.Tag, image.Status.Message)
215-
}
216-
}
187+
if result.Status.Import != nil {
188+
// TODO: dry-run doesn't return an image stream, so we have to display partial results
189+
info, err := describe.DescribeImageStream(result.Status.Import)
190+
if err != nil {
191+
return err
217192
}
193+
fmt.Fprintln(o.out, info)
194+
}
218195

219-
for _, image := range result.Status.Images {
196+
if repo := result.Status.Repository; repo != nil {
197+
for _, image := range repo.Images {
220198
if image.Image != nil {
221199
info, err := describe.DescribeImage(image.Image, imageapi.JoinImageStreamTag(stream.Name, image.Tag))
222200
if err != nil {
@@ -225,54 +203,27 @@ func (o *ImportImageOptions) Run() error {
225203
fmt.Fprintln(o.out, info)
226204
}
227205
} else {
228-
fmt.Fprintf(o.errout, "error: tag %s failed: %v\n", image.Tag, image.Status.Message)
206+
fmt.Fprintf(o.errout, "error: repository tag %s failed: %v\n", image.Tag, image.Status.Message)
229207
}
230208
}
231-
232-
if r := result.Status.Repository; r != nil && len(r.AdditionalTags) > 0 {
233-
fmt.Fprintf(o.out, "\ninfo: The remote repository contained %d additional tags which were not imported: %s\n", len(r.AdditionalTags), strings.Join(r.AdditionalTags, ", "))
234-
}
235-
return nil
236-
}
237-
238-
// Legacy path, remove when support for older importers is removed
239-
delete(stream.Annotations, imageapi.DockerImageRepositoryCheckAnnotation)
240-
if o.Insecure != nil && *o.Insecure {
241-
if stream.Annotations == nil {
242-
stream.Annotations = make(map[string]string)
243-
}
244-
stream.Annotations[imageapi.InsecureRepositoryAnnotation] = "true"
245-
}
246-
247-
if stream.CreationTimestamp.IsZero() {
248-
stream, err = o.isClient.Create(stream)
249-
} else {
250-
stream, err = o.isClient.Update(stream)
251209
}
252-
if err != nil {
253-
return err
254-
}
255-
256-
fmt.Fprintln(o.out, "Importing (ctrl+c to stop waiting) ...")
257210

258-
resourceVersion := stream.ResourceVersion
259-
updatedStream, err := o.waitForImport(resourceVersion)
260-
if err != nil {
261-
if _, ok := err.(importError); ok {
262-
return err
211+
for _, image := range result.Status.Images {
212+
if image.Image != nil {
213+
info, err := describe.DescribeImage(image.Image, imageapi.JoinImageStreamTag(stream.Name, image.Tag))
214+
if err != nil {
215+
fmt.Fprintf(o.errout, "error: tag %s failed: %v\n", image.Tag, err)
216+
} else {
217+
fmt.Fprintln(o.out, info)
218+
}
219+
} else {
220+
fmt.Fprintf(o.errout, "error: tag %s failed: %v\n", image.Tag, image.Status.Message)
263221
}
264-
return fmt.Errorf("unable to determine if the import completed successfully - please run '%s describe -n %s imagestream/%s' to see if the tags were updated as expected: %v", o.CommandName, stream.Namespace, stream.Name, err)
265222
}
266223

267-
fmt.Fprint(o.out, "The import completed successfully.\n\n")
268-
269-
d := describe.ImageStreamDescriber{ImageClient: o.imageClient}
270-
info, err := d.Describe(updatedStream.Namespace, updatedStream.Name, kprinters.DescriberSettings{})
271-
if err != nil {
272-
return err
224+
if r := result.Status.Repository; r != nil && len(r.AdditionalTags) > 0 {
225+
fmt.Fprintf(o.out, "\ninfo: The remote repository contained %d additional tags which were not imported: %s\n", len(r.AdditionalTags), strings.Join(r.AdditionalTags, ", "))
273226
}
274-
275-
fmt.Fprintln(o.out, info)
276227
return nil
277228
}
278229

@@ -297,45 +248,6 @@ func (e importError) Error() string {
297248
return fmt.Sprintf("unable to import image: %s", e.annotation)
298249
}
299250

300-
func (o *ImportImageOptions) waitForImport(resourceVersion string) (*imageapi.ImageStream, error) {
301-
streamWatch, err := o.isClient.Watch(metav1.ListOptions{FieldSelector: fields.OneTermEqualSelector("metadata.name", o.Name).String(), ResourceVersion: resourceVersion})
302-
if err != nil {
303-
return nil, err
304-
}
305-
defer streamWatch.Stop()
306-
307-
for {
308-
select {
309-
case event, ok := <-streamWatch.ResultChan():
310-
if !ok {
311-
return nil, fmt.Errorf("image stream watch ended prematurely")
312-
}
313-
314-
switch event.Type {
315-
case watch.Modified:
316-
s, ok := event.Object.(*imageapi.ImageStream)
317-
if !ok {
318-
continue
319-
}
320-
annotation, ok := s.Annotations[imageapi.DockerImageRepositoryCheckAnnotation]
321-
if !ok {
322-
continue
323-
}
324-
325-
if _, err := time.Parse(time.RFC3339, annotation); err == nil {
326-
return s, nil
327-
}
328-
return nil, importError{annotation}
329-
330-
case watch.Deleted:
331-
return nil, fmt.Errorf("the image stream was deleted")
332-
case watch.Error:
333-
return nil, fmt.Errorf("error watching image stream")
334-
}
335-
}
336-
}
337-
}
338-
339251
func (o *ImportImageOptions) createImageImport() (*imageapi.ImageStream, *imageapi.ImageStreamImport, error) {
340252
var isi *imageapi.ImageStreamImport
341253
stream, err := o.isClient.Get(o.Name, metav1.GetOptions{})
@@ -593,27 +505,3 @@ func (o *ImportImageOptions) newImageStreamImportTags(stream *imageapi.ImageStre
593505
}
594506
return isi
595507
}
596-
597-
// TransformUnsupportedError converts specific error conditions to unsupported
598-
func TransformUnsupportedError(err error) error {
599-
if err == nil {
600-
return nil
601-
}
602-
if errors.IsNotFound(err) {
603-
status, ok := err.(errors.APIStatus)
604-
if !ok {
605-
return imageapi.ErrImageStreamImportUnsupported
606-
}
607-
if status.Status().Details == nil || status.Status().Details.Kind == "" {
608-
return imageapi.ErrImageStreamImportUnsupported
609-
}
610-
}
611-
// The ImageStreamImport resource exists in v1.1.1 of origin but is not yet
612-
// enabled by policy. A create request will return a Forbidden(403) error.
613-
// We want to return ErrImageStreamImportUnsupported to allow fallback behavior
614-
// in clients.
615-
if errors.IsForbidden(err) && !quotautil.IsErrorQuotaExceeded(err) {
616-
return imageapi.ErrImageStreamImportUnsupported
617-
}
618-
return err
619-
}

0 commit comments

Comments
 (0)