github.com/simonferquel/app@v0.6.1-0.20181012141724-68b7cccf26ac/internal/packager/packing.go (about)

     1  package packager
     2  
     3  import (
     4  	"archive/tar"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  	"os"
     9  	"path/filepath"
    10  
    11  	"github.com/docker/app/internal"
    12  	"github.com/docker/docker/pkg/archive"
    13  )
    14  
    15  func tarAdd(tarout *tar.Writer, path, file string) error {
    16  	payload, err := ioutil.ReadFile(file)
    17  	if err != nil {
    18  		return err
    19  	}
    20  	h := &tar.Header{
    21  		Name:     path,
    22  		Size:     int64(len(payload)),
    23  		Mode:     0644,
    24  		Typeflag: tar.TypeReg,
    25  	}
    26  	err = tarout.WriteHeader(h)
    27  	if err != nil {
    28  		return err
    29  	}
    30  	_, err = tarout.Write(payload)
    31  	return err
    32  }
    33  
    34  // Pack packs the app as a single file
    35  func Pack(appname string, target io.Writer) error {
    36  	tarout := tar.NewWriter(target)
    37  	for _, f := range internal.FileNames {
    38  		err := tarAdd(tarout, f, filepath.Join(appname, f))
    39  		if err != nil {
    40  			return err
    41  		}
    42  	}
    43  	// check for images
    44  	dir := "images"
    45  	_, err := os.Stat(filepath.Join(appname, dir))
    46  	if err == nil {
    47  		if err := tarout.WriteHeader(&tar.Header{
    48  			Typeflag: tar.TypeDir,
    49  			Name:     dir,
    50  			Mode:     0755,
    51  		}); err != nil {
    52  			return err
    53  		}
    54  		imageDir, err := os.Open(filepath.Join(appname, dir))
    55  		if err != nil {
    56  			return err
    57  		}
    58  		defer imageDir.Close()
    59  		images, err := imageDir.Readdirnames(0)
    60  		if err != nil {
    61  			return err
    62  		}
    63  		for _, i := range images {
    64  			err = tarAdd(tarout, filepath.Join(dir, i), filepath.Join(appname, dir, i))
    65  			if err != nil {
    66  				return err
    67  			}
    68  		}
    69  	}
    70  	return tarout.Close()
    71  }
    72  
    73  // Unpack extracts a packed app
    74  func Unpack(appname, targetDir string) error {
    75  	s, err := os.Stat(appname)
    76  	if err != nil {
    77  		// try appending our extension
    78  		appname = internal.DirNameFromAppName(appname)
    79  		s, err = os.Stat(appname)
    80  	}
    81  	if err != nil {
    82  		return err
    83  	}
    84  	if s.IsDir() {
    85  		return fmt.Errorf("app already extracted")
    86  	}
    87  	out := filepath.Join(targetDir, internal.AppNameFromDir(appname)+internal.AppExtension)
    88  	err = os.Mkdir(out, 0755)
    89  	if err != nil {
    90  		return err
    91  	}
    92  	f, err := os.Open(appname)
    93  	if err != nil {
    94  		return err
    95  	}
    96  	defer f.Close()
    97  	return archive.Untar(f, out, &archive.TarOptions{
    98  		NoLchown: true,
    99  	})
   100  }