gopkg.in/juju/charm.v6-unstable@v6.0.0-20171026192109-50d0c219b496/bundlearchive.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the LGPLv3, see LICENCE file for details. 3 4 package charm 5 6 import ( 7 "bytes" 8 "io" 9 "io/ioutil" 10 11 ziputil "github.com/juju/utils/zip" 12 ) 13 14 type BundleArchive struct { 15 zopen zipOpener 16 17 Path string 18 data *BundleData 19 readMe string 20 } 21 22 // ReadBundleArchive reads a bundle archive from the given file path. 23 func ReadBundleArchive(path string) (*BundleArchive, error) { 24 a, err := readBundleArchive(newZipOpenerFromPath(path)) 25 if err != nil { 26 return nil, err 27 } 28 a.Path = path 29 return a, nil 30 } 31 32 // ReadBundleArchiveBytes reads a bundle archive from the given byte 33 // slice. 34 func ReadBundleArchiveBytes(data []byte) (*BundleArchive, error) { 35 zopener := newZipOpenerFromReader(bytes.NewReader(data), int64(len(data))) 36 return readBundleArchive(zopener) 37 } 38 39 // ReadBundleArchiveFromReader returns a BundleArchive that uses 40 // r to read the bundle. The given size must hold the number 41 // of available bytes in the file. 42 // 43 // Note that the caller is responsible for closing r - methods on 44 // the returned BundleArchive may fail after that. 45 func ReadBundleArchiveFromReader(r io.ReaderAt, size int64) (*BundleArchive, error) { 46 return readBundleArchive(newZipOpenerFromReader(r, size)) 47 } 48 49 func readBundleArchive(zopen zipOpener) (*BundleArchive, error) { 50 a := &BundleArchive{ 51 zopen: zopen, 52 } 53 zipr, err := zopen.openZip() 54 if err != nil { 55 return nil, err 56 } 57 defer zipr.Close() 58 reader, err := zipOpenFile(zipr, "bundle.yaml") 59 if err != nil { 60 return nil, err 61 } 62 a.data, err = ReadBundleData(reader) 63 reader.Close() 64 if err != nil { 65 return nil, err 66 } 67 reader, err = zipOpenFile(zipr, "README.md") 68 if err != nil { 69 return nil, err 70 } 71 readMe, err := ioutil.ReadAll(reader) 72 if err != nil { 73 return nil, err 74 } 75 a.readMe = string(readMe) 76 return a, nil 77 } 78 79 // Data implements Bundle.Data. 80 func (a *BundleArchive) Data() *BundleData { 81 return a.data 82 } 83 84 // ReadMe implements Bundle.ReadMe. 85 func (a *BundleArchive) ReadMe() string { 86 return a.readMe 87 } 88 89 // ExpandTo expands the bundle archive into dir, creating it if necessary. 90 // If any errors occur during the expansion procedure, the process will 91 // abort. 92 func (a *BundleArchive) ExpandTo(dir string) error { 93 zipr, err := a.zopen.openZip() 94 if err != nil { 95 return err 96 } 97 defer zipr.Close() 98 return ziputil.ExtractAll(zipr.Reader, dir) 99 }