 5ca3ac65c4
			
		
	
	5ca3ac65c4
	
	
	
		
			
			Go example:
```go
opts := []converter.Opt{
  // convert Docker media types to OCI ones
  converter.WithDocker2OCI(true),
  // convert tar.gz layers to uncompressed tar layers
  converter.WithLayerConvertFunc(uncompress.LayerConvertFunc),
}
srcRef := "example.com/foo:orig"
dstRef := "example.com/foo:converted"
dstImg, err = converter.Convert(ctx, client, dstRef, srcRef, opts...)
fmt.Println(dstImg.Target)
```
ctr example: `ctr images convert --oci --uncompress example.com/foo:orig example.com/foo:converted`
Go test: `go test -exec sudo -test.root -test.run TestConvert`
The implementation is from https://github.com/containerd/stargz-snapshotter/pull/224,
but eStargz-specific functions are not included in this PR.
eStargz converter can be specified by importing `estargz` package and using `WithLayerConvertFunc(estargz.LayerConvertFunc)` option.
This converter interface will be potentially useful for converting zstd and ocicrypt layers as well.
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
		
	
		
			
				
	
	
		
			89 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			89 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
|    Copyright The containerd Authors.
 | |
| 
 | |
|    Licensed under the Apache License, Version 2.0 (the "License");
 | |
|    you may not use this file except in compliance with the License.
 | |
|    You may obtain a copy of the License at
 | |
| 
 | |
|        http://www.apache.org/licenses/LICENSE-2.0
 | |
| 
 | |
|    Unless required by applicable law or agreed to in writing, software
 | |
|    distributed under the License is distributed on an "AS IS" BASIS,
 | |
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|    See the License for the specific language governing permissions and
 | |
|    limitations under the License.
 | |
| */
 | |
| 
 | |
| package containerd
 | |
| 
 | |
| import (
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/containerd/containerd/images"
 | |
| 	"github.com/containerd/containerd/images/converter"
 | |
| 	"github.com/containerd/containerd/images/converter/uncompress"
 | |
| 	"github.com/containerd/containerd/platforms"
 | |
| 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
 | |
| 	"gotest.tools/v3/assert"
 | |
| )
 | |
| 
 | |
| // TestConvert creates an image from testImage, with the following conversion:
 | |
| // - Media type: Docker -> OCI
 | |
| // - Layer type: tar.gz -> tar
 | |
| // - Arch:       Multi  -> Single
 | |
| func TestConvert(t *testing.T) {
 | |
| 	if testing.Short() {
 | |
| 		t.Skip()
 | |
| 	}
 | |
| 	ctx, cancel := testContext(t)
 | |
| 	defer cancel()
 | |
| 
 | |
| 	client, err := New(address)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	defer client.Close()
 | |
| 
 | |
| 	_, err = client.Fetch(ctx, testImage)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	dstRef := testImage + "-testconvert"
 | |
| 	defPlat := platforms.DefaultStrict()
 | |
| 	opts := []converter.Opt{
 | |
| 		converter.WithDockerToOCI(true),
 | |
| 		converter.WithLayerConvertFunc(uncompress.LayerConvertFunc),
 | |
| 		converter.WithPlatform(defPlat),
 | |
| 	}
 | |
| 	dstImg, err := converter.Convert(ctx, client, dstRef, testImage, opts...)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	defer func() {
 | |
| 		if deleteErr := client.ImageService().Delete(ctx, dstRef); deleteErr != nil {
 | |
| 			t.Fatal(deleteErr)
 | |
| 		}
 | |
| 	}()
 | |
| 	cs := client.ContentStore()
 | |
| 	plats, err := images.Platforms(ctx, cs, dstImg.Target)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	// Assert that the image does not have any extra arch.
 | |
| 	assert.Equal(t, 1, len(plats))
 | |
| 	assert.Check(t, defPlat.Match(plats[0]))
 | |
| 
 | |
| 	// Assert that the media type is converted to OCI and also uncompressed
 | |
| 	mani, err := images.Manifest(ctx, cs, dstImg.Target, defPlat)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	for _, l := range mani.Layers {
 | |
| 		if plats[0].OS == "windows" {
 | |
| 			assert.Equal(t, ocispec.MediaTypeImageLayerNonDistributable, l.MediaType)
 | |
| 		} else {
 | |
| 			assert.Equal(t, ocispec.MediaTypeImageLayer, l.MediaType)
 | |
| 		}
 | |
| 	}
 | |
| }
 |