func (s *BundleSuite) TestBundleRevisionFile(c *C) { charmDir := testing.Charms.ClonedDirPath(c.MkDir(), "dummy") revPath := filepath.Join(charmDir, "revision") // Missing revision file err := os.Remove(revPath) c.Assert(err, IsNil) bundle, err := charm.ReadBundle(extBundleDir(c, charmDir)) c.Assert(err, IsNil) c.Assert(bundle.Revision(), Equals, 0) // Missing revision file with old revision in metadata file, err := os.OpenFile(filepath.Join(charmDir, "metadata.yaml"), os.O_WRONLY|os.O_APPEND, 0) c.Assert(err, IsNil) _, err = file.Write([]byte("\nrevision: 1234\n")) c.Assert(err, IsNil) bundle, err = charm.ReadBundle(extBundleDir(c, charmDir)) c.Assert(err, IsNil) c.Assert(bundle.Revision(), Equals, 1234) // Revision file with bad content err = ioutil.WriteFile(revPath, []byte("garbage"), 0666) c.Assert(err, IsNil) bundle, err = charm.ReadBundle(extBundleDir(c, charmDir)) c.Assert(err, ErrorMatches, "invalid revision file") c.Assert(bundle, IsNil) }
func (s *BundleSuite) TestExpandToWithBadLink(c *C) { charmDir := testing.Charms.ClonedDirPath(c.MkDir(), "dummy") badLink := filepath.Join(charmDir, "hooks", "badlink") // Symlink targeting a path outside of the charm. err := os.Symlink("../../target", badLink) c.Assert(err, IsNil) bundle, err := charm.ReadBundle(extBundleDir(c, charmDir)) c.Assert(err, IsNil) path := filepath.Join(c.MkDir(), "charm") err = bundle.ExpandTo(path) c.Assert(err, ErrorMatches, `symlink "hooks/badlink" links out of charm: "../../target"`) // Symlink targeting an absolute path. os.Remove(badLink) err = os.Symlink("/target", badLink) c.Assert(err, IsNil) bundle, err = charm.ReadBundle(extBundleDir(c, charmDir)) c.Assert(err, IsNil) path = filepath.Join(c.MkDir(), "charm") err = bundle.ExpandTo(path) c.Assert(err, ErrorMatches, `symlink "hooks/badlink" is absolute: "/target"`) }
func (s *BundleSuite) TestReadBundleWithoutConfig(c *C) { path := testing.Charms.BundlePath(c.MkDir(), "varnish") bundle, err := charm.ReadBundle(path) c.Assert(err, IsNil) // A lacking config.yaml file still causes a proper // Config value to be returned. c.Assert(bundle.Config().Options, HasLen, 0) }
// Read returns a charm bundle from the directory. If no bundle exists yet, // one will be downloaded and validated and copied into the directory before // being returned. Downloads will be aborted if a value is received on abort. func (d *BundlesDir) Read(sch *state.Charm, abort <-chan struct{}) (*charm.Bundle, error) { path := d.bundlePath(sch) if _, err := os.Stat(path); err != nil { if !os.IsNotExist(err) { return nil, err } else if err = d.download(sch, abort); err != nil { return nil, err } } return charm.ReadBundle(path) }
func (s *BundleSuite) TestExpandTo(c *C) { bundle, err := charm.ReadBundle(s.bundlePath) c.Assert(err, IsNil) path := filepath.Join(c.MkDir(), "charm") err = bundle.ExpandTo(path) c.Assert(err, IsNil) dir, err := charm.ReadDir(path) c.Assert(err, IsNil) checkDummy(c, dir, path) }
func (s *BundlesDirSuite) AddCharm(c *C) (*state.Charm, []byte) { curl := corecharm.MustParseURL("cs:series/dummy-1") surl, err := url.Parse(s.URL("/some/charm.bundle")) c.Assert(err, IsNil) bunpath := coretesting.Charms.BundlePath(c.MkDir(), "dummy") bun, err := corecharm.ReadBundle(bunpath) c.Assert(err, IsNil) bundata, hash := readHash(c, bunpath) sch, err := s.State.AddCharm(bun, curl, surl, hash) c.Assert(err, IsNil) return sch, bundata }
func (s *BundleSuite) TestBundleSetRevision(c *C) { bundle, err := charm.ReadBundle(s.bundlePath) c.Assert(err, IsNil) c.Assert(bundle.Revision(), Equals, 1) bundle.SetRevision(42) c.Assert(bundle.Revision(), Equals, 42) path := filepath.Join(c.MkDir(), "charm") err = bundle.ExpandTo(path) c.Assert(err, IsNil) dir, err := charm.ReadDir(path) c.Assert(err, IsNil) c.Assert(dir.Revision(), Equals, 42) }
func (s *DeployerSuite) bundle(c *C, customize func(path string)) *corecharm.Bundle { base := c.MkDir() dirpath := testing.Charms.ClonedDirPath(base, "dummy") customize(dirpath) dir, err := corecharm.ReadDir(dirpath) c.Assert(err, IsNil) bunpath := filepath.Join(base, "bundle") file, err := os.Create(bunpath) c.Assert(err, IsNil) defer file.Close() err = dir.BundleTo(file) c.Assert(err, IsNil) bun, err := corecharm.ReadBundle(bunpath) c.Assert(err, IsNil) return bun }
func (s *BundleSuite) TestExpandToSetsHooksExecutable(c *C) { charmDir := testing.Charms.ClonedDir(c.MkDir(), "all-hooks") // Bundle manually, so we can check ExpandTo(), unaffected // by BundleTo()'s behavior bundlePath := filepath.Join(c.MkDir(), "bundle.charm") s.prepareBundle(c, charmDir, bundlePath) bundle, err := charm.ReadBundle(bundlePath) c.Assert(err, IsNil) path := filepath.Join(c.MkDir(), "charm") err = bundle.ExpandTo(path) c.Assert(err, IsNil) _, err = charm.ReadDir(path) c.Assert(err, IsNil) for name := range bundle.Meta().Hooks() { hookName := string(name) info, err := os.Stat(filepath.Join(path, "hooks", hookName)) c.Assert(err, IsNil) perm := info.Mode() & 0777 c.Assert(perm&0100 != 0, Equals, true, Commentf("hook %q is not executable", hookName)) } }
// Bundle returns an actual charm.Bundle created from a new charm bundle file // created from the charm directory named name, in the directory dst. func (r *Repo) Bundle(dst, name string) *charm.Bundle { ch, err := charm.ReadBundle(r.BundlePath(dst, name)) check(err) return ch }
func (s *BundleSuite) TestReadBundle(c *C) { bundle, err := charm.ReadBundle(s.bundlePath) c.Assert(err, IsNil) checkDummy(c, bundle, s.bundlePath) }