github.com/jdolitsky/cnab-go@v0.7.1-beta1/packager/import.go (about) 1 package packager 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 9 "github.com/deislabs/cnab-go/bundle" 10 "github.com/deislabs/cnab-go/bundle/loader" 11 "github.com/docker/docker/pkg/archive" 12 ) 13 14 // Importer is responsible for importing a file 15 type Importer struct { 16 Source string 17 Destination string 18 Loader loader.BundleLoader 19 } 20 21 // NewImporter creates a new secure *Importer 22 // 23 // source is the filesystem path to the archive. 24 // destination is the directory to unpack the contents. 25 // load is a loader.BundleLoader preconfigured for loading bundles. 26 func NewImporter(source, destination string, load loader.BundleLoader) *Importer { 27 return &Importer{ 28 Source: source, 29 Destination: destination, 30 Loader: load, 31 } 32 } 33 34 // Import decompresses a bundle from Source (location of the compressed bundle) and properly places artifacts in the correct location(s) 35 func (im *Importer) Import() error { 36 _, _, err := im.Unzip() 37 38 // TODO: https://github.com/deislabs/cnab-go/issues/136 39 40 return err 41 } 42 43 // Unzip decompresses a bundle from Source (location of the compressed bundle) and returns the path of the bundle and the bundle itself. 44 func (im *Importer) Unzip() (string, *bundle.Bundle, error) { 45 baseDir := strings.TrimSuffix(filepath.Base(im.Source), ".tgz") 46 dest := filepath.Join(im.Destination, baseDir) 47 if err := os.MkdirAll(dest, 0755); err != nil { 48 return "", nil, err 49 } 50 51 reader, err := os.Open(im.Source) 52 if err != nil { 53 return "", nil, err 54 } 55 defer reader.Close() 56 57 tarOptions := &archive.TarOptions{ 58 Compression: archive.Gzip, 59 IncludeFiles: []string{"."}, 60 IncludeSourceDir: true, 61 NoLchown: true, 62 } 63 if err := archive.Untar(reader, dest, tarOptions); err != nil { 64 return "", nil, fmt.Errorf("untar failed: %s", err) 65 } 66 67 // We try to load a bundle.cnab file first, and fall back to a bundle.json 68 ext := "cnab" 69 if _, err := os.Stat(filepath.Join(dest, "bundle.cnab")); os.IsNotExist(err) { 70 ext = "json" 71 } 72 73 bun, err := im.Loader.Load(filepath.Join(dest, "bundle."+ext)) 74 if err != nil { 75 removeErr := os.RemoveAll(dest) 76 if removeErr != nil { 77 return "", nil, fmt.Errorf("failed to load and validate bundle.%s on import %s and failed to remove invalid bundle from filesystem %s", ext, err, removeErr) 78 } 79 return "", nil, fmt.Errorf("failed to load and validate bundle.%s: %s", ext, err) 80 } 81 return dest, bun, nil 82 }