Example #1
0
// FindAvailableTools returns a tools.List containing all tools with a given
// major version number available in the environment.
// If *any* tools are present in private storage, *only* tools from private
// storage are available.
// If *no* tools are present in private storage, *only* tools from public
// storage are available.
// If no *available* tools have the supplied major version number, the function
// returns a *NotFoundError.
func FindAvailableTools(environ Environ, majorVersion int) (list tools.List, err error) {
	log.Infof("environs: reading tools with major version %d", majorVersion)
	defer convertToolsError(&err)
	list, err = tools.ReadList(environ.Storage(), majorVersion)
	if err == tools.ErrNoTools {
		log.Infof("environs: falling back to public bucket")
		list, err = tools.ReadList(environ.PublicStorage(), majorVersion)
	}
	return list, err
}
Example #2
0
func (s *StorageSuite) TestReadList(c *gc.C) {
	store := s.env.Storage()
	v001 := version.MustParseBinary("0.0.1-precise-amd64")
	t001 := envtesting.UploadFakeToolsVersion(c, store, v001)
	v100 := version.MustParseBinary("1.0.0-precise-amd64")
	t100 := envtesting.UploadFakeToolsVersion(c, store, v100)
	v101 := version.MustParseBinary("1.0.1-precise-amd64")
	t101 := envtesting.UploadFakeToolsVersion(c, store, v101)

	for i, t := range []struct {
		majorVersion int
		list         tools.List
	}{{
		0, tools.List{t001},
	}, {
		1, tools.List{t100, t101},
	}, {
		2, nil,
	}} {
		c.Logf("test %d", i)
		list, err := tools.ReadList(store, t.majorVersion)
		if t.list != nil {
			c.Assert(err, gc.IsNil)
			c.Assert(list, gc.DeepEquals, t.list)
		} else {
			c.Assert(err, gc.Equals, tools.ErrNoMatches)
		}
	}
}
Example #3
0
func assertEmpty(c *gc.C, storage environs.StorageReader) {
	list, err := tools.ReadList(storage, 1)
	if len(list) > 0 {
		c.Logf("got unexpected tools: %s", list)
	}
	c.Assert(err, gc.Equals, tools.ErrNoTools)
}
Example #4
0
func (s *StorageSuite) TestUploadFakeSeries(c *gc.C) {
	t, err := tools.Upload(s.env.Storage(), nil, "sham", "fake")
	c.Assert(err, gc.IsNil)
	c.Assert(t.Version, gc.Equals, version.Current)
	expectRaw := downloadToolsRaw(c, t)

	list, err := tools.ReadList(s.env.Storage(), version.Current.Major)
	c.Assert(err, gc.IsNil)
	c.Assert(list, gc.HasLen, 3)
	expectSeries := []string{"fake", "sham", version.CurrentSeries()}
	sort.Strings(expectSeries)
	c.Assert(list.Series(), gc.DeepEquals, expectSeries)
	for _, t := range list {
		c.Logf("checking %s", t.URL)
		c.Assert(t.Version.Number, gc.Equals, version.CurrentNumber())
		actualRaw := downloadToolsRaw(c, t)
		c.Assert(string(actualRaw), gc.Equals, string(expectRaw))
	}
}
Example #5
0
func (s *StorageSuite) TestReadListEmpty(c *gc.C) {
	store := s.env.Storage()
	_, err := tools.ReadList(store, 2)
	c.Assert(err, gc.Equals, tools.ErrNoTools)
}
Example #6
0
// SyncTools copies the Juju tools tarball from the official bucket
// or a specified source directory into the user's environment.
func SyncTools(ctx *SyncContext) error {
	var err error
	ctx.sourceStorage, err = selectSourceStorage(ctx)
	if err != nil {
		return fmt.Errorf("unable to select source: %v", err)
	}
	targetEnv, err := environs.NewFromName(ctx.EnvName)
	if err != nil {
		return fmt.Errorf("unable to read %q from environment", ctx.EnvName)
	}

	logger.Infof("listing available tools")
	majorVersion := version.Current.Major
	sourceTools, err := tools.ReadList(ctx.sourceStorage, majorVersion)
	if err != nil {
		return err
	}
	if !ctx.Dev {
		// No development versions, only released ones.
		filter := tools.Filter{Released: true}
		if sourceTools, err = sourceTools.Match(filter); err != nil {
			return err
		}
	}
	logger.Infof("found %d tools", len(sourceTools))
	if !ctx.AllVersions {
		var latest version.Number
		latest, sourceTools = sourceTools.Newest()
		logger.Infof("found %d recent tools (version %s)", len(sourceTools), latest)
	}
	for _, tool := range sourceTools {
		logger.Debugf("found source tool: %s", tool)
	}

	logger.Infof("listing target bucket")
	ctx.targetStorage = targetEnv.Storage()
	if ctx.PublicBucket {
		switch _, err := tools.ReadList(ctx.targetStorage, majorVersion); err {
		case tools.ErrNoTools:
		case nil, tools.ErrNoMatches:
			return fmt.Errorf("private tools present: public tools would be ignored")
		default:
			return err
		}
		var ok bool
		if ctx.targetStorage, ok = targetEnv.PublicStorage().(environs.Storage); !ok {
			return fmt.Errorf("cannot write to public storage")
		}
	}
	targetTools, err := tools.ReadList(ctx.targetStorage, majorVersion)
	switch err {
	case nil, tools.ErrNoMatches, tools.ErrNoTools:
	default:
		return err
	}
	for _, tool := range targetTools {
		logger.Debugf("found target tool: %s", tool)
	}

	missing := sourceTools.Exclude(targetTools)
	logger.Infof("found %d tools in target; %d tools to be copied", len(targetTools), len(missing))
	err = copyTools(missing, ctx)
	if err != nil {
		return err
	}
	logger.Infof("copied %d tools", len(missing))
	return nil
}
Example #7
0
func (c *SyncToolsCommand) Run(ctx *cmd.Context) error {
	sourceStorage, err := selectSourceStorage(c.source)
	if err != nil {
		log.Errorf("unable to select source: %v", err)
		return err
	}
	targetEnv, err := environs.NewFromName(c.EnvName)
	if err != nil {
		log.Errorf("unable to read %q from environment", c.EnvName)
		return err
	}

	fmt.Fprintf(ctx.Stderr, "listing the source bucket\n")
	majorVersion := version.Current.Major
	sourceTools, err := tools.ReadList(sourceStorage, majorVersion)
	if err != nil {
		return err
	}
	if !c.dev {
		filter := tools.Filter{Released: true}
		if sourceTools, err = sourceTools.Match(filter); err != nil {
			return err
		}
	}
	fmt.Fprintf(ctx.Stderr, "found %d tools\n", len(sourceTools))
	if !c.allVersions {
		var latest version.Number
		latest, sourceTools = sourceTools.Newest()
		fmt.Fprintf(ctx.Stderr, "found %d recent tools (version %s)\n", len(sourceTools), latest)
	}
	for _, tool := range sourceTools {
		log.Debugf("found source tool: %s", tool)
	}

	fmt.Fprintf(ctx.Stderr, "listing target bucket\n")
	targetStorage := targetEnv.Storage()
	if c.publicBucket {
		switch _, err := tools.ReadList(targetStorage, majorVersion); err {
		case tools.ErrNoTools:
		case nil, tools.ErrNoMatches:
			return fmt.Errorf("private tools present: public tools would be ignored")
		default:
			return err
		}
		var ok bool
		if targetStorage, ok = targetEnv.PublicStorage().(environs.Storage); !ok {
			return fmt.Errorf("cannot write to public storage")
		}
	}
	targetTools, err := tools.ReadList(targetStorage, majorVersion)
	switch err {
	case nil, tools.ErrNoMatches, tools.ErrNoTools:
	default:
		return err
	}
	for _, tool := range targetTools {
		log.Debugf("found target tool: %s", tool)
	}

	missing := sourceTools.Exclude(targetTools)
	fmt.Fprintf(ctx.Stdout, "found %d tools in target; %d tools to be copied\n",
		len(targetTools), len(missing))
	err = copyTools(missing, sourceStorage, targetStorage, c.dryRun, ctx)
	if err != nil {
		return err
	}
	fmt.Fprintf(ctx.Stderr, "copied %d tools\n", len(missing))
	return nil
}