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  }