Jelajahi Sumber

archive: Re-add XZ compression support

This shells out to the xz binary to support .tar.xz layers, as
there is no compression/xz support in go.
Alexander Larsson 11 tahun lalu
induk
melakukan
b8a4f570fb
1 mengubah file dengan 11 tambahan dan 3 penghapusan
  1. 11 3
      archive/archive.go

+ 11 - 3
archive/archive.go

@@ -61,6 +61,12 @@ func DetectCompression(source []byte) Compression {
 	return Uncompressed
 }
 
+func xzDecompress(archive io.Reader) (io.Reader, error) {
+	args := []string{"xz", "-d", "-c", "-q"}
+
+	return CmdStream(exec.Command(args[0], args[1:]...), archive, nil)
+}
+
 func DecompressStream(archive io.Reader) (io.Reader, error) {
 	buf := make([]byte, 10)
 	totalN := 0
@@ -85,6 +91,8 @@ func DecompressStream(archive io.Reader) (io.Reader, error) {
 		return gzip.NewReader(wrap)
 	case Bzip2:
 		return bzip2.NewReader(wrap), nil
+	case Xz:
+		return xzDecompress(wrap)
 	default:
 		return nil, fmt.Errorf("Unsupported compression format %s", (&compression).Extension())
 	}
@@ -186,7 +194,7 @@ func TarFilter(path string, options *TarOptions) (io.Reader, error) {
 		}
 	}
 
-	return CmdStream(exec.Command(args[0], args[1:]...), &files, func() {
+	return CmdStream(exec.Command(args[0], args[1:]...), bytes.NewBufferString(files), func() {
 		if tmpDir != "" {
 			_ = os.RemoveAll(tmpDir)
 		}
@@ -332,7 +340,7 @@ func CopyFileWithTar(src, dst string) error {
 // CmdStream executes a command, and returns its stdout as a stream.
 // If the command fails to run or doesn't complete successfully, an error
 // will be returned, including anything written on stderr.
-func CmdStream(cmd *exec.Cmd, input *string, atEnd func()) (io.Reader, error) {
+func CmdStream(cmd *exec.Cmd, input io.Reader, atEnd func()) (io.Reader, error) {
 	if input != nil {
 		stdin, err := cmd.StdinPipe()
 		if err != nil {
@@ -343,7 +351,7 @@ func CmdStream(cmd *exec.Cmd, input *string, atEnd func()) (io.Reader, error) {
 		}
 		// Write stdin if any
 		go func() {
-			_, _ = stdin.Write([]byte(*input))
+			io.Copy(stdin, input)
 			stdin.Close()
 		}()
 	}