Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support syncfs to fix broken image #3891

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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_load.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func NewLoadCommand() *cobra.Command {
loadCommand.Flags().StringSlice("platform", []string{}, "Import content for a specific platform")
loadCommand.RegisterFlagCompletionFunc("platform", completion.Platforms)
loadCommand.Flags().Bool("all-platforms", false, "Import content for all platforms")
loadCommand.Flags().BoolP("sync-fs", "s", true, "Synchronize the underlying filesystem containing files when unpack images")
// #endregion

return loadCommand
Expand All @@ -71,6 +72,10 @@ func processLoadCommandFlags(cmd *cobra.Command) (types.ImageLoadOptions, error)
if err != nil {
return types.ImageLoadOptions{}, err
}
syncfs, err := cmd.Flags().GetBool("sync-fs")
if err != nil {
return types.ImageLoadOptions{}, err
}
return types.ImageLoadOptions{
GOptions: globalOptions,
Input: input,
Expand All @@ -79,6 +84,7 @@ func processLoadCommandFlags(cmd *cobra.Command) (types.ImageLoadOptions, error)
Stdout: cmd.OutOrStdout(),
Stdin: cmd.InOrStdin(),
Quiet: quiet,
SyncFs: syncfs,
}, nil
}

Expand Down
7 changes: 7 additions & 0 deletions cmd/nerdctl/image/image_pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func NewPullCommand() *cobra.Command {
// #endregion

pullCommand.Flags().BoolP("quiet", "q", false, "Suppress verbose output")
pullCommand.Flags().BoolP("sync-fs", "s", true, "Synchronize the underlying filesystem containing files when unpack images")

pullCommand.Flags().String("ipfs-address", "", "multiaddr of IPFS API (default uses $IPFS_PATH env variable if defined or local directory ~/.ipfs)")

Expand Down Expand Up @@ -114,6 +115,11 @@ func processPullCommandFlags(cmd *cobra.Command) (types.ImagePullOptions, error)
return types.ImagePullOptions{}, err
}

syncFs, err := cmd.Flags().GetBool("sync-fs")
if err != nil {
return types.ImagePullOptions{}, err
}

