func PutManifestInCompatibleSchema(
	ctx context.Context,
	srcManifest distribution.Manifest,
	tag string,
	toManifests distribution.ManifestService,
	ref reference.Named,
	blobs distribution.BlobService, // support schema2 -> schema1 downconversion
	configJSON []byte, // optional, if not passed blobs will be used
) (digest.Digest, error) {
	var options []distribution.ManifestServiceOption
	if len(tag) > 0 {
		klog.V(5).Infof("Put manifest %s:%s", ref, tag)
		options = []distribution.ManifestServiceOption{distribution.WithTag(tag)}
	} else {
		klog.V(5).Infof("Put manifest %s", ref)
	}
	switch t := srcManifest.(type) {
	case *schema1.SignedManifest:
		manifest, err := convertToSchema2(ctx, blobs, t)
		if err != nil {
			klog.V(2).Infof("Unable to convert manifest to schema2: %v", err)
			return toManifests.Put(ctx, t, distribution.WithTag(tag))
		}
		klog.Infof("warning: Digests are not preserved with schema version 1 images. Support for schema version 1 images will be removed in a future release")
		return toManifests.Put(ctx, manifest, options...)
	}

	toDigest, err := toManifests.Put(ctx, srcManifest, options...)
	if err == nil {
		return toDigest, nil
	}
	errs, ok := err.(errcode.Errors)
	if !ok || len(errs) == 0 {
		return toDigest, err
	}
	errcode, ok := errs[0].(errcode.Error)
	if !ok || errcode.ErrorCode() != v2.ErrorCodeManifestInvalid {
		return toDigest, err
	}
	// try downconverting to v2-schema1
	schema2Manifest, ok := srcManifest.(*schema2.DeserializedManifest)
	if !ok {
		return toDigest, err
	}
	tagRef, tagErr := reference.WithTag(ref, tag)
	if tagErr != nil {
		return toDigest, err
	}
	klog.V(5).Infof("Registry reported invalid manifest error, attempting to convert to v2schema1 as ref %s", tagRef)
	schema1Manifest, convertErr := convertToSchema1(ctx, blobs, configJSON, schema2Manifest, tagRef)
	if convertErr != nil {
		if klog.V(6).Enabled() {
			_, data, _ := schema2Manifest.Payload()
			klog.Infof("Input schema\n%s", string(data))
		}
		klog.V(2).Infof("Unable to convert manifest to schema1: %v", convertErr)
		return toDigest, err
	}
	if klog.V(6).Enabled() {
		_, data, _ := schema1Manifest.Payload()
		klog.Infof("Converted to v2schema1\n%s", string(data))
	}
	return toManifests.Put(ctx, schema1Manifest, distribution.WithTag(tag))
}
// TODO: Remove support for v2 schema in 4.9
Remove support for v2 schema in 4.9
// TODO : Remove support for v2 schema in 4 . 9
func PutManifestInCompatibleSchema(
	ctx context.Context,
	srcManifest distribution.Manifest,
	tag string,
	toManifests distribution.ManifestService,
	ref reference.Named,
	blobs distribution.BlobService, 
	configJSON []byte, 
) (digest.Digest, error) {
	var options []distribution.ManifestServiceOption
	if len(tag) > 0 {
		klog.V(5).Infof("Put manifest %s:%s", ref, tag)
		options = []distribution.ManifestServiceOption{distribution.WithTag(tag)}
	} else {
		klog.V(5).Infof("Put manifest %s", ref)
	}
	switch t := srcManifest.(type) {
	case *schema1.SignedManifest:
		manifest, err := convertToSchema2(ctx, blobs, t)
		if err != nil {
			klog.V(2).Infof("Unable to convert manifest to schema2: %v", err)
			return toManifests.Put(ctx, t, distribution.WithTag(tag))
		}
		klog.Infof("warning: Digests are not preserved with schema version 1 images. Support for schema version 1 images will be removed in a future release")
		return toManifests.Put(ctx, manifest, options...)
	}
	toDigest, err := toManifests.Put(ctx, srcManifest, options...)
	if err == nil {
		return toDigest, nil
	}
	errs, ok := err.(errcode.Errors)
	if !ok || len(errs) == 0 {
		return toDigest, err
	}
	errcode, ok := errs[0].(errcode.Error)
	if !ok || errcode.ErrorCode() != v2.ErrorCodeManifestInvalid {
		return toDigest, err
	}
	schema2Manifest, ok := srcManifest.(*schema2.DeserializedManifest)
	if !ok {
		return toDigest, err
	}
	tagRef, tagErr := reference.WithTag(ref, tag)
	if tagErr != nil {
		return toDigest, err
	}
	klog.V(5).Infof("Registry reported invalid manifest error, attempting to convert to v2schema1 as ref %s", tagRef)
	schema1Manifest, convertErr := convertToSchema1(ctx, blobs, configJSON, schema2Manifest, tagRef)
	if convertErr != nil {
		if klog.V(6).Enabled() {
			_, data, _ := schema2Manifest.Payload()
			klog.Infof("Input schema\n%s", string(data))
		}
		klog.V(2).Infof("Unable to convert manifest to schema1: %v", convertErr)
		return toDigest, err
	}
	if klog.V(6).Enabled() {
		_, data, _ := schema1Manifest.Payload()
		klog.Infof("Converted to v2schema1\n%s", string(data))
	}
	return toManifests.Put(ctx, schema1Manifest, distribution.WithTag(tag))
}
func PutManifestInCompatibleSchema ( ctx context . Context , srcManifest distribution . Manifest , tag string , toManifests distribution . ManifestService , ref reference . Named , blobs distribution . BlobService , configJSON [ ] byte , ) ( digest . Digest , error ) { var options [ ] distribution . ManifestServiceOption if len ( tag ) > 0 { klog . V ( 5 ) . Infof ( " " , ref , tag ) options = [ ] distribution . ManifestServiceOption { distribution . WithTag ( tag ) } } else { klog . V ( 5 ) . Infof ( " " , ref ) } switch t := srcManifest . ( type ) { case * schema1 . SignedManifest : manifest , err := convertToSchema2 ( ctx , blobs , t ) if err != nil { klog . V ( 2 ) . Infof ( " " , err ) return toManifests . Put ( ctx , t , distribution . WithTag ( tag ) ) } klog . Infof ( " " ) return toManifests . Put ( ctx , manifest , options ... ) } toDigest , err := toManifests . Put ( ctx , srcManifest , options ... ) if err == nil { return toDigest , nil } errs , ok := err . ( errcode . Errors ) if ! ok || len ( errs ) == 0 { return toDigest , err } errcode , ok := errs [ 0 ] . ( errcode . Error ) if ! ok || errcode . ErrorCode ( ) != v2 . ErrorCodeManifestInvalid { return toDigest , err } schema2Manifest , ok := srcManifest . ( * schema2 . DeserializedManifest ) if ! ok { return toDigest , err } tagRef , tagErr := reference . WithTag ( ref , tag ) if tagErr != nil { return toDigest , err } klog . V ( 5 ) . Infof ( " " , tagRef ) schema1Manifest , convertErr := convertToSchema1 ( ctx , blobs , configJSON , schema2Manifest , tagRef ) if convertErr != nil { if klog . V ( 6 ) . Enabled ( ) { _ , data , _ := schema2Manifest . Payload ( ) klog . Infof ( " \n " , string ( data ) ) } klog . V ( 2 ) . Infof ( " " , convertErr ) return toDigest , err } if klog . V ( 6 ) . Enabled ( ) { _ , data , _ := schema1Manifest . Payload ( ) klog . Infof ( " \n " , string ( data ) ) } return toManifests . Put ( ctx , schema1Manifest , distribution . WithTag ( tag ) ) }
Remove support for v2 schema in 4.9
Remove support for v2 schema in 4 . 9
// support schema2 -> schema1 downconversion // optional, if not passed blobs will be used // try downconverting to v2-schema1