func convert_v1beta3_Image_To_api_Image(in *Image, out *newer.Image, s conversion.Scope) error { if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil { return err } out.DockerImageReference = in.DockerImageReference out.DockerImageManifest = in.DockerImageManifest version := in.DockerImageMetadataVersion if len(version) == 0 { version = "1.0" } if len(in.DockerImageMetadata.RawJSON) > 0 { // TODO: add a way to default the expected kind and version of an object if not set obj, err := kapi.Scheme.New(version, "DockerImage") if err != nil { return err } if err := kapi.Scheme.DecodeInto(in.DockerImageMetadata.RawJSON, obj); err != nil { return err } if err := s.Convert(obj, &out.DockerImageMetadata, 0); err != nil { return err } } out.DockerImageMetadataVersion = version return nil }
func imageWithLayers(id, ref string, layers ...string) imageapi.Image { image := imageapi.Image{ ObjectMeta: kapi.ObjectMeta{ Name: id, Annotations: map[string]string{ imageapi.ManagedByOpenShiftAnnotation: "true", }, }, DockerImageReference: ref, } manifest := imageapi.DockerImageManifest{ FSLayers: []imageapi.DockerFSLayer{}, } for _, layer := range layers { manifest.FSLayers = append(manifest.FSLayers, imageapi.DockerFSLayer{DockerBlobSum: layer}) } manifestBytes, err := json.Marshal(&manifest) if err != nil { panic(err) } image.DockerImageManifest = string(manifestBytes) return image }
func Convert_v1beta3_Image_To_api_Image(in *Image, out *newer.Image, s conversion.Scope) error { if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil { return err } out.DockerImageReference = in.DockerImageReference out.DockerImageManifest = in.DockerImageManifest out.DockerImageManifestMediaType = in.DockerImageManifestMediaType out.DockerImageConfig = in.DockerImageConfig version := in.DockerImageMetadataVersion if len(version) == 0 { version = "1.0" } if len(in.DockerImageMetadata.Raw) > 0 { // TODO: add a way to default the expected kind and version of an object if not set obj, err := api.Scheme.New(unversioned.GroupVersionKind{Version: version, Kind: "DockerImage"}) if err != nil { return err } if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), in.DockerImageMetadata.Raw, obj); err != nil { return err } if err := s.Convert(obj, &out.DockerImageMetadata, 0); err != nil { return err } } out.DockerImageMetadataVersion = version return nil }
func imageWithLayers(id, ref string, configName *string, layers ...string) imageapi.Image { image := imageapi.Image{ ObjectMeta: kapi.ObjectMeta{ Name: id, Annotations: map[string]string{ imageapi.ManagedByOpenShiftAnnotation: "true", }, }, DockerImageReference: ref, } if configName != nil { image.DockerImageMetadata = imageapi.DockerImage{ ID: *configName, } image.DockerImageConfig = fmt.Sprintf("{Digest: %s}", *configName) } image.DockerImageLayers = []imageapi.ImageLayer{} for _, layer := range layers { image.DockerImageLayers = append(image.DockerImageLayers, imageapi.ImageLayer{Name: layer}) } return image }
func newISTag(tag string, imageStream *api.ImageStream, image *api.Image) (*api.ImageStreamTag, error) { istagName := api.JoinImageStreamTag(imageStream.Name, tag) event := api.LatestTaggedImage(imageStream, tag) if event == nil || len(event.Image) == 0 { return nil, kapierrors.NewNotFound("imageStreamTag", istagName) } ist := &api.ImageStreamTag{ ObjectMeta: kapi.ObjectMeta{ Namespace: imageStream.Namespace, Name: istagName, CreationTimestamp: event.Created, Annotations: map[string]string{}, ResourceVersion: imageStream.ResourceVersion, }, } // if the imageStream has Spec.Tags[tag].Annotations[k] = v, copy it to the image's annotations // and add them to the istag's annotations if imageStream.Spec.Tags != nil { if tagRef, ok := imageStream.Spec.Tags[tag]; ok { if image != nil && image.Annotations == nil { image.Annotations = make(map[string]string) } for k, v := range tagRef.Annotations { ist.Annotations[k] = v if image != nil { image.Annotations[k] = v } } } } if image != nil { if err := api.ImageWithMetadata(image); err != nil { return nil, err } image.DockerImageManifest = "" ist.Image = *image } else { ist.Image = api.Image{} ist.Image.Name = event.Image } // Replace the DockerImageReference with the value from event, which contains // real value from status. This should fix the problem for v1 registries, // where mutliple tags point to a single id and only the first image's metadata // is saved. This in turn will always return the pull spec from the first // imported image, which might be different than the requested tag. ist.Image.DockerImageReference = event.DockerImageReference return ist, nil }
func autoConvert_v1_Image_To_api_Image(in *Image, out *api.Image, s conversion.Scope) error { if err := api_v1.Convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { return err } out.DockerImageReference = in.DockerImageReference // TODO: Inefficient conversion - can we improve it? if err := s.Convert(&in.DockerImageMetadata, &out.DockerImageMetadata, 0); err != nil { return err } out.DockerImageMetadataVersion = in.DockerImageMetadataVersion out.DockerImageManifest = in.DockerImageManifest out.DockerImageLayers = *(*[]api.ImageLayer)(unsafe.Pointer(&in.DockerImageLayers)) if in.Signatures != nil { in, out := &in.Signatures, &out.Signatures *out = make([]api.ImageSignature, len(*in)) for i := range *in { if err := Convert_v1_ImageSignature_To_api_ImageSignature(&(*in)[i], &(*out)[i], s); err != nil { return err } } } else { out.Signatures = nil } out.DockerImageSignatures = *(*[][]byte)(unsafe.Pointer(&in.DockerImageSignatures)) out.DockerImageManifestMediaType = in.DockerImageManifestMediaType out.DockerImageConfig = in.DockerImageConfig return nil }
func imageWithLayers(id, ref string, layers ...string) imageapi.Image { image := imageapi.Image{ ObjectMeta: kapi.ObjectMeta{ Name: id, Annotations: map[string]string{ imageapi.ManagedByOpenShiftAnnotation: "true", }, }, DockerImageReference: ref, } image.DockerImageLayers = []imageapi.ImageLayer{} for _, layer := range layers { image.DockerImageLayers = append(image.DockerImageLayers, imageapi.ImageLayer{Name: layer}) } return image }
func convert_v1_Image_To_api_Image(in *Image, out *newer.Image, s conversion.Scope) error { if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil { return err } out.DockerImageReference = in.DockerImageReference out.DockerImageManifest = in.DockerImageManifest version := in.DockerImageMetadataVersion if len(version) == 0 { version = "1.0" } if len(in.DockerImageMetadata.RawJSON) > 0 { // TODO: add a way to default the expected kind and version of an object if not set obj, err := kapi.Scheme.New(unversioned.GroupVersionKind{Version: version, Kind: "DockerImage"}) if err != nil { return err } if err := kapi.Scheme.DecodeInto(in.DockerImageMetadata.RawJSON, obj); err != nil { return err } if err := s.Convert(obj, &out.DockerImageMetadata, 0); err != nil { return err } } out.DockerImageMetadataVersion = version if in.DockerImageLayers != nil { out.DockerImageLayers = make([]newer.ImageLayer, len(in.DockerImageLayers)) for i := range in.DockerImageLayers { if err := s.Convert(&in.DockerImageLayers[i], &out.DockerImageLayers[i], 0); err != nil { return err } } } else { out.DockerImageLayers = nil } return nil }
func fuzzImage(t *testing.T, image *api.Image, seed int64) *api.Image { f := apitesting.FuzzerFor(t, v1.SchemeGroupVersion, rand.NewSource(seed)) f.Funcs( func(j *api.Image, c fuzz.Continue) { c.FuzzNoCustom(j) j.Annotations = make(map[string]string) j.Labels = make(map[string]string) j.Signatures = make([]api.ImageSignature, c.Rand.Intn(3)+2) for i := range j.Signatures { sign := &j.Signatures[i] c.Fuzz(sign) sign.Conditions = make([]api.SignatureCondition, c.Rand.Intn(3)+2) for ci := range sign.Conditions { cond := &sign.Conditions[ci] c.Fuzz(cond) } } for i := 0; i < c.Rand.Intn(3)+2; i++ { j.Labels[c.RandString()] = c.RandString() j.Annotations[c.RandString()] = c.RandString() } }, ) updated := api.Image{} f.Fuzz(&updated) updated.Namespace = image.Namespace updated.Name = image.Name j, err := meta.TypeAccessor(image) if err != nil { t.Fatalf("Unexpected error %v for %#v", err, image) } j.SetKind("") j.SetAPIVersion("") return &updated }
// deserializedManifestFillImageMetadata fills a given image with metadata. func (r *repository) deserializedManifestFillImageMetadata(manifest *schema2.DeserializedManifest, image *imageapi.Image) error { configBytes, err := r.Blobs(r.ctx).Get(r.ctx, manifest.Config.Digest) if err != nil { context.GetLogger(r.ctx).Errorf("failed to get image config %s: %v", manifest.Config.Digest.String(), err) return err } image.DockerImageConfig = string(configBytes) if err := imageapi.ImageWithMetadata(image); err != nil { return err } return nil }
// signedManifestFillImageMetadata fills a given image with metadata. It also corrects layer sizes with blob sizes. Newer // Docker client versions don't set layer sizes in the manifest at all. Origin master needs correct layer // sizes for proper image quota support. That's why we need to fill the metadata in the registry. func (r *repository) signedManifestFillImageMetadata(manifest *schema1.SignedManifest, image *imageapi.Image) error { signatures, err := manifest.Signatures() if err != nil { return err } for _, signDigest := range signatures { image.DockerImageSignatures = append(image.DockerImageSignatures, signDigest) } if err := imageapi.ImageWithMetadata(image); err != nil { return err } refs := manifest.References() blobSet := sets.NewString() image.DockerImageMetadata.Size = int64(0) blobs := r.Blobs(r.ctx) for i := range image.DockerImageLayers { layer := &image.DockerImageLayers[i] // DockerImageLayers represents manifest.Manifest.FSLayers in reversed order desc, err := blobs.Stat(r.ctx, refs[len(image.DockerImageLayers)-i-1].Digest) if err != nil { context.GetLogger(r.ctx).Errorf("failed to stat blobs %s of image %s", layer.Name, image.DockerImageReference) return err } if layer.MediaType == "" { if desc.MediaType != "" { layer.MediaType = desc.MediaType } else { layer.MediaType = schema1.MediaTypeManifestLayer } } layer.LayerSize = desc.Size // count empty layer just once (empty layer may actually have non-zero size) if !blobSet.Has(layer.Name) { image.DockerImageMetadata.Size += desc.Size blobSet.Insert(layer.Name) } } if len(image.DockerImageConfig) > 0 && !blobSet.Has(image.DockerImageMetadata.ID) { blobSet.Insert(image.DockerImageMetadata.ID) image.DockerImageMetadata.Size += int64(len(image.DockerImageConfig)) } return nil }
func (h *manifestSchema2Handler) FillImageMetadata(ctx context.Context, image *imageapi.Image) error { // The manifest.Config references a configuration object for a container by its digest. // It needs to be fetched in order to fill an image object metadata below. configBytes, err := h.repo.Blobs(ctx).Get(ctx, h.manifest.Config.Digest) if err != nil { context.GetLogger(ctx).Errorf("failed to get image config %s: %v", h.manifest.Config.Digest.String(), err) return err } image.DockerImageConfig = string(configBytes) if err := imageapi.ImageWithMetadata(image); err != nil { return err } return nil }
func getFakeImageGetHandler(t *testing.T, namespace string) ktestclient.ReactionFunc { return func(action ktestclient.Action) (handled bool, ret runtime.Object, err error) { switch a := action.(type) { case ktestclient.GetAction: name := a.GetName() res := imageapi.Image{ ObjectMeta: kapi.ObjectMeta{ Name: name, Annotations: map[string]string{imageapi.ManagedByOpenShiftAnnotation: "true"}, }, DockerImageReference: fmt.Sprintf("registry.example.org/%s/%s", namespace, a.GetName()), } switch name { case baseImageWith1LayerDigest: res.DockerImageManifest = baseImageWith1Layer case baseImageWith2LayersDigest: res.DockerImageManifest = baseImageWith2Layers case childImageWith2LayersDigest: res.DockerImageManifest = childImageWith2Layers case childImageWith3LayersDigest: res.DockerImageManifest = childImageWith3Layers case miscImageDigest: res.DockerImageManifest = miscImage default: err := fmt.Errorf("image %q not found", name) t.Error(err.Error()) return true, nil, err } t.Logf("images get handler: returning %q", res.Name) return true, &res, nil } return false, nil, nil } }
func Convert_v1_Image_To_api_Image(in *Image, out *newer.Image, s conversion.Scope) error { if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil { return err } out.DockerImageReference = in.DockerImageReference out.DockerImageManifest = in.DockerImageManifest out.DockerImageManifestMediaType = in.DockerImageManifestMediaType out.DockerImageConfig = in.DockerImageConfig version := in.DockerImageMetadataVersion if len(version) == 0 { version = "1.0" } if len(in.DockerImageMetadata.Raw) > 0 { // TODO: add a way to default the expected kind and version of an object if not set obj, err := api.Scheme.New(unversioned.GroupVersionKind{Version: version, Kind: "DockerImage"}) if err != nil { return err } if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), in.DockerImageMetadata.Raw, obj); err != nil { return err } if err := s.Convert(obj, &out.DockerImageMetadata, 0); err != nil { return err } } out.DockerImageMetadataVersion = version if in.DockerImageLayers != nil { out.DockerImageLayers = make([]newer.ImageLayer, len(in.DockerImageLayers)) for i := range in.DockerImageLayers { out.DockerImageLayers[i].MediaType = in.DockerImageLayers[i].MediaType out.DockerImageLayers[i].Name = in.DockerImageLayers[i].Name out.DockerImageLayers[i].LayerSize = in.DockerImageLayers[i].LayerSize } } else { out.DockerImageLayers = nil } if in.Signatures != nil { out.Signatures = make([]newer.ImageSignature, len(in.Signatures)) for i := range in.Signatures { if err := s.Convert(&in.Signatures[i], &out.Signatures[i], 0); err != nil { return err } } } else { out.Signatures = nil } if in.DockerImageSignatures != nil { out.DockerImageSignatures = nil for _, v := range in.DockerImageSignatures { out.DockerImageSignatures = append(out.DockerImageSignatures, v) } } else { out.DockerImageSignatures = nil } return nil }
// newISTag initializes an image stream tag from an image stream and image. The allowEmptyEvent will create a tag even // in the event that the status tag does does not exist yet (no image has successfully been tagged) or the image is nil. func newISTag(tag string, imageStream *imageapi.ImageStream, image *imageapi.Image, allowEmptyEvent bool) (*imageapi.ImageStreamTag, error) { istagName := imageapi.JoinImageStreamTag(imageStream.Name, tag) event := imageapi.LatestTaggedImage(imageStream, tag) if event == nil || len(event.Image) == 0 { if !allowEmptyEvent { return nil, kapierrors.NewNotFound(imageapi.Resource("imagestreamtags"), istagName) } event = &imageapi.TagEvent{ Created: imageStream.CreationTimestamp, } } ist := &imageapi.ImageStreamTag{ ObjectMeta: kapi.ObjectMeta{ Namespace: imageStream.Namespace, Name: istagName, CreationTimestamp: event.Created, Annotations: map[string]string{}, ResourceVersion: imageStream.ResourceVersion, UID: imageStream.UID, }, Generation: event.Generation, Conditions: imageStream.Status.Tags[tag].Conditions, } if imageStream.Spec.Tags != nil { if tagRef, ok := imageStream.Spec.Tags[tag]; ok { // copy the spec tag ist.Tag = &tagRef if from := ist.Tag.From; from != nil { copied := *from ist.Tag.From = &copied } if gen := ist.Tag.Generation; gen != nil { copied := *gen ist.Tag.Generation = &copied } // if the imageStream has Spec.Tags[tag].Annotations[k] = v, copy it to the image's annotations // and add them to the istag's annotations if image != nil && image.Annotations == nil { image.Annotations = make(map[string]string) } for k, v := range tagRef.Annotations { ist.Annotations[k] = v if image != nil { image.Annotations[k] = v } } } } if image != nil { if err := imageapi.ImageWithMetadata(image); err != nil { return nil, err } image.DockerImageManifest = "" ist.Image = *image } else { ist.Image = imageapi.Image{} ist.Image.Name = event.Image } // Replace the DockerImageReference with the value from event, which contains // real value from status. This should fix the problem for v1 registries, // where mutliple tags point to a single id and only the first image's metadata // is saved. This in turn will always return the pull spec from the first // imported image, which might be different than the requested tag. ist.Image.DockerImageReference = event.DockerImageReference return ist, nil }