verifyOptions, err := helpers.ProcessImageVerifyOptions(cmd)
if err != nil {
return types.ImagePullOptions{}, err
Expand All @@ -123,6 +129,7 @@ func processPullCommandFlags(cmd *cobra.Command) (types.ImagePullOptions, error)
VerifyOptions: verifyOptions,
OCISpecPlatform: ociSpecPlatform,
Unpack: unpack,
SyncFs: syncFs,
Mode: "always",
Quiet: quiet,
IPFSAddress: ipfsAddressStr,
Expand Down
1 change: 1 addition & 0 deletions pkg/api/types/image_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ type ImagePullOptions struct {
// If nil, it will unpack automatically if only 1 platform is specified.
Unpack *bool
// Content for specific platforms. Empty if `--all-platforms` is true
SyncFs bool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add some comments for SyncFs or move it to after OCISpecPlatform []v1.Platform. The comment above it is for OCISpecPlatform []v1.Platform

OCISpecPlatform []v1.Platform
// Pull mode
Mode string
Expand Down
3 changes: 2 additions & 1 deletion pkg/api/types/load_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ type ImageLoadOptions struct {
// AllPlatforms import content for all platforms
AllPlatforms bool
// Quiet suppresses the load output.
Quiet bool
Quiet bool
SyncFs bool
}
8 changes: 5 additions & 3 deletions pkg/imgutil/imgutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (

containerd "github.com/containerd/containerd/v2/client"
"github.com/containerd/containerd/v2/core/content"
"github.com/containerd/containerd/v2/core/diff"
"github.com/containerd/containerd/v2/core/images"
"github.com/containerd/containerd/v2/core/remotes"
"github.com/containerd/containerd/v2/core/snapshots"
Expand Down Expand Up @@ -59,7 +60,7 @@ type EnsuredImage struct {
type PullMode = string

// GetExistingImage returns the specified image if exists in containerd. Return errdefs.NotFound() if not exists.
func GetExistingImage(ctx context.Context, client *containerd.Client, snapshotter, rawRef string, platform ocispec.Platform) (*EnsuredImage, error) {
func GetExistingImage(ctx context.Context, client *containerd.Client, snapshotter string, syncfs bool, rawRef string, platform ocispec.Platform) (*EnsuredImage, error) {
var res *EnsuredImage
imgwalker := &imagewalker.ImageWalker{
Client: client,
Expand All @@ -82,7 +83,7 @@ func GetExistingImage(ctx context.Context, client *containerd.Client, snapshotte
Remote: getSnapshotterOpts(snapshotter).isRemote(),
}
if unpacked, err := image.IsUnpacked(ctx, snapshotter); err == nil && !unpacked {
if err := image.Unpack(ctx, snapshotter); err != nil {
if err := image.Unpack(ctx, snapshotter, containerd.WithUnpackApplyOpts(diff.WithSyncFs(syncfs))); err != nil {
return err
}
}
Expand Down Expand Up @@ -115,7 +116,7 @@ func EnsureImage(ctx context.Context, client *containerd.Client, rawRef string,

// if not `always` pull and given one platform and image found locally, return existing image directly.
if options.Mode != "always" && len(options.OCISpecPlatform) == 1 {
if res, err := GetExistingImage(ctx, client, options.GOptions.Snapshotter, rawRef, options.OCISpecPlatform[0]); err == nil {
if res, err := GetExistingImage(ctx, client, options.GOptions.Snapshotter, options.SyncFs, rawRef, options.OCISpecPlatform[0]); err == nil {
return res, nil
} else if !errdefs.IsNotFound(err) {
return nil, err
Expand Down Expand Up @@ -204,6 +205,7 @@ func PullImage(ctx context.Context, client *containerd.Client, resolver remotes.
Resolver: resolver,
RemoteOpts: []containerd.RemoteOpt{},
Platforms: options.OCISpecPlatform, // empty for all-platforms
SyncFs: options.SyncFs,
}
if !options.Quiet {
config.ProgressOutput = options.Stderr
Expand Down
4 changes: 2 additions & 2 deletions pkg/imgutil/load/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"strings"

containerd "github.com/containerd/containerd/v2/client"
"github.com/containerd/containerd/v2/core/diff"
"github.com/containerd/containerd/v2/core/images"
"github.com/containerd/containerd/v2/core/images/archive"
"github.com/containerd/containerd/v2/pkg/archive/compression"
Expand Down Expand Up @@ -137,8 +138,7 @@ func unpackImage(ctx context.Context, client *containerd.Client, model images.Im
if !options.Quiet {
fmt.Fprintf(options.Stdout, "unpacking %s (%s)...\n", model.Name, model.Target.Digest)
}

err := image.Unpack(ctx, options.GOptions.Snapshotter)
err := image.Unpack(ctx, options.GOptions.Snapshotter, containerd.WithUnpackApplyOpts(diff.WithSyncFs(options.SyncFs)))
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions pkg/imgutil/pull/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type Config struct {
// RemoteOpts related to unpacking can be set only when len(Platforms) is 1.
RemoteOpts []containerd.RemoteOpt
Platforms []ocispec.Platform // empty for all-platforms
SyncFs bool
}

// Pull loads all resources into the content store and returns the image
Expand Down
2 changes: 1 addition & 1 deletion pkg/ipfs/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func EnsureImage(ctx context.Context, client *containerd.Client, scheme, ref, ip

// if not `always` pull and given one platform and image found locally, return existing image directly.
if options.Mode != "always" && len(options.OCISpecPlatform) == 1 {
if res, err := imgutil.GetExistingImage(ctx, client, options.GOptions.Snapshotter, ref, options.OCISpecPlatform[0]); err == nil {
if res, err := imgutil.GetExistingImage(ctx, client, options.GOptions.Snapshotter, options.SyncFs, ref, options.OCISpecPlatform[0]); err == nil {
return res, nil
} else if !errdefs.IsNotFound(err) {
return nil, err
Expand Down
Loading