|
@@ -36,10 +36,17 @@ type (
|
|
NoLchown bool
|
|
NoLchown bool
|
|
Name string
|
|
Name string
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // Archiver allows the reuse of most utility functions of this package
|
|
|
|
+ // with a pluggable Untar function.
|
|
|
|
+ Archiver struct {
|
|
|
|
+ Untar func(io.Reader, string, *TarOptions) error
|
|
|
|
+ }
|
|
)
|
|
)
|
|
|
|
|
|
var (
|
|
var (
|
|
ErrNotImplemented = errors.New("Function not implemented")
|
|
ErrNotImplemented = errors.New("Function not implemented")
|
|
|
|
+ defaultArchiver = &Archiver{Untar}
|
|
)
|
|
)
|
|
|
|
|
|
const (
|
|
const (
|
|
@@ -549,45 +556,47 @@ loop:
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-// TarUntar is a convenience function which calls Tar and Untar, with
|
|
|
|
-// the output of one piped into the other. If either Tar or Untar fails,
|
|
|
|
-// TarUntar aborts and returns the error.
|
|
|
|
-func TarUntar(src string, dst string) error {
|
|
|
|
|
|
+func (archiver *Archiver) TarUntar(src, dst string) error {
|
|
log.Debugf("TarUntar(%s %s)", src, dst)
|
|
log.Debugf("TarUntar(%s %s)", src, dst)
|
|
archive, err := TarWithOptions(src, &TarOptions{Compression: Uncompressed})
|
|
archive, err := TarWithOptions(src, &TarOptions{Compression: Uncompressed})
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
defer archive.Close()
|
|
defer archive.Close()
|
|
- return Untar(archive, dst, nil)
|
|
|
|
|
|
+ return archiver.Untar(archive, dst, nil)
|
|
}
|
|
}
|
|
|
|
|
|
-// UntarPath is a convenience function which looks for an archive
|
|
|
|
-// at filesystem path `src`, and unpacks it at `dst`.
|
|
|
|
-func UntarPath(src, dst string) error {
|
|
|
|
|
|
+// TarUntar is a convenience function which calls Tar and Untar, with the output of one piped into the other.
|
|
|
|
+// If either Tar or Untar fails, TarUntar aborts and returns the error.
|
|
|
|
+func TarUntar(src, dst string) error {
|
|
|
|
+ return defaultArchiver.TarUntar(src, dst)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (archiver *Archiver) UntarPath(src, dst string) error {
|
|
archive, err := os.Open(src)
|
|
archive, err := os.Open(src)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
defer archive.Close()
|
|
defer archive.Close()
|
|
- if err := Untar(archive, dst, nil); err != nil {
|
|
|
|
|
|
+ if err := archiver.Untar(archive, dst, nil); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-// CopyWithTar creates a tar archive of filesystem path `src`, and
|
|
|
|
-// unpacks it at filesystem path `dst`.
|
|
|
|
-// The archive is streamed directly with fixed buffering and no
|
|
|
|
-// intermediary disk IO.
|
|
|
|
-//
|
|
|
|
-func CopyWithTar(src, dst string) error {
|
|
|
|
|
|
+// UntarPath is a convenience function which looks for an archive
|
|
|
|
+// at filesystem path `src`, and unpacks it at `dst`.
|
|
|
|
+func UntarPath(src, dst string) error {
|
|
|
|
+ return defaultArchiver.UntarPath(src, dst)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (archiver *Archiver) CopyWithTar(src, dst string) error {
|
|
srcSt, err := os.Stat(src)
|
|
srcSt, err := os.Stat(src)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
if !srcSt.IsDir() {
|
|
if !srcSt.IsDir() {
|
|
- return CopyFileWithTar(src, dst)
|
|
|
|
|
|
+ return archiver.CopyFileWithTar(src, dst)
|
|
}
|
|
}
|
|
// Create dst, copy src's content into it
|
|
// Create dst, copy src's content into it
|
|
log.Debugf("Creating dest directory: %s", dst)
|
|
log.Debugf("Creating dest directory: %s", dst)
|
|
@@ -595,16 +604,18 @@ func CopyWithTar(src, dst string) error {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
log.Debugf("Calling TarUntar(%s, %s)", src, dst)
|
|
log.Debugf("Calling TarUntar(%s, %s)", src, dst)
|
|
- return TarUntar(src, dst)
|
|
|
|
|
|
+ return archiver.TarUntar(src, dst)
|
|
}
|
|
}
|
|
|
|
|
|
-// CopyFileWithTar emulates the behavior of the 'cp' command-line
|
|
|
|
-// for a single file. It copies a regular file from path `src` to
|
|
|
|
-// path `dst`, and preserves all its metadata.
|
|
|
|
-//
|
|
|
|
-// If `dst` ends with a trailing slash '/', the final destination path
|
|
|
|
-// will be `dst/base(src)`.
|
|
|
|
-func CopyFileWithTar(src, dst string) (err error) {
|
|
|
|
|
|
+// CopyWithTar creates a tar archive of filesystem path `src`, and
|
|
|
|
+// unpacks it at filesystem path `dst`.
|
|
|
|
+// The archive is streamed directly with fixed buffering and no
|
|
|
|
+// intermediary disk IO.
|
|
|
|
+func CopyWithTar(src, dst string) error {
|
|
|
|
+ return defaultArchiver.CopyWithTar(src, dst)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
|
|
log.Debugf("CopyFileWithTar(%s, %s)", src, dst)
|
|
log.Debugf("CopyFileWithTar(%s, %s)", src, dst)
|
|
srcSt, err := os.Stat(src)
|
|
srcSt, err := os.Stat(src)
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -652,7 +663,17 @@ func CopyFileWithTar(src, dst string) (err error) {
|
|
err = er
|
|
err = er
|
|
}
|
|
}
|
|
}()
|
|
}()
|
|
- return Untar(r, filepath.Dir(dst), nil)
|
|
|
|
|
|
+ return archiver.Untar(r, filepath.Dir(dst), nil)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// CopyFileWithTar emulates the behavior of the 'cp' command-line
|
|
|
|
+// for a single file. It copies a regular file from path `src` to
|
|
|
|
+// path `dst`, and preserves all its metadata.
|
|
|
|
+//
|
|
|
|
+// If `dst` ends with a trailing slash '/', the final destination path
|
|
|
|
+// will be `dst/base(src)`.
|
|
|
|
+func CopyFileWithTar(src, dst string) (err error) {
|
|
|
|
+ return defaultArchiver.CopyFileWithTar(src, dst)
|
|
}
|
|
}
|
|
|
|
|
|
// CmdStream executes a command, and returns its stdout as a stream.
|
|
// CmdStream executes a command, and returns its stdout as a stream.
|