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 }