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: 6 additions & 0 deletions cmd/nerdctl/image/image_save.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func SaveCommand() *cobra.Command {
SilenceErrors: true,
}
cmd.Flags().StringP("output", "o", "", "Write to a file, instead of STDOUT")
cmd.Flags().Bool("skip-verify", false, "Skip verification of remote layers. Use this when the original registry is unavailable but you have all layers locally.")

// #region platform flags
// platform is defined as StringSlice, not StringArray, to allow specifying "--platform=amd64,arm64"
Expand All @@ -67,11 +68,16 @@ func saveOptions(cmd *cobra.Command) (types.ImageSaveOptions, error) {
if err != nil {
return types.ImageSaveOptions{}, err
}
skipVerify, err := cmd.Flags().GetBool("skip-verify")
if err != nil {
return types.ImageSaveOptions{}, err
}

return types.ImageSaveOptions{
GOptions: globalOptions,
AllPlatforms: allPlatforms,
Platform: platform,
SkipVerify: skipVerify,
}, err
}

Expand Down
17 changes: 17 additions & 0 deletions cmd/nerdctl/image/image_save_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,23 @@ func TestSaveContent(t *testing.T) {
testCase.Run(t)
}

func TestSaveSkipVerify(t *testing.T) {
nerdtest.Setup()

testCase := &test.Case{
Require: require.Not(require.Windows),
Setup: func(data test.Data, helpers test.Helpers) {
helpers.Ensure("pull", "--quiet", testutil.CommonImage)
},
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
return helpers.Command("save", "--skip-verify", "-o", filepath.Join(data.Temp().Path(), "out.tar"), testutil.CommonImage)
},
Expected: test.Expects(0, nil, nil),
}

testCase.Run(t)
}

func TestSave(t *testing.T) {
testCase := nerdtest.Setup()

Expand Down
2 changes: 2 additions & 0 deletions pkg/api/types/image_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ type ImageSaveOptions struct {
AllPlatforms bool
// Export content for a specific platform
Platform []string
// Skip verification of remote layers
SkipVerify bool
}

// ImageSignOptions contains options for signing an image. It contains options from
Expand Down
11 changes: 8 additions & 3 deletions pkg/cmd/image/save.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

containerd "github.com/containerd/containerd/v2/client"
"github.com/containerd/containerd/v2/core/images/archive"
"github.com/containerd/log"

"github.com/containerd/nerdctl/v2/pkg/api/types"
"github.com/containerd/nerdctl/v2/pkg/idutil/imagewalker"
Expand Down Expand Up @@ -50,9 +51,13 @@ func Save(ctx context.Context, client *containerd.Client, images []string, optio
}

// Ensure all the layers are here: https://github.com/containerd/nerdctl/issues/3425
err = EnsureAllContent(ctx, client, found.Image.Name, platMC, options.GOptions)
if err != nil {
return err
if !options.SkipVerify {
err = EnsureAllContent(ctx, client, found.Image.Name, platMC, options.GOptions)
if err != nil {
return err
}
} else {
log.G(ctx).Info("Skipping remote layer verification (--skip-verify enabled)")
}

imgName := found.Image.Name
Expand Down
8 changes: 5 additions & 3 deletions pkg/cmd/image/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@
containerd "github.com/containerd/containerd/v2/client"
"github.com/containerd/containerd/v2/core/images"
"github.com/containerd/errdefs"
"github.com/containerd/log"

Check failure on line 26 in pkg/cmd/image/tag.go

View workflow job for this annotation

GitHub Actions / go / windows

File is not properly formatted (gci)

Check failure on line 26 in pkg/cmd/image/tag.go

View workflow job for this annotation

GitHub Actions / go / linux

File is not properly formatted (gci)

Check failure on line 26 in pkg/cmd/image/tag.go

View workflow job for this annotation

GitHub Actions / go / freebsd

File is not properly formatted (gci)

Check failure on line 26 in pkg/cmd/image/tag.go

View workflow job for this annotation

GitHub Actions / go / darwin

File is not properly formatted (gci)

"github.com/containerd/nerdctl/v2/pkg/api/types"
"github.com/containerd/nerdctl/v2/pkg/idutil/imagewalker"
"github.com/containerd/nerdctl/v2/pkg/platformutil"
Expand Down Expand Up @@ -70,8 +69,8 @@

err = EnsureAllContent(ctx, client, srcName, platMC, options.GOptions)
if err != nil {
log.G(ctx).Warn("Unable to fetch missing layers before committing. " +
"If you try to save or push this image, it might fail. See https://github.com/containerd/nerdctl/issues/3439.")
log.G(ctx).Warn("Unable to verify all image layers are present locally (this does not affect the tag operation). " +
"If you later save or push this image, some layers may need to be re-downloaded. See https://github.com/containerd/nerdctl/issues/3439.")
}

img, err := imageService.Get(ctx, srcName)
Expand All @@ -92,5 +91,8 @@
return err
}
}

// Log successful tag operation
log.G(ctx).Infof("Successfully tagged %s", parsedReference.String())
return nil
}
Loading