// findCompatibleTools finds tools in the list that have the same major, minor
// and patch level as jujuversion.Current.
//
// Build number is not important to match; uploaded tools will have
// incremented build number, and we want to match them.
328803
func findCompatibleTools(possibleTools coretools.List, version version.Number) (version.Number, coretools.List) {
	var compatibleTools coretools.List
	for _, tools := range possibleTools {
		if isCompatibleVersion(tools.Version.Number, version) {
			compatibleTools = append(compatibleTools, tools)
		}
	}
	return compatibleTools.Newest()
}
581682
func (s *Search) getMatches(iter memdb.ResultIterator, prefix string) ([]string, bool) {
	var matches []string

	for i := 0; i < truncateLimit; i++ {
		raw := iter.Next()
		if raw == nil {
			break
		}

		var id string
		switch t := raw.(type) {
		case *structs.Job:
			id = raw.(*structs.Job).ID
		case *structs.Evaluation:
			id = raw.(*structs.Evaluation).ID
		case *structs.Allocation:
			id = raw.(*structs.Allocation).ID
		case *structs.Node:
			id = raw.(*structs.Node).ID
		case *structs.Deployment:
			id = raw.(*structs.Deployment).ID
		default:
			matchID, ok := getEnterpriseMatch(raw)
			if !ok {
				s.logger.Error("unexpected type for resources context", "type", fmt.Sprintf("%T", t))
				continue
			}

			id = matchID
		}

		if !strings.HasPrefix(id, prefix) {
			continue
		}

		matches = append(matches, id)
	}

	return matches, iter.Next() != nil
}
954717
func (cfg *InstanceConfig) JujuTools() string {
	return agenttools.SharedToolsDir(cfg.DataDir, cfg.AgentVersion())
}
590884
func ValidateToolsMetadata(params *ToolsMetadataLookupParams) ([]string, *simplestreams.ResolveInfo, error) {
	if len(params.Sources) == 0 {
		return nil, nil, fmt.Errorf("required parameter sources not specified")
	}
	if params.Version == "" && params.Major == 0 {
		params.Version = jujuversion.Current.String()
	}
	var toolsConstraint *ToolsConstraint
	if params.Version == "" {
		toolsConstraint = NewGeneralToolsConstraint(params.Major, params.Minor, simplestreams.LookupParams{
			CloudSpec: simplestreams.CloudSpec{
				Region:   params.Region,
				Endpoint: params.Endpoint,
			},
			Stream: params.Stream,
			Series: []string{params.Series},
			Arches: params.Architectures,
		})
	} else {
		versNum, err := version.Parse(params.Version)
		if err != nil {
			return nil, nil, err
		}
		toolsConstraint = NewVersionedToolsConstraint(versNum, simplestreams.LookupParams{
			CloudSpec: simplestreams.CloudSpec{
				Region:   params.Region,
				Endpoint: params.Endpoint,
			},
			Stream: params.Stream,
			Series: []string{params.Series},
			Arches: params.Architectures,
		})
	}
	matchingTools, resolveInfo, err := Fetch(params.Sources, toolsConstraint)
	if err != nil {
		return nil, resolveInfo, err
	}
	if len(matchingTools) == 0 {
		return nil, resolveInfo, fmt.Errorf("no matching agent binaries found for constraint %+v", toolsConstraint)
	}
	versions := make([]string, len(matchingTools))
	for i, tm := range matchingTools {
		vers := version.Binary{
			Number: version.MustParse(tm.Version),
			Series: tm.Release,
			Arch:   tm.Arch,
		}
		versions[i] = vers.String()
	}
	return versions, resolveInfo, nil
}
711602
func (c *Client) FindTools(args params.FindToolsParams) (params.FindToolsResult, error) {
	if err := c.checkCanWrite(); err != nil {
		return params.FindToolsResult{}, err
	}

	return c.api.toolsFinder.FindTools(args)
}
991975
func getToolContentsImpl() (contents []byte, err error) {
	// Fast path: has the user set the flag?
	if *fToolPath != "" {
		contents, err = ioutil.ReadFile(*fToolPath)
		if err != nil {
			err = fmt.Errorf("Reading mount_sample contents: %v", err)
			return
		}

		return
	}

	// Create a temporary directory into which we will compile the tool.
	tempDir, err := ioutil.TempDir("", "sample_test")
	if err != nil {
		err = fmt.Errorf("TempDir: %v", err)
		return
	}

	toolPath := path.Join(tempDir, "mount_sample")

	// Ensure that we kill the temporary directory when we're finished here.
	defer os.RemoveAll(tempDir)

	// Run "go build".
	cmd := exec.Command(
		"go",
		"build",
		"-o",
		toolPath,
		"github.com/jacobsa/fuse/samples/mount_sample")

	output, err := cmd.CombinedOutput()
	if err != nil {
		err = fmt.Errorf(
			"mount_sample exited with %v, output:\n%s",
			err,
			string(output))

		return
	}

	// Slurp the tool contents.
	contents, err = ioutil.ReadFile(toolPath)
	if err != nil {
		err = fmt.Errorf("ReadFile: %v", err)
		return
	}

	return
}
1356974
func IsCompatible(client, server string) bool {
	if isUnreleased(client) || isUnreleased(server) {
		return true
	}
	cv, err := semver.NewVersion(client)
	if err != nil {
		return false
	}
	sv, err := semver.NewVersion(server)
	if err != nil {
		return false
	}

	constraint := fmt.Sprintf("^%d.%d.x", cv.Major(), cv.Minor())
	if cv.Prerelease() != "" || sv.Prerelease() != "" {
		constraint = cv.String()
	}

	return IsCompatibleRange(constraint, server)
}
752526
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
	bhead := new(big.Int).SetUint64(height)

	// Iterate checkCompatible to find the lowest conflict.
	var lasterr *ConfigCompatError
	for {
		err := c.checkCompatible(newcfg, bhead)
		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
			break
		}
		lasterr = err
		bhead.SetUint64(err.RewindTo)
	}
	return lasterr
}
230816
func findBuildTrigger(dst []buildv1.BuildTriggerPolicy, trigger buildv1.BuildTriggerPolicy) int {
	// make a copy for semantic equality
	if trigger.ImageChange != nil {
		trigger.ImageChange = &buildv1.ImageChangeTrigger{From: trigger.ImageChange.From}
	}
	for i, copied := range dst {
		// make a copy for semantic equality
		if copied.ImageChange != nil {
			copied.ImageChange = &buildv1.ImageChangeTrigger{From: copied.ImageChange.From}
		}
		if reflect.DeepEqual(copied, trigger) {
			return i
		}
	}
	return -1
}
326871
func NewGeneralToolsConstraint(majorVersion, minorVersion int, params simplestreams.LookupParams) *ToolsConstraint {
	return &ToolsConstraint{LookupParams: params, Version: version.Zero,
		MajorVersion: majorVersion, MinorVersion: minorVersion}
}
732673
func SyncTools(syncContext *SyncContext) error {
	sourceDataSource, err := selectSourceDatasource(syncContext)
	if err != nil {
		return errors.Trace(err)
	}

	logger.Infof("listing available agent binaries")
	if syncContext.MajorVersion == 0 && syncContext.MinorVersion == 0 {
		syncContext.MajorVersion = jujuversion.Current.Major
		syncContext.MinorVersion = -1
		if !syncContext.AllVersions {
			syncContext.MinorVersion = jujuversion.Current.Minor
		}
	}

	toolsDir := syncContext.Stream
	// If no stream has been specified, assume "released" for non-devel versions of Juju.
	if syncContext.Stream == "" {
		// We now store the tools in a directory named after their stream, but the
		// legacy behaviour is to store all tools in a single "releases" directory.
		toolsDir = envtools.ReleasedStream
		// Always use the primary stream here - the user can specify
		// to override that decision.
		syncContext.Stream = envtools.PreferredStreams(&jujuversion.Current, false, "")[0]
	}
	// For backwards compatibility with cloud storage, if there are no tools in the specified stream,
	// double check the release stream.
	// TODO - remove this when we no longer need to support cloud storage upgrades.
	streams := []string{syncContext.Stream, envtools.ReleasedStream}
	sourceTools, err := envtools.FindToolsForCloud(
		[]simplestreams.DataSource{sourceDataSource}, simplestreams.CloudSpec{},
		streams, syncContext.MajorVersion, syncContext.MinorVersion, coretools.Filter{})
	if err != nil {
		return errors.Trace(err)
	}

	logger.Infof("found %d agent binaries", len(sourceTools))
	if !syncContext.AllVersions {
		var latest version.Number
		latest, sourceTools = sourceTools.Newest()
		logger.Infof("found %d recent agent binaries (version %s)", len(sourceTools), latest)
	}
	for _, tool := range sourceTools {
		logger.Debugf("found source agent binary: %v", tool)
	}

	logger.Infof("listing target agent binaries storage")
	targetTools, err := syncContext.TargetToolsFinder.FindTools(syncContext.MajorVersion, syncContext.Stream)
	switch err {
	case nil, coretools.ErrNoMatches, envtools.ErrNoTools:
	default:
		return errors.Trace(err)
	}
	for _, tool := range targetTools {
		logger.Debugf("found target agent binary: %v", tool)
	}

	missing := sourceTools.Exclude(targetTools)
	logger.Infof("found %d agent binaries in target; %d agent binaries to be copied", len(targetTools), len(missing))
	if syncContext.DryRun {
		for _, tools := range missing {
			logger.Infof("copying %s from %s", tools.Version, tools.URL)
		}
		return nil
	}

	err = copyTools(toolsDir, syncContext.Stream, missing, syncContext.TargetToolsUploader)
	if err != nil {
		return err
	}
	logger.Infof("copied %d agent binaries", len(missing))
	return nil
}
478973
func compatibleFields(existing FieldDefinition, new FieldDefinition) bool {
	if existing.Required != new.Required {
		return false
	}
	return existing.Type.Equal(new.Type)
}
938318
func MatchCompLit(n ast.Node, ctx *Context, required string) *ast.CompositeLit {
	if complit, ok := n.(*ast.CompositeLit); ok {
		typeOf := ctx.Info.TypeOf(complit)
		if typeOf.String() == required {
			return complit
		}
	}
	return nil
}
7787
func NewVersionedToolsConstraint(vers version.Number, params simplestreams.LookupParams) *ToolsConstraint {
	return &ToolsConstraint{LookupParams: params, Version: vers}
}
213634
func FindExactTools(env environs.Environ, vers version.Number, series string, arch string) (_ *coretools.Tools, err error) {
	logger.Debugf("finding exact version %s", vers)
	// Construct a tools filter.
	// Discard all that are known to be irrelevant.
	filter := coretools.Filter{
		Number: vers,
		Series: series,
		Arch:   arch,
	}
	streams := PreferredStreams(&vers, env.Config().Development(), env.Config().AgentStream())
	logger.Debugf("looking for agent binaries in streams %v", streams)
	availableTools, err := FindTools(env, vers.Major, vers.Minor, streams, filter)
	if err != nil {
		return nil, err
	}
	if len(availableTools) != 1 {
		return nil, fmt.Errorf("expected one agent binary, got %d agent binaries", len(availableTools))
	}
	return availableTools[0], nil
}
1184330
func (f *ToolsFinder) matchingStorageTools(args params.FindToolsParams) (coretools.List, error) {
	storage, err := f.toolsStorageGetter.ToolsStorage()
	if err != nil {
		return nil, err
	}
	defer storage.Close()
	allMetadata, err := storage.AllMetadata()
	if err != nil {
		return nil, err
	}
	list := make(coretools.List, len(allMetadata))
	for i, m := range allMetadata {
		vers, err := version.ParseBinary(m.Version)
		if err != nil {
			return nil, errors.Annotatef(err, "unexpected bad version %q of agent binary in storage", m.Version)
		}
		list[i] = &coretools.Tools{
			Version: vers,
			Size:    m.Size,
			SHA256:  m.SHA256,
		}
	}
	list, err = list.Match(toolsFilter(args))
	if err != nil {
		return nil, err
	}
	var matching coretools.List
	for _, tools := range list {
		if args.MajorVersion != -1 && tools.Version.Major != args.MajorVersion {
			continue
		}
		if args.MinorVersion != -1 && tools.Version.Minor != args.MinorVersion {
			continue
		}
		matching = append(matching, tools)
	}
	if len(matching) == 0 {
		return nil, coretools.ErrNoMatches
	}
	return matching, nil
}
568056
func AnyCompatible(compatible []Semver, actual Semver) (isApiCompat bool) {
	for _, v := range compatible {
		if Compatible(v, actual) {
			isApiCompat = true
			break
		}
	}
	return
}