Example #1
0
func (s *LocalRepoSuite) TestMultipleVersions(c *gc.C) {
	charmURL := charm.MustParseURL("local:quantal/upgrade")
	s.addDir("upgrade1")
	rev, err := charm.Latest(s.repo, charmURL)
	c.Assert(err, gc.IsNil)
	c.Assert(rev, gc.Equals, 1)
	ch, err := s.repo.Get(charmURL)
	c.Assert(err, gc.IsNil)
	c.Assert(ch.Revision(), gc.Equals, 1)

	s.addDir("upgrade2")
	rev, err = charm.Latest(s.repo, charmURL)
	c.Assert(err, gc.IsNil)
	c.Assert(rev, gc.Equals, 2)
	ch, err = s.repo.Get(charmURL)
	c.Assert(err, gc.IsNil)
	c.Assert(ch.Revision(), gc.Equals, 2)

	revCharmURL := charmURL.WithRevision(1)
	rev, err = charm.Latest(s.repo, revCharmURL)
	c.Assert(err, gc.IsNil)
	c.Assert(rev, gc.Equals, 2)
	ch, err = s.repo.Get(revCharmURL)
	c.Assert(err, gc.IsNil)
	c.Assert(ch.Revision(), gc.Equals, 1)

	badRevCharmURL := charmURL.WithRevision(33)
	rev, err = charm.Latest(s.repo, badRevCharmURL)
	c.Assert(err, gc.IsNil)
	c.Assert(rev, gc.Equals, 2)
	_, err = s.repo.Get(badRevCharmURL)
	s.checkNotFoundErr(c, err, badRevCharmURL)
}
Example #2
0
func (s *LocalRepoSuite) TestMissingRepo(c *gc.C) {
	c.Assert(os.RemoveAll(s.repo.Path), gc.IsNil)
	_, err := charm.Latest(s.repo, charm.MustParseURL("local:quantal/zebra"))
	c.Assert(err, gc.ErrorMatches, `no repository found at ".*"`)
	_, err = s.repo.Get(charm.MustParseURL("local:quantal/zebra"))
	c.Assert(err, gc.ErrorMatches, `no repository found at ".*"`)
	c.Assert(ioutil.WriteFile(s.repo.Path, nil, 0666), gc.IsNil)
	_, err = charm.Latest(s.repo, charm.MustParseURL("local:quantal/zebra"))
	c.Assert(err, gc.ErrorMatches, `no repository found at ".*"`)
	_, err = s.repo.Get(charm.MustParseURL("local:quantal/zebra"))
	c.Assert(err, gc.ErrorMatches, `no repository found at ".*"`)
}
Example #3
0
// PutCharm uploads the given charm to provider storage, and adds a
// state.Charm to the state.  The charm is not uploaded if a charm with
// the same URL already exists in the state.
// If bumpRevision is true, the charm must be a local directory,
// and the revision number will be incremented before pushing.
func (conn *Conn) PutCharm(curl *charm.URL, repo charm.Repository, bumpRevision bool) (*state.Charm, error) {
	if curl.Revision == -1 {
		rev, err := charm.Latest(repo, curl)
		if err != nil {
			return nil, fmt.Errorf("cannot get latest charm revision: %v", err)
		}
		curl = curl.WithRevision(rev)
	}
	ch, err := repo.Get(curl)
	if err != nil {
		return nil, fmt.Errorf("cannot get charm: %v", err)
	}
	if bumpRevision {
		chd, ok := ch.(*charm.Dir)
		if !ok {
			return nil, fmt.Errorf("cannot increment revision of charm %q: not a directory", curl)
		}
		if err = chd.SetDiskRevision(chd.Revision() + 1); err != nil {
			return nil, fmt.Errorf("cannot increment revision of charm %q: %v", curl, err)
		}
		curl = curl.WithRevision(chd.Revision())
	}
	if sch, err := conn.State.Charm(curl); err == nil {
		return sch, nil
	}
	return conn.addCharm(curl, ch)
}
Example #4
0
// addCharmViaAPI calls the appropriate client API calls to add the
// given charm URL to state. Also displays the charm URL of the added
// charm on stdout.
func addCharmViaAPI(client *api.Client, ctx *cmd.Context, curl *charm.URL, repo charm.Repository) (*charm.URL, error) {
	if curl.Revision < 0 {
		latest, err := charm.Latest(repo, curl)
		if err != nil {
			return nil, err
		}
		curl = curl.WithRevision(latest)
	}
	switch curl.Schema {
	case "local":
		ch, err := repo.Get(curl)
		if err != nil {
			return nil, err
		}
		stateCurl, err := client.AddLocalCharm(curl, ch)
		if err != nil {
			return nil, err
		}
		curl = stateCurl
	case "cs":
		err := client.AddCharm(curl)
		if err != nil {
			return nil, err
		}
	default:
		return nil, fmt.Errorf("unsupported charm URL schema: %q", curl.Schema)
	}
	ctx.Infof("Added charm %q to the environment.", curl)
	return curl, nil
}
Example #5
0
func (s *StoreSuite) TestError(c *gc.C) {
	charmURL := charm.MustParseURL("cs:series/borken")
	expect := `charm info errors for "cs:series/borken": badness`
	_, err := charm.Latest(s.store, charmURL)
	c.Assert(err, gc.ErrorMatches, expect)
	_, err = s.store.Get(charmURL)
	c.Assert(err, gc.ErrorMatches, expect)
}
Example #6
0
func (s *StoreSuite) TestMissing(c *gc.C) {
	charmURL := charm.MustParseURL("cs:series/missing")
	expect := `charm not found: cs:series/missing`
	_, err := charm.Latest(s.store, charmURL)
	c.Assert(err, gc.ErrorMatches, expect)
	_, err = s.store.Get(charmURL)
	c.Assert(err, gc.ErrorMatches, expect)
}
Example #7
0
func (s *LocalRepoSuite) TestBundle(c *gc.C) {
	charmURL := charm.MustParseURL("local:quantal/dummy")
	s.addBundle("dummy")

	rev, err := charm.Latest(s.repo, charmURL)
	c.Assert(err, gc.IsNil)
	c.Assert(rev, gc.Equals, 1)
	ch, err := s.repo.Get(charmURL)
	c.Assert(err, gc.IsNil)
	c.Assert(ch.Revision(), gc.Equals, 1)
}
Example #8
0
func (s *StoreSuite) TestWarning(c *gc.C) {
	charmURL := charm.MustParseURL("cs:series/unwise")
	expect := `.* WARNING juju.charm charm store reports for "cs:series/unwise": foolishness` + "\n"
	r, err := charm.Latest(s.store, charmURL)
	c.Assert(r, gc.Equals, 23)
	c.Assert(err, gc.IsNil)
	c.Assert(c.GetTestLog(), gc.Matches, expect)
	ch, err := s.store.Get(charmURL)
	c.Assert(ch, gc.NotNil)
	c.Assert(err, gc.IsNil)
	c.Assert(c.GetTestLog(), gc.Matches, expect+expect)
}
Example #9
0
func (s *LocalRepoSuite) TestMissingCharm(c *gc.C) {
	for i, str := range []string{
		"local:quantal/zebra", "local:badseries/zebra",
	} {
		c.Logf("test %d: %s", i, str)
		charmURL := charm.MustParseURL(str)
		_, err := charm.Latest(s.repo, charmURL)
		s.checkNotFoundErr(c, err, charmURL)
		_, err = s.repo.Get(charmURL)
		s.checkNotFoundErr(c, err, charmURL)
	}
}
Example #10
0
func (s *LocalRepoSuite) TestIgnoresUnpromisingNames(c *gc.C) {
	err := ioutil.WriteFile(filepath.Join(s.seriesPath, "blah.notacharm"), nil, 0666)
	c.Assert(err, gc.IsNil)
	err = os.Mkdir(filepath.Join(s.seriesPath, ".blah"), 0666)
	c.Assert(err, gc.IsNil)
	renameSibling(c, s.addDir("dummy"), ".dummy")
	renameSibling(c, s.addBundle("dummy"), "dummy.notacharm")
	charmURL := charm.MustParseURL("local:quantal/dummy")

	_, err = s.repo.Get(charmURL)
	s.checkNotFoundErr(c, err, charmURL)
	_, err = charm.Latest(s.repo, charmURL)
	s.checkNotFoundErr(c, err, charmURL)
	c.Assert(c.GetTestLog(), gc.Equals, "")
}
Example #11
0
// Run connects to the specified environment and starts the charm
// upgrade process.
func (c *UpgradeCharmCommand) Run(ctx *cmd.Context) error {
	client, err := juju.NewAPIClientFromName(c.EnvName)
	if err != nil {
		return err
	}
	defer client.Close()
	oldURL, err := client.ServiceGetCharmURL(c.ServiceName)
	if err != nil {
		return err
	}

	attrs, err := client.EnvironmentGet()
	if err != nil {
		return err
	}
	conf, err := config.New(config.NoDefaults, attrs)
	if err != nil {
		return err
	}

	var newURL *charm.URL
	if c.SwitchURL != "" {
		newURL, err = resolveCharmURL(c.SwitchURL, client, conf)
		if err != nil {
			return err
		}
	} else {
		// No new URL specified, but revision might have been.
		newURL = oldURL.WithRevision(c.Revision)
	}

	repo, err := charm.InferRepository(newURL.Reference, ctx.AbsPath(c.RepoPath))
	if err != nil {
		return err
	}
	repo = config.SpecializeCharmRepo(repo, conf)

	// If no explicit revision was set with either SwitchURL
	// or Revision flags, discover the latest.
	explicitRevision := true
	if newURL.Revision == -1 {
		explicitRevision = false
		latest, err := charm.Latest(repo, newURL)
		if err != nil {
			return err
		}
		newURL = newURL.WithRevision(latest)
	}
	if *newURL == *oldURL {
		if explicitRevision {
			return fmt.Errorf("already running specified charm %q", newURL)
		} else if newURL.Schema == "cs" {
			// No point in trying to upgrade a charm store charm when
			// we just determined that's the latest revision
			// available.
			return fmt.Errorf("already running latest charm %q", newURL)
		}
	}

	addedURL, err := addCharmViaAPI(client, ctx, newURL, repo)
	if err != nil {
		return err
	}

	return client.ServiceSetCharm(c.ServiceName, addedURL.String(), c.Force)
}