Beispiel #1
0
func (s *BundleSuite) TestBundleRevisionFile(c *gc.C) {
	charmDir := testing.Charms.ClonedDirPath(c.MkDir(), "dummy")
	revPath := filepath.Join(charmDir, "revision")

	// Missing revision file
	err := os.Remove(revPath)
	c.Assert(err, gc.IsNil)

	bundle := extBundleDir(c, charmDir)
	c.Assert(bundle.Revision(), gc.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, gc.IsNil)
	_, err = file.Write([]byte("\nrevision: 1234\n"))
	c.Assert(err, gc.IsNil)

	bundle = extBundleDir(c, charmDir)
	c.Assert(bundle.Revision(), gc.Equals, 1234)

	// Revision file with bad content
	err = ioutil.WriteFile(revPath, []byte("garbage"), 0666)
	c.Assert(err, gc.IsNil)

	path := extBundleDirPath(c, charmDir)
	bundle, err = charm.ReadBundle(path)
	c.Assert(err, gc.ErrorMatches, "invalid revision file")
	c.Assert(bundle, gc.IsNil)
}
Beispiel #2
0
func (s *BundleSuite) TestManifest(c *gc.C) {
	bundle, err := charm.ReadBundle(s.bundlePath)
	c.Assert(err, gc.IsNil)
	manifest, err := bundle.Manifest()
	c.Assert(err, gc.IsNil)
	c.Assert(manifest, jc.DeepEquals, set.NewStrings(dummyManifest...))
}
Beispiel #3
0
func (s *BundleSuite) TestReadBundleWithoutConfig(c *gc.C) {
	path := testing.Charms.BundlePath(c.MkDir(), "varnish")
	bundle, err := charm.ReadBundle(path)
	c.Assert(err, gc.IsNil)

	// A lacking config.yaml file still causes a proper
	// Config value to be returned.
	c.Assert(bundle.Config().Options, gc.HasLen, 0)
}
Beispiel #4
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(info BundleInfo, abort <-chan struct{}) (Bundle, error) {
	path := d.bundlePath(info)
	if _, err := os.Stat(path); err != nil {
		if !os.IsNotExist(err) {
			return nil, err
		} else if err = d.download(info, abort); err != nil {
			return nil, err
		}
	}
	return charm.ReadBundle(path)
}
Beispiel #5
0
// sendBundleContent uses the given bundleContentSenderFunc to send a response
// related to the charm archive located in the given archivePath.
func sendBundleContent(w http.ResponseWriter, r *http.Request, archivePath string, sender bundleContentSenderFunc) {
	bundle, err := charm.ReadBundle(archivePath)
	if err != nil {
		http.Error(
			w, fmt.Sprintf("unable to read archive in %q: %v", archivePath, err),
			http.StatusInternalServerError)
		return
	}
	// The bundleContentSenderFunc will set up and send an appropriate response.
	sender(w, r, bundle)
}
Beispiel #6
0
func (s *BundleSuite) TestExpandTo(c *gc.C) {
	bundle, err := charm.ReadBundle(s.bundlePath)
	c.Assert(err, gc.IsNil)

	path := filepath.Join(c.MkDir(), "charm")
	err = bundle.ExpandTo(path)
	c.Assert(err, gc.IsNil)

	dir, err := charm.ReadDir(path)
	c.Assert(err, gc.IsNil)
	checkDummy(c, dir, path)
}
Beispiel #7
0
// processPost handles a charm upload POST request after authentication.
func (h *charmsHandler) processPost(r *http.Request) (*charm.URL, error) {
	query := r.URL.Query()
	series := query.Get("series")
	if series == "" {
		return nil, fmt.Errorf("expected series=URL argument")
	}
	// Make sure the content type is zip.
	contentType := r.Header.Get("Content-Type")
	if contentType != "application/zip" {
		return nil, fmt.Errorf("expected Content-Type: application/zip, got: %v", contentType)
	}
	tempFile, err := ioutil.TempFile("", "charm")
	if err != nil {
		return nil, fmt.Errorf("cannot create temp file: %v", err)
	}
	defer tempFile.Close()
	defer os.Remove(tempFile.Name())
	if _, err := io.Copy(tempFile, r.Body); err != nil {
		return nil, fmt.Errorf("error processing file upload: %v", err)
	}
	err = h.processUploadedArchive(tempFile.Name())
	if err != nil {
		return nil, err
	}
	archive, err := charm.ReadBundle(tempFile.Name())
	if err != nil {
		return nil, fmt.Errorf("invalid charm archive: %v", err)
	}
	// We got it, now let's reserve a charm URL for it in state.
	archiveURL := &charm.URL{
		Reference: charm.Reference{
			Schema:   "local",
			Name:     archive.Meta().Name,
			Revision: archive.Revision(),
		},
		Series: series,
	}
	preparedURL, err := h.state.PrepareLocalCharmUpload(archiveURL)
	if err != nil {
		return nil, err
	}
	// Now we need to repackage it with the reserved URL, upload it to
	// provider storage and update the state.
	err = h.repackageAndUploadCharm(archive, preparedURL)
	if err != nil {
		return nil, err
	}
	// All done.
	return preparedURL, nil
}
Beispiel #8
0
func (s *BundleSuite) TestManifestNoRevision(c *gc.C) {
	bundle, err := charm.ReadBundle(s.bundlePath)
	c.Assert(err, gc.IsNil)
	dirPath := c.MkDir()
	err = bundle.ExpandTo(dirPath)
	c.Assert(err, gc.IsNil)
	err = os.Remove(filepath.Join(dirPath, "revision"))
	c.Assert(err, gc.IsNil)

	bundle = extBundleDir(c, dirPath)
	manifest, err := bundle.Manifest()
	c.Assert(err, gc.IsNil)
	c.Assert(manifest, gc.DeepEquals, set.NewStrings(dummyManifest...))
}
Beispiel #9
0
func (s *BundleSuite) TestBundleSetRevision(c *gc.C) {
	bundle, err := charm.ReadBundle(s.bundlePath)
	c.Assert(err, gc.IsNil)

	c.Assert(bundle.Revision(), gc.Equals, 1)
	bundle.SetRevision(42)
	c.Assert(bundle.Revision(), gc.Equals, 42)

	path := filepath.Join(c.MkDir(), "charm")
	err = bundle.ExpandTo(path)
	c.Assert(err, gc.IsNil)

	dir, err := charm.ReadDir(path)
	c.Assert(err, gc.IsNil)
	c.Assert(dir.Revision(), gc.Equals, 42)
}
Beispiel #10
0
func (br *bundleReader) AddCustomBundle(c *gc.C, url *corecharm.URL, customize func(path string)) charm.BundleInfo {
	base := c.MkDir()
	dirpath := coretesting.Charms.ClonedDirPath(base, "dummy")
	if customize != nil {
		customize(dirpath)
	}
	dir, err := corecharm.ReadDir(dirpath)
	c.Assert(err, gc.IsNil)
	err = dir.SetDiskRevision(url.Revision)
	c.Assert(err, gc.IsNil)
	bunpath := filepath.Join(base, "bundle")
	file, err := os.Create(bunpath)
	c.Assert(err, gc.IsNil)
	defer file.Close()
	err = dir.BundleTo(file)
	c.Assert(err, gc.IsNil)
	bundle, err := corecharm.ReadBundle(bunpath)
	c.Assert(err, gc.IsNil)
	return br.AddBundle(c, url, bundle)
}
Beispiel #11
0
func (s *BundleSuite) TestExpandToSetsHooksExecutable(c *gc.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, gc.IsNil)

	path := filepath.Join(c.MkDir(), "charm")
	err = bundle.ExpandTo(path)
	c.Assert(err, gc.IsNil)

	_, err = charm.ReadDir(path)
	c.Assert(err, gc.IsNil)

	for name := range bundle.Meta().Hooks() {
		hookName := string(name)
		info, err := os.Stat(filepath.Join(path, "hooks", hookName))
		c.Assert(err, gc.IsNil)
		perm := info.Mode() & 0777
		c.Assert(perm&0100 != 0, gc.Equals, true, gc.Commentf("hook %q is not executable", hookName))
	}
}
Beispiel #12
0
// 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
}
Beispiel #13
0
func (s *BundleSuite) TestReadBundle(c *gc.C) {
	bundle, err := charm.ReadBundle(s.bundlePath)
	c.Assert(err, gc.IsNil)
	checkDummy(c, bundle, s.bundlePath)
}
Beispiel #14
0
func extBundleDir(c *gc.C, dirpath string) *charm.Bundle {
	path := extBundleDirPath(c, dirpath)
	bundle, err := charm.ReadBundle(path)
	c.Assert(err, gc.IsNil)
	return bundle
}