Implement windowsDiff.Compare via hcsshim/pkg/ociwclayer
This parallels the implementation of windowsDiff.Apply, including bouncing very briefly though archive.WriteDiff and then straight back out into Windows-specific code. It's mostly pulling existing mechanisms from non-Windows Compare or Windows Apply, and highlights that there's probably a lot of scope for refactoring on top of this. Now the export-related integration tests pass CI on Windows. Signed-off-by: Paul "TBBle" Hampson <Paul.Hampson@Pobox.com>
This commit is contained in:
@@ -63,13 +63,34 @@ func Diff(ctx context.Context, a, b string) io.ReadCloser {
|
||||
}
|
||||
|
||||
// WriteDiff writes a tar stream of the computed difference between the
|
||||
// provided directories.
|
||||
// provided paths.
|
||||
//
|
||||
// Produces a tar using OCI style file markers for deletions. Deleted
|
||||
// files will be prepended with the prefix ".wh.". This style is
|
||||
// based off AUFS whiteouts.
|
||||
// See https://github.com/opencontainers/image-spec/blob/master/layer.md
|
||||
func WriteDiff(ctx context.Context, w io.Writer, a, b string) error {
|
||||
func WriteDiff(ctx context.Context, w io.Writer, a, b string, opts ...WriteDiffOpt) error {
|
||||
var options WriteDiffOptions
|
||||
for _, opt := range opts {
|
||||
if err := opt(&options); err != nil {
|
||||
return errors.Wrap(err, "failed to apply option")
|
||||
}
|
||||
}
|
||||
if options.writeDiffFunc == nil {
|
||||
options.writeDiffFunc = writeDiffNaive
|
||||
}
|
||||
|
||||
return options.writeDiffFunc(ctx, w, a, b, options)
|
||||
}
|
||||
|
||||
// writeDiffNaive writes a tar stream of the computed difference between the
|
||||
// provided directories on disk.
|
||||
//
|
||||
// Produces a tar using OCI style file markers for deletions. Deleted
|
||||
// files will be prepended with the prefix ".wh.". This style is
|
||||
// based off AUFS whiteouts.
|
||||
// See https://github.com/opencontainers/image-spec/blob/master/layer.md
|
||||
func writeDiffNaive(ctx context.Context, w io.Writer, a, b string, _ WriteDiffOptions) error {
|
||||
cw := newChangeWriter(w, b)
|
||||
err := fs.Changes(ctx, a, b, cw.HandleChange)
|
||||
if err != nil {
|
||||
|
||||
@@ -70,7 +70,7 @@ func TestOverlayApplyNoParents(t *testing.T) {
|
||||
}
|
||||
fstest.FSSuite(t, overlayDiffApplier{
|
||||
tmp: base,
|
||||
diff: func(ctx context.Context, w io.Writer, a, b string) error {
|
||||
diff: func(ctx context.Context, w io.Writer, a, b string, _ ...WriteDiffOpt) error {
|
||||
cw := newChangeWriter(w, b)
|
||||
cw.addedDirs = nil
|
||||
err := fs.Changes(ctx, a, b, cw.HandleChange)
|
||||
@@ -85,7 +85,7 @@ func TestOverlayApplyNoParents(t *testing.T) {
|
||||
|
||||
type overlayDiffApplier struct {
|
||||
tmp string
|
||||
diff func(context.Context, io.Writer, string, string) error
|
||||
diff func(context.Context, io.Writer, string, string, ...WriteDiffOpt) error
|
||||
t *testing.T
|
||||
}
|
||||
|
||||
|
||||
@@ -73,3 +73,13 @@ func WithParents(p []string) ApplyOpt {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WriteDiffOptions provides additional options for a WriteDiff operation
|
||||
type WriteDiffOptions struct {
|
||||
ParentLayers []string // Windows needs the full list of parent layers
|
||||
|
||||
writeDiffFunc func(context.Context, io.Writer, string, string, WriteDiffOptions) error
|
||||
}
|
||||
|
||||
// WriteDiffOpt allows setting mutable archive write properties on creation
|
||||
type WriteDiffOpt func(options *WriteDiffOptions) error
|
||||
|
||||
@@ -40,3 +40,33 @@ func AsWindowsContainerLayer() ApplyOpt {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// writeDiffWindowsLayers writes a tar stream of the computed difference between the
|
||||
// provided Windows layers
|
||||
//
|
||||
// Produces a tar using OCI style file markers for deletions. Deleted
|
||||
// files will be prepended with the prefix ".wh.". This style is
|
||||
// based off AUFS whiteouts.
|
||||
// See https://github.com/opencontainers/image-spec/blob/master/layer.md
|
||||
func writeDiffWindowsLayers(ctx context.Context, w io.Writer, _, layer string, options WriteDiffOptions) error {
|
||||
return ociwclayer.ExportLayerToTar(ctx, w, layer, options.ParentLayers)
|
||||
}
|
||||
|
||||
// AsWindowsContainerLayerPair indicates that the paths to diff are a pair of
|
||||
// Windows Container Layers. The caller must be holding SeBackupPrivilege.
|
||||
func AsWindowsContainerLayerPair() WriteDiffOpt {
|
||||
return func(options *WriteDiffOptions) error {
|
||||
options.writeDiffFunc = writeDiffWindowsLayers
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithParentLayers provides the Windows Container Layers that are the parents
|
||||
// of the target (right-hand, "upper") layer, if any. The source (left-hand, "lower")
|
||||
// layer passed to WriteDiff should be "" in this case.
|
||||
func WithParentLayers(p []string) WriteDiffOpt {
|
||||
return func(options *WriteDiffOptions) error {
|
||||
options.ParentLayers = p
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user