Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions cmd/nerdctl/image/image_convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func convertOptions(cmd *cobra.Command) (types.ImageConvertOptions, error) {
if err != nil {
return types.ImageConvertOptions{}, err
}
progressOutput := cmd.ErrOrStderr()
format, err := cmd.Flags().GetString("format")
if err != nil {
return types.ImageConvertOptions{}, err
Expand Down Expand Up @@ -261,8 +262,9 @@ func convertOptions(cmd *cobra.Command) (types.ImageConvertOptions, error) {
}
// #endregion
return types.ImageConvertOptions{
GOptions: globalOptions,
Format: format,
GOptions: globalOptions,
Format: format,
ProgressOutput: progressOutput,
// #region generic flags
Uncompress: uncompress,
Oci: oci,
Expand Down
5 changes: 3 additions & 2 deletions pkg/api/types/image_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ type ImageListOptions struct {

// ImageConvertOptions specifies options for `nerdctl image convert`.
type ImageConvertOptions struct {
Stdout io.Writer
GOptions GlobalCommandOptions
Stdout io.Writer
ProgressOutput io.Writer
GOptions GlobalCommandOptions

// #region generic flags
// Uncompress convert tar.gz layers to uncompressed tar layers
Expand Down
58 changes: 58 additions & 0 deletions pkg/cmd/image/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"github.com/containerd/containerd/v2/core/images/converter"
"github.com/containerd/containerd/v2/core/images/converter/uncompress"
"github.com/containerd/log"
nydusconvert "github.com/containerd/nydus-snapshotter/pkg/converter"

Check failure on line 38 in pkg/cmd/image/convert.go

View workflow job for this annotation

GitHub Actions / go / freebsd

File is not properly formatted (gci)

Check failure on line 38 in pkg/cmd/image/convert.go

View workflow job for this annotation

GitHub Actions / go / windows

File is not properly formatted (gci)

Check failure on line 38 in pkg/cmd/image/convert.go

View workflow job for this annotation

GitHub Actions / go / linux

File is not properly formatted (gci)

Check failure on line 38 in pkg/cmd/image/convert.go

View workflow job for this annotation

GitHub Actions / go / darwin

File is not properly formatted (gci)
"github.com/containerd/stargz-snapshotter/estargz"
estargzconvert "github.com/containerd/stargz-snapshotter/nativeconverter/estargz"
estargzexternaltocconvert "github.com/containerd/stargz-snapshotter/nativeconverter/estargz/externaltoc"
Expand All @@ -45,10 +45,13 @@

"github.com/containerd/nerdctl/v2/pkg/api/types"
"github.com/containerd/nerdctl/v2/pkg/clientutil"
"github.com/containerd/nerdctl/v2/pkg/containerdutil"
converterutil "github.com/containerd/nerdctl/v2/pkg/imgutil/converter"
"github.com/containerd/nerdctl/v2/pkg/imgutil/jobs"
"github.com/containerd/nerdctl/v2/pkg/platformutil"
"github.com/containerd/nerdctl/v2/pkg/referenceutil"
"github.com/containerd/nerdctl/v2/pkg/snapshotterutil"
"github.com/containerd/platforms"
)

func Convert(ctx context.Context, client *containerd.Client, srcRawRef, targetRawRef string, options types.ImageConvertOptions) error {
Expand Down Expand Up @@ -205,11 +208,40 @@
convertOpts = append(convertOpts, converter.WithDockerToOCI(true))
}

var (
cancelProgress context.CancelFunc
progressDone chan struct{}
)

if options.ProgressOutput != nil {
var progressCtx context.Context
progressCtx, cancelProgress = context.WithCancel(ctx)

Check failure on line 218 in pkg/cmd/image/convert.go

View workflow job for this annotation

GitHub Actions / go / freebsd

lostcancel: the cancelProgress function is not used on all paths (possible context leak) (govet)

Check failure on line 218 in pkg/cmd/image/convert.go

View workflow job for this annotation

GitHub Actions / go / windows

lostcancel: the cancelProgress function is not used on all paths (possible context leak) (govet)

Check failure on line 218 in pkg/cmd/image/convert.go

View workflow job for this annotation

GitHub Actions / go / linux

lostcancel: the cancelProgress function is not used on all paths (possible context leak) (govet)

Check failure on line 218 in pkg/cmd/image/convert.go

View workflow job for this annotation

GitHub Actions / go / darwin

lostcancel: the cancelProgress function is not used on all paths (possible context leak) (govet)
progressDone = make(chan struct{})
ongoing := jobs.New(targetRef)
if err := addDescriptorsToJobs(ctx, client, srcRef, platMC, ongoing); err != nil {
return err

Check failure on line 222 in pkg/cmd/image/convert.go

View workflow job for this annotation

GitHub Actions / go / freebsd

lostcancel: this return statement may be reached without using the cancelProgress var defined on line 218 (govet)

Check failure on line 222 in pkg/cmd/image/convert.go

View workflow job for this annotation

GitHub Actions / go / windows

lostcancel: this return statement may be reached without using the cancelProgress var defined on line 218 (govet)

Check failure on line 222 in pkg/cmd/image/convert.go

View workflow job for this annotation

GitHub Actions / go / linux

lostcancel: this return statement may be reached without using the cancelProgress var defined on line 218 (govet)

Check failure on line 222 in pkg/cmd/image/convert.go

View workflow job for this annotation

GitHub Actions / go / darwin

lostcancel: this return statement may be reached without using the cancelProgress var defined on line 218 (govet)
}
go func() {
jobs.ShowProgress(progressCtx, ongoing, client.ContentStore(), options.ProgressOutput)
close(progressDone)
}()
}

// converter.Convert() gains the lease by itself
newImg, err := converterutil.Convert(ctx, client, targetRef, srcRef, convertOpts...)
if err != nil {
if cancelProgress != nil {
cancelProgress()
<-progressDone
}
return err
}

if cancelProgress != nil {
cancelProgress()
<-progressDone
}

res := converterutil.ConvertedImageInfo{
Image: newImg.Name + "@" + newImg.Target.Digest.String(),
}
Expand All @@ -233,6 +265,32 @@
return printConvertedImage(options.Stdout, options, res)
}

func addDescriptorsToJobs(ctx context.Context, client *containerd.Client, srcRef string, platMC platforms.MatchComparer, ongoing *jobs.Jobs) error {
imageService := client.ImageService()
img, err := imageService.Get(ctx, srcRef)
if err != nil {
return err
}
provider := containerdutil.NewProvider(client)
handler := images.ChildrenHandler(provider)
if platMC != nil {
handler = images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
if desc.Platform != nil && !platMC.Match(*desc.Platform) {
return nil, nil
}
return images.Children(ctx, provider, desc)
})
}
err = images.Walk(ctx, images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
ongoing.Add(desc)
return handler(ctx, desc)
}), img.Target)
if err != nil {
return err
}
return nil
}

func getESGZConverter(options types.ImageConvertOptions) (convertFunc converter.ConvertFunc, finalize func(ctx context.Context, cs content.Store, ref string, desc *ocispec.Descriptor) (*images.Image, error), _ error) {
if options.EstargzExternalToc && !options.GOptions.Experimental {
return nil, nil, fmt.Errorf("estargz-external-toc requires experimental mode to be enabled")
Expand Down
Loading