// FindTools returns a List containing all tools in the given stream, with a given // major.minor version number available in the cloud instance, filtered by filter. // If minorVersion = -1, then only majorVersion is considered. // If no *available* tools have the supplied major.minor version number, or match the // supplied filter, the function returns a *NotFoundError. func FindTools(env environs.Environ, majorVersion, minorVersion int, stream string, filter coretools.Filter) (list coretools.List, err error) { var cloudSpec simplestreams.CloudSpec switch env := env.(type) { case simplestreams.HasRegion: if cloudSpec, err = env.Region(); err != nil { return nil, err } case HasAgentMirror: if cloudSpec, err = env.AgentMirror(); err != nil { return nil, err } } // If only one of region or endpoint is provided, that is a problem. if cloudSpec.Region != cloudSpec.Endpoint && (cloudSpec.Region == "" || cloudSpec.Endpoint == "") { return nil, fmt.Errorf("cannot find tools without a complete cloud configuration") } logger.Infof("finding tools in stream %q", stream) if minorVersion >= 0 { logger.Infof("reading tools with major.minor version %d.%d", majorVersion, minorVersion) } else { logger.Infof("reading tools with major version %d", majorVersion) } defer convertToolsError(&err) // Construct a tools filter. // Discard all that are known to be irrelevant. if filter.Number != version.Zero { logger.Infof("filtering tools by version: %s", filter.Number) } if filter.Series != "" { logger.Infof("filtering tools by series: %s", filter.Series) } if filter.Arch != "" { logger.Infof("filtering tools by architecture: %s", filter.Arch) } sources, err := GetMetadataSources(env) if err != nil { return nil, err } return FindToolsForCloud(sources, cloudSpec, stream, majorVersion, minorVersion, filter) }