Example #1
0
// EnsureToolsAvailability verifies the tools are available. If no tools are
// found, it will automatically synchronize them.
func EnsureToolsAvailability(ctx environs.BootstrapContext, env environs.Environ, series string, toolsArch *string) (coretools.List, error) {
	cfg := env.Config()
	var vers *version.Number
	if agentVersion, ok := cfg.AgentVersion(); ok {
		vers = &agentVersion
	}

	logger.Debugf(
		"looking for bootstrap tools: series=%q, arch=%v, version=%v",
		series, toolsArch, vers,
	)
	params := envtools.BootstrapToolsParams{
		Version: vers,
		Arch:    toolsArch,
		Series:  series,
		// If vers.Build>0, the tools may have been uploaded in this session.
		// Allow retries, so we wait until the storage has caught up.
		AllowRetry: vers != nil && vers.Build > 0,
	}
	toolsList, err := envtools.FindBootstrapTools(env, params)
	if err == nil {
		return toolsList, nil
	} else if !errors.IsNotFound(err) {
		return nil, err
	}

	// Only automatically upload tools for dev versions.
	if !version.Current.IsDev() {
		return nil, fmt.Errorf("cannot upload bootstrap tools: %v", noToolsNoUploadMessage)
	}

	// No tools available so our only hope is to build locally and upload.
	logger.Warningf("no prepackaged tools available")
	uploadSeries := SeriesToUpload(cfg, nil)
	if series != "" {
		uploadSeries = append(uploadSeries, series)
	}
	if err := UploadTools(ctx, env, toolsArch, false, uploadSeries...); err != nil {
		logger.Errorf("%s", noToolsMessage)
		return nil, fmt.Errorf("cannot upload bootstrap tools: %v", err)
	}
	// TODO(axw) have uploadTools return the list of tools in the target, and use that.
	params.AllowRetry = true
	if toolsList, err = envtools.FindBootstrapTools(env, params); err != nil {
		return nil, fmt.Errorf("cannot find bootstrap tools: %v", err)
	}
	return toolsList, nil
}
Example #2
0
func (s *bootstrapSuite) getArgs(c *gc.C) manual.BootstrapArgs {
	hostname, err := os.Hostname()
	c.Assert(err, gc.IsNil)
	toolsList, err := tools.FindBootstrapTools(s.Conn.Environ, tools.BootstrapToolsParams{})
	c.Assert(err, gc.IsNil)
	arch := "amd64"
	return manual.BootstrapArgs{
		Host:          hostname,
		DataDir:       "/var/lib/juju",
		Environ:       s.env,
		PossibleTools: toolsList,
		Series:        "precise",
		HardwareCharacteristics: &instance.HardwareCharacteristics{
			Arch: &arch,
		},
		Context: coretesting.Context(c),
	}
}
Example #3
0
func (s *bootstrapSuite) assertUploadTools(c *gc.C, vers version.Binary, forceVersion bool,
	extraConfig map[string]interface{}, errMessage string) {

	s.PatchValue(&version.Current, vers)
	// If we allow released tools to be uploaded, the build number is incremented so in that case
	// we need to ensure the environment is set up to allow dev tools to be used.
	env := newEnviron("foo", useDefaultKeys, extraConfig)
	s.setDummyStorage(c, env)
	envtesting.RemoveFakeTools(c, env.Storage())

	// At this point, as a result of setDummyStorage, env has tools for amd64 uploaded.
	// Set version.Current to be arm64 to simulate a different CLI version.
	cliVersion := version.Current
	cliVersion.Arch = "arm64"
	version.Current = cliVersion
	s.PatchValue(&sync.BuildToolsTarball, s.getMockBuildTools(c))
	// Host runs arm64, environment supports arm64.
	s.PatchValue(&arch.HostArch, func() string {
		return "arm64"
	})
	arch := "arm64"
	err := bootstrap.UploadTools(coretesting.Context(c), env, &arch, forceVersion, "precise")
	if errMessage != "" {
		c.Assert(err, gc.NotNil)
		stripped := strings.Replace(err.Error(), "\n", "", -1)
		c.Assert(stripped, gc.Matches, errMessage)
		return
	}
	c.Assert(err, gc.IsNil)
	params := envtools.BootstrapToolsParams{
		Arch:   &arch,
		Series: version.Current.Series,
	}
	agentTools, err := envtools.FindBootstrapTools(env, params)
	c.Assert(err, gc.IsNil)
	c.Assert(agentTools, gc.HasLen, 1)
	expectedVers := vers
	expectedVers.Number.Build++
	expectedVers.Series = version.Current.Series
	c.Assert(agentTools[0].Version, gc.DeepEquals, expectedVers)
}
Example #4
0
func (s *SimpleStreamsToolsSuite) TestFindBootstrapTools(c *gc.C) {
	// Remove the default tools URL from the search path, just look in cloud storage.
	s.PatchValue(&envtools.DefaultBaseURL, "")
	for i, test := range envtesting.BootstrapToolsTests {
		c.Logf("\ntest %d: %s", i, test.Info)
		attrs := map[string]interface{}{
			"development": test.Development,
		}
		var agentVersion *version.Number
		if test.AgentVersion != version.Zero {
			attrs["agent-version"] = test.AgentVersion.String()
			agentVersion = &test.AgentVersion
		}
		s.reset(c, attrs)
		version.Current = test.CliVersion
		available := s.uploadCustom(c, test.Available...)

		params := envtools.BootstrapToolsParams{
			Version: agentVersion,
			Series:  test.DefaultSeries,
			Arch:    &test.Arch,
		}
		actual, err := envtools.FindBootstrapTools(s.env, params)
		if test.Err != "" {
			if len(actual) > 0 {
				c.Logf(actual.String())
			}
			c.Check(err, jc.Satisfies, errors.IsNotFound)
			continue
		}
		expect := map[version.Binary]string{}
		for _, expected := range test.Expect {
			expect[expected] = available[expected]
		}
		c.Check(actual.URLs(), gc.DeepEquals, expect)
	}
}