github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/worker/uniter/charm/charm.go (about)

     1  // Copyright 2012-2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package charm
     5  
     6  import (
     7  	"errors"
     8  	"net/url"
     9  
    10  	"github.com/juju/charm"
    11  	"github.com/juju/loggo"
    12  	"github.com/juju/utils"
    13  	"github.com/juju/utils/set"
    14  )
    15  
    16  var logger = loggo.GetLogger("juju.worker.uniter.charm")
    17  
    18  // charmURLPath is the path within a charm directory to which Deployers
    19  // commonly write the charm URL of the latest deployed charm.
    20  const charmURLPath = ".juju-charm"
    21  
    22  // Bundle allows access to a charm's files.
    23  type Bundle interface {
    24  
    25  	// Manifest returns a set of slash-separated strings representing files,
    26  	// directories, and symlinks stored in the bundle.
    27  	Manifest() (set.Strings, error)
    28  
    29  	// ExpandTo unpacks the entities referenced in the manifest into the
    30  	// supplied directory. If it returns without error, every file referenced
    31  	// in the charm must be present in the directory; implementations may vary
    32  	// in the details of what they do with other files present.
    33  	ExpandTo(dir string) error
    34  }
    35  
    36  // BundleInfo describes a Bundle.
    37  type BundleInfo interface {
    38  
    39  	// URL returns the charm URL identifying the bundle.
    40  	URL() *charm.URL
    41  
    42  	// Archive URL returns the location of the bundle data.
    43  	ArchiveURL() (*url.URL, utils.SSLHostnameVerification, error)
    44  
    45  	// ArchiveSha256 returns the hex-encoded SHA-256 digest of the bundle data.
    46  	ArchiveSha256() (string, error)
    47  }
    48  
    49  // BundleReader provides a mechanism for getting a Bundle from a BundleInfo.
    50  type BundleReader interface {
    51  
    52  	// Read returns the bundle identified by the supplied info. The abort chan
    53  	// can be used to notify an implementation that it need not complete the
    54  	// operation, and can immediately error out if it is convenient to do so.
    55  	Read(bi BundleInfo, abort <-chan struct{}) (Bundle, error)
    56  }
    57  
    58  // Deployer is responsible for installing and upgrading charms.
    59  type Deployer interface {
    60  
    61  	// Stage must be called to prime the Deployer to install or upgrade the
    62  	// bundle identified by the supplied info. The abort chan can be used to
    63  	// notify an implementation that it need not complete the operation, and
    64  	// can immediately error out if it convenient to do so. It must always
    65  	// be safe to restage the same bundle, or to stage a new bundle.
    66  	Stage(info BundleInfo, abort <-chan struct{}) error
    67  
    68  	// Deploy will install or upgrade the most recently staged bundle.
    69  	// Behaviour is undefined if Stage has not been called. Failures that
    70  	// can be resolved by user intervention will be signalled by returning
    71  	// ErrConflict.
    72  	Deploy() error
    73  
    74  	// NotifyRevert must be called when a conflicted deploy is abandoned, in
    75  	// preparation for a new upgrade.
    76  	NotifyRevert() error
    77  
    78  	// NotifyResolved must be called when the cause of a deploy conflict has
    79  	// been resolved, and a new deploy attempt will be made.
    80  	NotifyResolved() error
    81  }
    82  
    83  // ErrConflict indicates that an upgrade failed and cannot be resolved
    84  // without human intervention.
    85  var ErrConflict = errors.New("charm upgrade has conflicts")
    86  
    87  // ReadCharmURL reads a charm identity file from the supplied path.
    88  func ReadCharmURL(path string) (*charm.URL, error) {
    89  	surl := ""
    90  	if err := utils.ReadYaml(path, &surl); err != nil {
    91  		return nil, err
    92  	}
    93  	return charm.ParseURL(surl)
    94  }
    95  
    96  // WriteCharmURL writes a charm identity file into the supplied path.
    97  func WriteCharmURL(path string, url *charm.URL) error {
    98  	return utils.WriteYaml(path, url.String())
    99  }