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