Example #1
0
func (s *URLSuite) TestInferURLNoDefaultSeries(c *gc.C) {
	for _, t := range inferNoDefaultSeriesTests {
		inferred, err := charm.InferURL(t.vague, "")
		if t.exact == "" {
			c.Assert(err, gc.ErrorMatches, fmt.Sprintf("cannot infer charm URL for %q: no series provided", t.vague))
		} else {
			parsed, err := charm.ParseURL(t.exact)
			c.Assert(err, gc.IsNil)
			c.Assert(inferred, gc.DeepEquals, parsed, gc.Commentf(`InferURL(%q, "")`, t.vague))
		}
	}
}
Example #2
0
func (s *CharmSuite) TestInferRepository(c *gc.C) {
	for i, t := range inferRepoTests {
		c.Logf("test %d", i)
		curl, err := charm.InferURL(t.url, "precise")
		c.Assert(err, gc.IsNil)
		repo, err := charm.InferRepository(curl.Reference, "/some/path")
		c.Assert(err, gc.IsNil)
		switch repo := repo.(type) {
		case *charm.LocalRepository:
			c.Assert(repo.Path, gc.Equals, t.path)
		default:
			c.Assert(repo, gc.Equals, charm.Store)
		}
	}
	curl, err := charm.InferURL("local:whatever", "precise")
	c.Assert(err, gc.IsNil)
	_, err = charm.InferRepository(curl.Reference, "")
	c.Assert(err, gc.ErrorMatches, "path to local repository not specified")
	curl.Schema = "foo"
	_, err = charm.InferRepository(curl.Reference, "")
	c.Assert(err, gc.ErrorMatches, "unknown schema for charm reference.*")
}
Example #3
0
func (s *URLSuite) TestInferURL(c *gc.C) {
	for i, t := range inferTests {
		c.Logf("test %d", i)
		comment := gc.Commentf("InferURL(%q, %q)", t.vague, "defseries")
		inferred, ierr := charm.InferURL(t.vague, "defseries")
		parsed, perr := charm.ParseURL(t.exact)
		if perr == nil {
			c.Check(inferred, gc.DeepEquals, parsed, comment)
			c.Check(ierr, gc.IsNil)
		} else {
			expect := perr.Error()
			if t.vague != t.exact {
				if colIdx := strings.Index(expect, ":"); colIdx > 0 {
					expect = expect[:colIdx]
				}
			}
			c.Check(ierr.Error(), gc.Matches, expect+".*", comment)
		}
	}
	u, err := charm.InferURL("~blah", "defseries")
	c.Assert(u, gc.IsNil)
	c.Assert(err, gc.ErrorMatches, "charm URL without charm name: .*")
}
Example #4
0
func (c *DeployCommand) Init(args []string) error {
	switch len(args) {
	case 2:
		if !names.IsService(args[1]) {
			return fmt.Errorf("invalid service name %q", args[1])
		}
		c.ServiceName = args[1]
		fallthrough
	case 1:
		if _, err := charm.InferURL(args[0], "fake"); err != nil {
			return fmt.Errorf("invalid charm name %q", args[0])
		}
		c.CharmName = args[0]
	case 0:
		return errors.New("no charm specified")
	default:
		return cmd.CheckEmpty(args[2:])
	}
	return c.UnitCommandBase.Init(args)
}
Example #5
0
func (c *PublishCommand) Run(ctx *cmd.Context) (err error) {
	branch := bzr.New(ctx.AbsPath(c.CharmPath))
	if _, err := os.Stat(branch.Join(".bzr")); err != nil {
		return fmt.Errorf("not a charm branch: %s", branch.Location())
	}
	if err := branch.CheckClean(); err != nil {
		return err
	}

	var curl *charm.URL
	if c.URL == "" {
		if err == nil {
			loc, err := branch.PushLocation()
			if err != nil {
				return fmt.Errorf("no charm URL provided and cannot infer from current directory (no push location)")
			}
			curl, err = charm.Store.CharmURL(loc)
			if err != nil {
				return fmt.Errorf("cannot infer charm URL from branch location: %q", loc)
			}
		}
	} else {
		curl, err = charm.InferURL(c.URL, "")
		if err != nil {
			return err
		}
	}

	pushLocation := charm.Store.BranchLocation(curl)
	if c.changePushLocation != nil {
		pushLocation = c.changePushLocation(pushLocation)
	}

	repo, err := charm.InferRepository(curl.Reference, "/not/important")
	if err != nil {
		return err
	}
	if repo != charm.Store {
		return fmt.Errorf("charm URL must reference the juju charm store")
	}

	localDigest, err := branch.RevisionId()
	if err != nil {
		return fmt.Errorf("cannot obtain local digest: %v", err)
	}
	logger.Infof("local digest is %s", localDigest)

	ch, err := charm.ReadDir(branch.Location())
	if err != nil {
		return err
	}
	if ch.Meta().Name != curl.Name {
		return fmt.Errorf("charm name in metadata must match name in URL: %q != %q", ch.Meta().Name, curl.Name)
	}

	oldEvent, err := charm.Store.Event(curl, localDigest)
	if _, ok := err.(*charm.NotFoundError); ok {
		oldEvent, err = charm.Store.Event(curl, "")
		if _, ok := err.(*charm.NotFoundError); ok {
			logger.Infof("charm %s is not yet in the store", curl)
			err = nil
		}
	}
	if err != nil {
		return fmt.Errorf("cannot obtain event details from the store: %s", err)
	}

	if oldEvent != nil && oldEvent.Digest == localDigest {
		return handleEvent(ctx, curl, oldEvent)
	}

	logger.Infof("sending charm to the charm store...")

	err = branch.Push(&bzr.PushAttr{Location: pushLocation, Remember: true})
	if err != nil {
		return err
	}
	logger.Infof("charm sent; waiting for it to be published...")
	for {
		time.Sleep(c.pollDelay)
		newEvent, err := charm.Store.Event(curl, "")
		if _, ok := err.(*charm.NotFoundError); ok {
			continue
		}
		if err != nil {
			return fmt.Errorf("cannot obtain event details from the store: %s", err)
		}
		if oldEvent != nil && oldEvent.Digest == newEvent.Digest {
			continue
		}
		if newEvent.Digest != localDigest {
			// TODO Check if the published digest is in the local history.
			return fmt.Errorf("charm changed but not to local charm digest; publishing race?")
		}
		return handleEvent(ctx, curl, newEvent)
	}
}