github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/testing/targz.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package testing
     5  
     6  import (
     7  	"archive/tar"
     8  	"bytes"
     9  	"compress/gzip"
    10  	"crypto/sha256"
    11  	"fmt"
    12  	"io"
    13  	"os"
    14  )
    15  
    16  // TarFile represents a file to be archived.
    17  type TarFile struct {
    18  	Header   tar.Header
    19  	Contents string
    20  }
    21  
    22  var modes = map[os.FileMode]byte{
    23  	os.ModeDir:     tar.TypeDir,
    24  	os.ModeSymlink: tar.TypeSymlink,
    25  	0:              tar.TypeReg,
    26  }
    27  
    28  // NewTarFile returns a new TarFile instance with the given file
    29  // mode and contents.
    30  func NewTarFile(name string, mode os.FileMode, contents string) *TarFile {
    31  	ftype := modes[mode&os.ModeType]
    32  	if ftype == 0 {
    33  		panic(fmt.Errorf("unexpected mode %v", mode))
    34  	}
    35  	// NOTE: Do not set attributes (e.g. times) dynamically, as various
    36  	// tests expect the contents of fake tools archives to be unchanging.
    37  	return &TarFile{
    38  		Header: tar.Header{
    39  			Typeflag: ftype,
    40  			Name:     name,
    41  			Size:     int64(len(contents)),
    42  			Mode:     int64(mode & 0777),
    43  			Uname:    "ubuntu",
    44  			Gname:    "ubuntu",
    45  		},
    46  		Contents: contents,
    47  	}
    48  }
    49  
    50  // TarGz returns the given files in gzipped tar-archive format, along with the sha256 checksum.
    51  func TarGz(files ...*TarFile) ([]byte, string) {
    52  	var buf bytes.Buffer
    53  	sha256hash := sha256.New()
    54  	gzw := gzip.NewWriter(io.MultiWriter(&buf, sha256hash))
    55  	tarw := tar.NewWriter(gzw)
    56  
    57  	for _, f := range files {
    58  		err := tarw.WriteHeader(&f.Header)
    59  		if err != nil {
    60  			panic(err)
    61  		}
    62  		_, err = tarw.Write([]byte(f.Contents))
    63  		if err != nil {
    64  			panic(err)
    65  		}
    66  	}
    67  	err := tarw.Close()
    68  	if err != nil {
    69  		panic(err)
    70  	}
    71  	err = gzw.Close()
    72  	if err != nil {
    73  		panic(err)
    74  	}
    75  	checksum := fmt.Sprintf("%x", sha256hash.Sum(nil))
    76  	return buf.Bytes(), checksum
    77  }