Skip to content
Closed
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
47 changes: 37 additions & 10 deletions diff/windows/windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,13 @@ func mountsToLayerAndParents(mounts []mount.Mount) (string, []string, error) {
return "", nil, fmt.Errorf("number of mounts should always be 1 for Windows layers: %w", errdefs.ErrInvalidArgument)
}
mnt := mounts[0]
if mnt.Type != "windows-layer" {

if mnt.Type != "windows-layer" && mnt.Type != "bind" {
// This is a special case error. When this is received the diff service
// will attempt the next differ in the chain which for Windows is the
// lcow differ that we want.
// TODO: Is there any situation where we actually wanted a "bind" mount to
// fall through to the lcow differ?
return "", nil, fmt.Errorf("windowsDiff does not support layer type %s: %w", mnt.Type, errdefs.ErrNotImplemented)
}

Expand All @@ -323,6 +326,30 @@ func mountsToLayerAndParents(mounts []mount.Mount) (string, []string, error) {
return "", nil, err
}

isView := false
for _, o := range mnt.Options {
if o == "ro" {
isView = true
break
}
}

if isView {
if mnt.Type == "bind" && len(parentLayerPaths) != 0 {
return "", nil, fmt.Errorf("unexpected bind-mount View with parents: %w", errdefs.ErrInvalidArgument)
} else if mnt.Type == "bind" {
// rootfs.CreateDiff creates a new, empty View to diff against,
// when diffing something with no parent.
// This makes perfect sense for a walking Diff, but for WCOW,
// we have to recognise this as "diff against nothing"
return "", nil, nil
} else if len(parentLayerPaths) == 0 {
return "", nil, fmt.Errorf("unexpected windows-layer View with no parent: %w", errdefs.ErrInvalidArgument)
}
// Ignore the dummy sandbox.
return parentLayerPaths[0], parentLayerPaths[1:], nil
}

return mnt.Source, parentLayerPaths, nil
}

Expand All @@ -337,8 +364,16 @@ func mountPairToLayerStack(lower, upper []mount.Mount) ([]string, error) {
return nil, fmt.Errorf("Upper mount invalid: %w", err)
}

lowerLayer, lowerParentLayerPaths, err := mountsToLayerAndParents(lower)
if errdefs.IsNotImplemented(err) {
// Upper was a windows-layer or bind, lower is not. We can't handle that.
return nil, fmt.Errorf("windowsDiff cannot diff a windows-layer against a non-windows-layer: %w", errdefs.ErrInvalidArgument)
} else if err != nil {
return nil, fmt.Errorf("Lower mount invalid: %w", err)
}

// Trivial case, diff-against-nothing
if len(lower) == 0 {
if lowerLayer == "" {
if len(upperParentLayerPaths) != 0 {
return nil, fmt.Errorf("windowsDiff cannot diff a layer with parents against a null layer: %w", errdefs.ErrInvalidArgument)
}
Expand All @@ -349,14 +384,6 @@ func mountPairToLayerStack(lower, upper []mount.Mount) ([]string, error) {
return nil, fmt.Errorf("windowsDiff cannot diff a layer with no parents against another layer: %w", errdefs.ErrInvalidArgument)
}

lowerLayer, lowerParentLayerPaths, err := mountsToLayerAndParents(lower)
if errdefs.IsNotImplemented(err) {
// Upper was a windows-layer, lower is not. We can't handle that.
return nil, fmt.Errorf("windowsDiff cannot diff a windows-layer against a non-windows-layer: %w", errdefs.ErrInvalidArgument)
} else if err != nil {
return nil, fmt.Errorf("Lower mount invalid: %w", err)
}

if upperParentLayerPaths[0] != lowerLayer {
return nil, fmt.Errorf("windowsDiff cannot diff a layer against a layer other than its own parent: %w", errdefs.ErrInvalidArgument)
}
Expand Down
10 changes: 8 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/containerd/btrfs v1.0.0
github.com/containerd/cgroups v1.0.4
github.com/containerd/console v1.0.3
github.com/containerd/continuity v0.3.0
github.com/containerd/continuity v0.3.1-0.20220810172617-b4ca35286886
github.com/containerd/fifo v1.0.0
github.com/containerd/go-cni v1.1.6
github.com/containerd/go-runc v1.0.0
Expand All @@ -30,7 +30,7 @@ require (
github.com/emicklei/go-restful/v3 v3.8.0
github.com/fsnotify/fsnotify v1.5.1
github.com/google/go-cmp v0.5.8
github.com/google/uuid v1.2.0
github.com/google/uuid v1.3.0
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/hashicorp/go-multierror v1.1.1
Expand Down Expand Up @@ -87,6 +87,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
github.com/cyphar/filepath-securejoin v0.2.3 // indirect
github.com/emicklei/go-restful v2.9.5+incompatible // indirect
github.com/gabriel-samfira/go-hivex v0.0.0-20190725123041-b40bc95a7ced // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/godbus/dbus/v5 v5.0.6 // indirect
Expand Down Expand Up @@ -122,11 +123,14 @@ require (
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect
go.opentelemetry.io/proto/otlp v0.16.0 // indirect
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/appengine v1.6.7 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
Expand All @@ -136,3 +140,5 @@ require (
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)

replace github.com/Microsoft/hcsshim => github.com/TBBle/hcsshim v0.10.0-rc.0.0.20220811170900-035362c035c9
Loading