Merge pull request #65 from nalind/diffoptions
Make Diff() methods take an optional *DiffOptions
This commit is contained in:
commit
d46b0bfb28
|
|
@ -14,6 +14,7 @@ import (
|
||||||
var (
|
var (
|
||||||
applyDiffFile = ""
|
applyDiffFile = ""
|
||||||
diffFile = ""
|
diffFile = ""
|
||||||
|
diffUncompressed = false
|
||||||
diffGzip = false
|
diffGzip = false
|
||||||
diffBzip2 = false
|
diffBzip2 = false
|
||||||
diffXz = false
|
diffXz = false
|
||||||
|
|
@ -71,28 +72,27 @@ func diff(flags *mflag.FlagSet, action string, m storage.Store, args []string) i
|
||||||
diffStream = f
|
diffStream = f
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
}
|
}
|
||||||
reader, err := m.Diff(from, to)
|
|
||||||
if err != nil {
|
options := storage.DiffOptions{}
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
if diffUncompressed || diffGzip || diffBzip2 || diffXz {
|
||||||
return 1
|
c := archive.Uncompressed
|
||||||
}
|
|
||||||
if diffGzip || diffBzip2 || diffXz {
|
|
||||||
compression := archive.Uncompressed
|
|
||||||
if diffGzip {
|
if diffGzip {
|
||||||
compression = archive.Gzip
|
c = archive.Gzip
|
||||||
} else if diffBzip2 {
|
|
||||||
compression = archive.Bzip2
|
|
||||||
} else if diffXz {
|
|
||||||
compression = archive.Xz
|
|
||||||
}
|
}
|
||||||
compressor, err := archive.CompressStream(diffStream, compression)
|
if diffBzip2 {
|
||||||
|
c = archive.Bzip2
|
||||||
|
}
|
||||||
|
if diffXz {
|
||||||
|
c = archive.Xz
|
||||||
|
}
|
||||||
|
options.Compression = &c
|
||||||
|
}
|
||||||
|
|
||||||
|
reader, err := m.Diff(from, to, &options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
diffStream = compressor
|
|
||||||
defer compressor.Close()
|
|
||||||
}
|
|
||||||
_, err = io.Copy(diffStream, reader)
|
_, err = io.Copy(diffStream, reader)
|
||||||
reader.Close()
|
reader.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -171,9 +171,10 @@ func init() {
|
||||||
action: diff,
|
action: diff,
|
||||||
addFlags: func(flags *mflag.FlagSet, cmd *command) {
|
addFlags: func(flags *mflag.FlagSet, cmd *command) {
|
||||||
flags.StringVar(&diffFile, []string{"-file", "f"}, "", "Write to file instead of stdout")
|
flags.StringVar(&diffFile, []string{"-file", "f"}, "", "Write to file instead of stdout")
|
||||||
|
flags.BoolVar(&diffUncompressed, []string{"-uncompressed", "u"}, diffUncompressed, "Use no compression")
|
||||||
flags.BoolVar(&diffGzip, []string{"-gzip", "c"}, diffGzip, "Compress using gzip")
|
flags.BoolVar(&diffGzip, []string{"-gzip", "c"}, diffGzip, "Compress using gzip")
|
||||||
flags.BoolVar(&diffBzip2, []string{"-bzip2", "-bz2", "b"}, diffBzip2, "Compress using bzip2")
|
flags.BoolVar(&diffBzip2, []string{"-bzip2", "-bz2", "b"}, diffBzip2, "Compress using bzip2 (not currently supported)")
|
||||||
flags.BoolVar(&diffXz, []string{"-xz", "x"}, diffXz, "Compress using xz")
|
flags.BoolVar(&diffXz, []string{"-xz", "x"}, diffXz, "Compress using xz (not currently supported)")
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
commands = append(commands, command{
|
commands = append(commands, command{
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,14 @@ Write the diff to the specified file instead of stdout.
|
||||||
|
|
||||||
**-c | --gzip**
|
**-c | --gzip**
|
||||||
|
|
||||||
Compress the diff using gzip compression. If the layer was populated by a
|
Force the diff to be compressed using gzip compression. If the layer was
|
||||||
layer diff, and that layer diff was compressed, this will be done
|
populated by a layer diff, and that layer diff was compressed, this will be
|
||||||
automatically.
|
done automatically.
|
||||||
|
|
||||||
|
**-u | --uncompressed**
|
||||||
|
|
||||||
|
Force the diff to be uncompressed. If the layer was populated by a layer diff,
|
||||||
|
and that layer diff was compressed, it will be decompressed for output.
|
||||||
|
|
||||||
## EXAMPLE
|
## EXAMPLE
|
||||||
**oci-storage diff my-base-layer**
|
**oci-storage diff my-base-layer**
|
||||||
|
|
|
||||||
20
layers.go
20
layers.go
|
|
@ -81,6 +81,12 @@ type layerMountPoint struct {
|
||||||
MountCount int `json:"count"`
|
MountCount int `json:"count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DiffOptions override the default behavior of Diff() methods.
|
||||||
|
type DiffOptions struct {
|
||||||
|
// Compression, if set overrides the default compressor when generating a diff.
|
||||||
|
Compression *archive.Compression
|
||||||
|
}
|
||||||
|
|
||||||
// ROLayerStore wraps a graph driver, adding the ability to refer to layers by
|
// ROLayerStore wraps a graph driver, adding the ability to refer to layers by
|
||||||
// name, and keeping track of parent-child relationships, along with a list of
|
// name, and keeping track of parent-child relationships, along with a list of
|
||||||
// all known layers.
|
// all known layers.
|
||||||
|
|
@ -107,8 +113,9 @@ type ROLayerStore interface {
|
||||||
// Diff produces a tarstream which can be applied to a layer with the contents
|
// Diff produces a tarstream which can be applied to a layer with the contents
|
||||||
// of the first layer to produce a layer with the contents of the second layer.
|
// of the first layer to produce a layer with the contents of the second layer.
|
||||||
// By default, the parent of the second layer is used as the first
|
// By default, the parent of the second layer is used as the first
|
||||||
// layer, so it need not be specified.
|
// layer, so it need not be specified. Options can be used to override
|
||||||
Diff(from, to string) (io.ReadCloser, error)
|
// default behavior, but are also not required.
|
||||||
|
Diff(from, to string, options *DiffOptions) (io.ReadCloser, error)
|
||||||
|
|
||||||
// DiffSize produces an estimate of the length of the tarstream which would be
|
// DiffSize produces an estimate of the length of the tarstream which would be
|
||||||
// produced by Diff.
|
// produced by Diff.
|
||||||
|
|
@ -741,13 +748,15 @@ func (r *layerStore) newFileGetter(id string) (drivers.FileGetCloser, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) Diff(from, to string) (io.ReadCloser, error) {
|
func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser, error) {
|
||||||
var metadata storage.Unpacker
|
var metadata storage.Unpacker
|
||||||
|
|
||||||
from, to, toLayer, err := r.findParentAndLayer(from, to)
|
from, to, toLayer, err := r.findParentAndLayer(from, to)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ErrLayerUnknown
|
return nil, ErrLayerUnknown
|
||||||
}
|
}
|
||||||
|
// Default to applying the type of encryption that we noted was used
|
||||||
|
// for the layerdiff when it was applied.
|
||||||
compression := archive.Uncompressed
|
compression := archive.Uncompressed
|
||||||
if cflag, ok := toLayer.Flags[compressionFlag]; ok {
|
if cflag, ok := toLayer.Flags[compressionFlag]; ok {
|
||||||
if ctype, ok := cflag.(float64); ok {
|
if ctype, ok := cflag.(float64); ok {
|
||||||
|
|
@ -756,6 +765,11 @@ func (r *layerStore) Diff(from, to string) (io.ReadCloser, error) {
|
||||||
compression = archive.Compression(ctype)
|
compression = archive.Compression(ctype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// If a particular compression type (or no compression) was selected,
|
||||||
|
// use that instead.
|
||||||
|
if options != nil && options.Compression != nil {
|
||||||
|
compression = *options.Compression
|
||||||
|
}
|
||||||
if from != toLayer.Parent {
|
if from != toLayer.Parent {
|
||||||
diff, err := r.driver.Diff(to, from)
|
diff, err := r.driver.Diff(to, from)
|
||||||
if err == nil && (compression != archive.Uncompressed) {
|
if err == nil && (compression != archive.Uncompressed) {
|
||||||
|
|
|
||||||
8
store.go
8
store.go
|
|
@ -298,8 +298,8 @@ type Store interface {
|
||||||
DiffSize(from, to string) (int64, error)
|
DiffSize(from, to string) (int64, error)
|
||||||
|
|
||||||
// Diff returns the tarstream which would specify the changes returned by
|
// Diff returns the tarstream which would specify the changes returned by
|
||||||
// Changes.
|
// Changes. If options are passed in, they can override default behaviors.
|
||||||
Diff(from, to string) (io.ReadCloser, error)
|
Diff(from, to string, options *DiffOptions) (io.ReadCloser, error)
|
||||||
|
|
||||||
// ApplyDiff applies a tarstream to a layer. Information about the tarstream
|
// ApplyDiff applies a tarstream to a layer. Information about the tarstream
|
||||||
// is cached with the layer. Typically, a layer which is populated using a
|
// is cached with the layer. Typically, a layer which is populated using a
|
||||||
|
|
@ -1747,7 +1747,7 @@ func (s *store) DiffSize(from, to string) (int64, error) {
|
||||||
return -1, ErrLayerUnknown
|
return -1, ErrLayerUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *store) Diff(from, to string) (io.ReadCloser, error) {
|
func (s *store) Diff(from, to string, options *DiffOptions) (io.ReadCloser, error) {
|
||||||
rlstore, err := s.LayerStore()
|
rlstore, err := s.LayerStore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -1764,7 +1764,7 @@ func (s *store) Diff(from, to string) (io.ReadCloser, error) {
|
||||||
rlstore.Load()
|
rlstore.Load()
|
||||||
}
|
}
|
||||||
if rlstore.Exists(to) {
|
if rlstore.Exists(to) {
|
||||||
return rlstore.Diff(from, to)
|
return rlstore.Diff(from, to, options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, ErrLayerUnknown
|
return nil, ErrLayerUnknown
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue