func addCharm(c *C, st *State, series string, ch charm.Charm) *Charm { ident := fmt.Sprintf("%s-%s-%d", series, ch.Meta().Name, ch.Revision()) curl := charm.MustParseURL("local:" + series + "/" + ident) bundleURL, err := url.Parse("http://bundles.testing.invalid/" + ident) c.Assert(err, IsNil) sch, err := st.AddCharm(ch, curl, bundleURL, ident+"-sha256") c.Assert(err, IsNil) return sch }
func (conn *Conn) addCharm(curl *charm.URL, ch charm.Charm) (*state.Charm, error) { var f *os.File name := charm.Quote(curl.String()) switch ch := ch.(type) { case *charm.Dir: var err error if f, err = ioutil.TempFile("", name); err != nil { return nil, err } defer os.Remove(f.Name()) defer f.Close() err = ch.BundleTo(f) if err != nil { return nil, fmt.Errorf("cannot bundle charm: %v", err) } if _, err := f.Seek(0, 0); err != nil { return nil, err } case *charm.Bundle: var err error if f, err = os.Open(ch.Path); err != nil { return nil, fmt.Errorf("cannot read charm bundle: %v", err) } defer f.Close() default: return nil, fmt.Errorf("unknown charm type %T", ch) } h := sha256.New() size, err := io.Copy(h, f) if err != nil { return nil, err } digest := hex.EncodeToString(h.Sum(nil)) if _, err := f.Seek(0, 0); err != nil { return nil, err } storage := conn.Environ.Storage() log.Infof("writing charm to storage [%d bytes]", size) if err := storage.Put(name, f, size); err != nil { return nil, fmt.Errorf("cannot put charm: %v", err) } ustr, err := storage.URL(name) if err != nil { return nil, fmt.Errorf("cannot get storage URL for charm: %v", err) } u, err := url.Parse(ustr) if err != nil { return nil, fmt.Errorf("cannot parse storage URL: %v", err) } log.Infof("adding charm to state") sch, err := conn.State.AddCharm(ch, curl, u, digest) if err != nil { return nil, fmt.Errorf("cannot add charm: %v", err) } return sch, nil }
// AddCharm adds the ch charm with curl to the state. bundleUrl must be // set to a URL where the bundle for ch may be downloaded from. // On success the newly added charm state is returned. func (st *State) AddCharm(ch charm.Charm, curl *charm.URL, bundleURL *url.URL, bundleSha256 string) (stch *Charm, err error) { cdoc := &charmDoc{ URL: curl, Meta: ch.Meta(), Config: ch.Config(), BundleURL: bundleURL, BundleSha256: bundleSha256, } err = st.charms.Insert(cdoc) if err != nil { return nil, fmt.Errorf("cannot add charm %q: %v", curl, err) } return newCharm(st, cdoc) }
// ImplementedBy returns whether the endpoint is implemented by the supplied charm. func (ep Endpoint) ImplementedBy(ch charm.Charm) bool { if ep.IsImplicit() { return true } var m map[string]charm.Relation switch ep.Role { case charm.RoleProvider: m = ch.Meta().Provides case charm.RoleRequirer: m = ch.Meta().Requires case charm.RolePeer: m = ch.Meta().Peers default: panic(fmt.Errorf("unknown relation role %q", ep.Role)) } rel, found := m[ep.Name] if !found { return false } if rel.Interface == ep.Interface { switch ep.Scope { case charm.ScopeGlobal: return rel.Scope != charm.ScopeContainer case charm.ScopeContainer: return true default: panic(fmt.Errorf("unknown relation scope %q", ep.Scope)) } } return false }
func checkDummy(c *C, f charm.Charm, path string) { c.Assert(f.Revision(), Equals, 1) c.Assert(f.Meta().Name, Equals, "dummy") c.Assert(f.Config().Options["title"].Default, Equals, "My Title") switch f := f.(type) { case *charm.Bundle: c.Assert(f.Path, Equals, path) case *charm.Dir: c.Assert(f.Path, Equals, path) } }