Skip to content

Commit 1feb234

Browse files
authored
Merge pull request containerd#9401 from fuweid/v2-mode
*: introduce image_pull_with_sync_fs in CRI
2 parents 75f72d6 + 23278c8 commit 1feb234

File tree

15 files changed

+137
-60
lines changed

15 files changed

+137
-60
lines changed

api/next.pb.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3821,6 +3821,13 @@ file {
38213821
type_name: ".containerd.services.diff.v1.ApplyRequest.PayloadsEntry"
38223822
json_name: "payloads"
38233823
}
3824+
field {
3825+
name: "sync_fs"
3826+
number: 4
3827+
label: LABEL_OPTIONAL
3828+
type: TYPE_BOOL
3829+
json_name: "syncFs"
3830+
}
38243831
nested_type {
38253832
name: "PayloadsEntry"
38263833
field {

api/services/diff/v1/diff.pb.go

Lines changed: 66 additions & 56 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/services/diff/v1/diff.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ message ApplyRequest {
4444
repeated containerd.types.Mount mounts = 2;
4545

4646
map<string, google.protobuf.Any> payloads = 3;
47+
// SyncFs is to synchronize the underlying filesystem containing files.
48+
bool sync_fs = 4;
4749
}
4850

4951
message ApplyResponse {

client/image.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,14 @@ func WithUnpackDuplicationSuppressor(suppressor kmutex.KeyedLocker) UnpackOpt {
279279
}
280280
}
281281

282+
// WithUnpackApplyOpts appends new apply options on the UnpackConfig.
283+
func WithUnpackApplyOpts(opts ...diff.ApplyOpt) UnpackOpt {
284+
return func(ctx context.Context, uc *UnpackConfig) error {
285+
uc.ApplyOpts = append(uc.ApplyOpts, opts...)
286+
return nil
287+
}
288+
}
289+
282290
func (i *image) Unpack(ctx context.Context, snapshotterName string, opts ...UnpackOpt) error {
283291
ctx, done, err := i.client.WithLease(ctx)
284292
if err != nil {

contrib/diffservice/service.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ func (s *service) Apply(ctx context.Context, er *diffapi.ApplyRequest) (*diffapi
6060
}
6161
opts = append(opts, diff.WithPayloads(payloads))
6262
}
63+
opts = append(opts, diff.WithSyncFs(er.SyncFs))
6364

6465
ocidesc, err = s.applier.Apply(ctx, desc, mounts, opts...)
6566
if err != nil {

diff/apply/apply.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func (s *fsApplier) Apply(ctx context.Context, desc ocispec.Descriptor, mounts [
9292
r: io.TeeReader(processor, digester.Hash()),
9393
}
9494

95-
if err := apply(ctx, mounts, rc); err != nil {
95+
if err := apply(ctx, mounts, rc, config.SyncFs); err != nil {
9696
return emptyDesc, err
9797
}
9898

diff/apply/apply_darwin.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525
"github.com/containerd/containerd/v2/mount"
2626
)
2727

28-
func apply(ctx context.Context, mounts []mount.Mount, r io.Reader) error {
28+
func apply(ctx context.Context, mounts []mount.Mount, r io.Reader, _sync bool) error {
2929
// We currently do not support mounts nor bind mounts on MacOS in the containerd daemon.
3030
// Using this as an exception to enable native snapshotter and allow further research.
3131
if len(mounts) == 1 && mounts[0].Type == "bind" {
@@ -38,6 +38,8 @@ func apply(ctx context.Context, mounts []mount.Mount, r io.Reader) error {
3838
path := mounts[0].Source
3939
_, err := archive.Apply(ctx, path, r, opts...)
4040
return err
41+
42+
// TODO: Do we need to sync all the filesystems?
4143
}
4244

4345
return mount.WithTempMount(ctx, mounts, func(root string) error {

diff/apply/apply_linux.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,18 @@ import (
2020
"context"
2121
"fmt"
2222
"io"
23+
"os"
2324
"strings"
2425

2526
"github.com/containerd/containerd/v2/archive"
2627
"github.com/containerd/containerd/v2/errdefs"
2728
"github.com/containerd/containerd/v2/mount"
2829
"github.com/containerd/containerd/v2/pkg/userns"
30+
31+
"golang.org/x/sys/unix"
2932
)
3033

31-
func apply(ctx context.Context, mounts []mount.Mount, r io.Reader) error {
34+
func apply(ctx context.Context, mounts []mount.Mount, r io.Reader, sync bool) (retErr error) {
3235
switch {
3336
case len(mounts) == 1 && mounts[0].Type == "overlay":
3437
// OverlayConvertWhiteout (mknod c 0 0) doesn't work in userns.
@@ -50,7 +53,18 @@ func apply(ctx context.Context, mounts []mount.Mount, r io.Reader) error {
5053
opts = append(opts, archive.WithParents(parents))
5154
}
5255
_, err = archive.Apply(ctx, path, r, opts...)
56+
if err == nil && sync {
57+
err = doSyncFs(path)
58+
}
5359
return err
60+
case sync && len(mounts) == 1 && mounts[0].Type == "bind":
61+
defer func() {
62+
if retErr != nil {
63+
return
64+
}
65+
66+
retErr = doSyncFs(mounts[0].Source)
67+
}()
5468
}
5569
return mount.WithTempMount(ctx, mounts, func(root string) error {
5670
_, err := archive.Apply(ctx, root, r)
@@ -75,3 +89,17 @@ func getOverlayPath(options []string) (upper string, lower []string, err error)
7589

7690
return
7791
}
92+
93+
func doSyncFs(file string) error {
94+
fd, err := os.Open(file)
95+
if err != nil {
96+
return fmt.Errorf("failed to open %s: %w", file, err)
97+
}
98+
defer fd.Close()
99+
100+
_, _, errno := unix.Syscall(unix.SYS_SYNCFS, fd.Fd(), 0, 0)
101+
if errno != 0 {
102+
return fmt.Errorf("failed to syncfs for %s: %w", file, errno)
103+
}
104+
return nil
105+
}

diff/apply/apply_other.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ import (
2626
"github.com/containerd/containerd/v2/mount"
2727
)
2828

29-
func apply(ctx context.Context, mounts []mount.Mount, r io.Reader) error {
29+
func apply(ctx context.Context, mounts []mount.Mount, r io.Reader, _sync bool) error {
30+
// TODO: for windows, how to sync?
3031
return mount.WithTempMount(ctx, mounts, func(root string) error {
3132
_, err := archive.Apply(ctx, root, r)
3233
return err

diff/diff.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ type Comparer interface {
6767
type ApplyConfig struct {
6868
// ProcessorPayloads specifies the payload sent to various processors
6969
ProcessorPayloads map[string]typeurl.Any
70+
// SyncFs is to synchronize the underlying filesystem containing files
71+
SyncFs bool
7072
}
7173

7274
// ApplyOpt is used to configure an Apply operation
@@ -125,6 +127,14 @@ func WithPayloads(payloads map[string]typeurl.Any) ApplyOpt {
125127
}
126128
}
127129

130+
// WithSyncFs sets sync flag to the config.
131+
func WithSyncFs(sync bool) ApplyOpt {
132+
return func(_ context.Context, _ ocispec.Descriptor, c *ApplyConfig) error {
133+
c.SyncFs = sync
134+
return nil
135+
}
136+
}
137+
128138
// WithSourceDateEpoch specifies the timestamp used to provide control for reproducibility.
129139
// See also https://reproducible-builds.org/docs/source-date-epoch/ .
130140
//

0 commit comments

Comments
 (0)