func (s *URLsSuite) TestToolsURL(c *gc.C) { var toolsTests = []struct { in string expected string expectedErr error }{{ in: "", expected: "", expectedErr: nil, }, { in: "file://foo", expected: "file://foo", expectedErr: nil, }, { in: "http://foo", expected: "http://foo", expectedErr: nil, }, { in: "foo", expected: "", expectedErr: fmt.Errorf("foo is not an absolute path"), }} toolsTests = append(toolsTests, toolsTestsPlatformSpecific...) for i, t := range toolsTests { c.Logf("Test %d:", i) out, err := tools.ToolsURL(t.in) c.Assert(err, gc.DeepEquals, t.expectedErr) c.Assert(out, gc.Equals, t.expected) } }
// selectSourceDatasource returns a storage reader based on the source setting. func selectSourceDatasource(syncContext *SyncContext) (simplestreams.DataSource, error) { source := syncContext.Source if source == "" { source = envtools.DefaultBaseURL } sourceURL, err := envtools.ToolsURL(source) if err != nil { return nil, err } logger.Infof("using sync tools source: %v", sourceURL) return simplestreams.NewURLDataSource("sync tools source", sourceURL, utils.VerifySSLHostnames), nil }
// selectSourceDatasource returns a storage reader based on the source setting. func selectSourceDatasource(syncContext *SyncContext) (simplestreams.DataSource, error) { source := syncContext.Source if source == "" { source = envtools.DefaultBaseURL } sourceURL, err := envtools.ToolsURL(source) if err != nil { return nil, err } logger.Infof("using sync tools source: %v", sourceURL) return simplestreams.NewURLSignedDataSource("sync tools source", sourceURL, juju.JujuPublicKey, utils.VerifySSLHostnames, simplestreams.CUSTOM_CLOUD_DATA, false), nil }
func (s *URLsSuite) TestToolsURL(c *gc.C) { for source, expected := range map[string]string{ "": "", "foo": "file://foo/tools", "/home/foo": "file:///home/foo/tools", "file://foo": "file://foo", "http://foo": "http://foo", } { URL, err := tools.ToolsURL(source) c.Assert(err, gc.IsNil) c.Assert(URL, gc.Equals, expected) } }
func (c *toolsMetadataCommand) Run(context *cmd.Context) error { loggo.RegisterWriter("toolsmetadata", cmd.NewCommandLogWriter("juju.environs.tools", context.Stdout, context.Stderr), loggo.INFO) defer loggo.RemoveWriter("toolsmetadata") if c.metadataDir == "" { c.metadataDir = osenv.JujuHome() } else { c.metadataDir = context.AbsPath(c.metadataDir) } sourceStorage, err := filestorage.NewFileStorageReader(c.metadataDir) if err != nil { return err } // 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 := c.stream if c.stream == "" { fmt.Fprintf(context.Stdout, "No stream specified, defaulting to released tools in the releases directory.\n") c.stream = envtools.ReleasedStream toolsDir = envtools.LegacyReleaseDirectory } fmt.Fprintf(context.Stdout, "Finding tools in %s for stream %s.\n", c.metadataDir, c.stream) const minorVersion = -1 toolsList, err := envtools.ReadList(sourceStorage, toolsDir, version.Current.Major, minorVersion) if err == envtools.ErrNoTools { var source string source, err = envtools.ToolsURL(envtools.DefaultBaseURL) if err != nil { return err } sourceDataSource := simplestreams.NewURLDataSource("local source", source, utils.VerifySSLHostnames) toolsList, err = envtools.FindToolsForCloud( []simplestreams.DataSource{sourceDataSource}, simplestreams.CloudSpec{}, c.stream, version.Current.Major, minorVersion, coretools.Filter{}) } if err != nil { return err } targetStorage, err := filestorage.NewFileStorageWriter(c.metadataDir) if err != nil { return err } writeMirrors := envtools.DoNotWriteMirrors if c.public { writeMirrors = envtools.WriteMirrors } return mergeAndWriteMetadata(targetStorage, toolsDir, c.stream, c.clean, toolsList, writeMirrors) }
func (c *toolsMetadataCommand) Run(context *cmd.Context) error { writer := loggo.NewMinimumLevelWriter( cmd.NewCommandLogWriter("juju.environs.tools", context.Stdout, context.Stderr), loggo.INFO) loggo.RegisterWriter("toolsmetadata", writer) defer loggo.RemoveWriter("toolsmetadata") if c.metadataDir == "" { c.metadataDir = osenv.JujuXDGDataHomeDir() } else { c.metadataDir = context.AbsPath(c.metadataDir) } sourceStorage, err := filestorage.NewFileStorageReader(c.metadataDir) if err != nil { return err } // 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 := c.stream if c.stream == "" { fmt.Fprintln(context.Stdout, "No stream specified, defaulting to released tools in the releases directory.") c.stream = envtools.ReleasedStream toolsDir = envtools.LegacyReleaseDirectory } fmt.Fprintf(context.Stdout, "Finding tools in %s for stream %s.\n", c.metadataDir, c.stream) toolsList, err := envtools.ReadList(sourceStorage, toolsDir, -1, -1) if err == envtools.ErrNoTools { var source string source, err = envtools.ToolsURL(envtools.DefaultBaseURL) if err != nil { return err } toolsList, err = envtools.FindToolsForCloud(toolsDataSources(source), simplestreams.CloudSpec{}, c.stream, -1, -1, coretools.Filter{}) } if err != nil { return err } targetStorage, err := filestorage.NewFileStorageWriter(c.metadataDir) if err != nil { return err } writeMirrors := envtools.DoNotWriteMirrors if c.public { writeMirrors = envtools.WriteMirrors } return mergeAndWriteMetadata(targetStorage, toolsDir, c.stream, c.clean, toolsList, writeMirrors) }
func (c *ToolsMetadataCommand) Run(context *cmd.Context) error { loggo.RegisterWriter("toolsmetadata", cmd.NewCommandLogWriter("juju.environs.tools", context.Stdout, context.Stderr), loggo.INFO) defer loggo.RemoveWriter("toolsmetadata") if c.metadataDir == "" { c.metadataDir = osenv.JujuHome() } else { c.metadataDir = context.AbsPath(c.metadataDir) } sourceStorage, err := filestorage.NewFileStorageReader(c.metadataDir) if err != nil { return err } fmt.Fprintf(context.Stdout, "Finding tools in %s\n", c.metadataDir) const minorVersion = -1 toolsList, err := envtools.ReadList(sourceStorage, version.Current.Major, minorVersion) if err == envtools.ErrNoTools { var source string source, err = envtools.ToolsURL(envtools.DefaultBaseURL) if err != nil { return err } sourceDataSource := simplestreams.NewURLDataSource("local source", source, utils.VerifySSLHostnames) toolsList, err = envtools.FindToolsForCloud( []simplestreams.DataSource{sourceDataSource}, simplestreams.CloudSpec{}, version.Current.Major, minorVersion, coretools.Filter{}) } if err != nil { return err } targetStorage, err := filestorage.NewFileStorageWriter(c.metadataDir) if err != nil { return err } writeMirrors := envtools.DoNotWriteMirrors if c.public { writeMirrors = envtools.WriteMirrors } return mergeAndWriteMetadata(targetStorage, toolsList, writeMirrors) }
func (c *toolsMetadataCommand) Run(context *cmd.Context) error { writer := loggo.NewMinimumLevelWriter( cmd.NewCommandLogWriter("juju.environs.tools", context.Stdout, context.Stderr), loggo.INFO) loggo.RegisterWriter("toolsmetadata", writer) defer loggo.RemoveWriter("toolsmetadata") if c.metadataDir == "" { c.metadataDir = osenv.JujuXDGDataHomeDir() } else { c.metadataDir = context.AbsPath(c.metadataDir) } sourceStorage, err := filestorage.NewFileStorageReader(c.metadataDir) if err != nil { return errors.Trace(err) } fmt.Fprintf(context.Stdout, "Finding tools in %s for stream %s.\n", c.metadataDir, c.stream) toolsList, err := envtools.ReadList(sourceStorage, c.stream, -1, -1) if err == envtools.ErrNoTools { var source string source, err = envtools.ToolsURL(envtools.DefaultBaseURL) if err != nil { return errors.Trace(err) } toolsList, err = envtools.FindToolsForCloud(toolsDataSources(source), simplestreams.CloudSpec{}, c.stream, -1, -1, coretools.Filter{}) } if err != nil { return errors.Trace(err) } targetStorage, err := filestorage.NewFileStorageWriter(c.metadataDir) if err != nil { return errors.Trace(err) } writeMirrors := envtools.DoNotWriteMirrors if c.public { writeMirrors = envtools.WriteMirrors } return errors.Trace(mergeAndWriteMetadata(targetStorage, c.stream, c.stream, c.clean, toolsList, writeMirrors)) }
func (c *validateToolsMetadataCommand) Run(context *cmd.Context) error { var params *simplestreams.MetadataLookupParams if c.providerType == "" { store, err := configstore.Default() if err != nil { return err } environ, err := c.prepare(context, store) if err == nil { mdLookup, ok := environ.(simplestreams.MetadataValidator) if !ok { return fmt.Errorf("%s provider does not support tools metadata validation", environ.Config().Type()) } params, err = mdLookup.MetadataLookupParams(c.region) if err != nil { return err } params.Sources, err = tools.GetMetadataSources(environ) if err != nil { return err } } else { if c.metadataDir == "" { return err } params = &simplestreams.MetadataLookupParams{ Architectures: arch.AllSupportedArches, } } } else { prov, err := environs.Provider(c.providerType) if err != nil { return err } mdLookup, ok := prov.(simplestreams.MetadataValidator) if !ok { return fmt.Errorf("%s provider does not support tools metadata validation", c.providerType) } params, err = mdLookup.MetadataLookupParams(c.region) if err != nil { return err } } if c.series != "" { params.Series = c.series } if c.region != "" { params.Region = c.region } if c.endpoint != "" { params.Endpoint = c.endpoint } if c.metadataDir != "" { if _, err := os.Stat(c.metadataDir); err != nil { return err } toolsURL, err := tools.ToolsURL(c.metadataDir) if err != nil { return err } params.Sources = []simplestreams.DataSource{simplestreams.NewURLDataSource( "local metadata directory", toolsURL, utils.VerifySSLHostnames, simplestreams.CUSTOM_CLOUD_DATA, false), } } params.Stream = c.stream versions, resolveInfo, err := tools.ValidateToolsMetadata(&tools.ToolsMetadataLookupParams{ MetadataLookupParams: *params, Version: c.exactVersion, Major: c.major, Minor: c.minor, }) if err != nil { if resolveInfo != nil { metadata := map[string]interface{}{ "Resolve Metadata": *resolveInfo, } if metadataYaml, yamlErr := cmd.FormatYaml(metadata); yamlErr == nil { err = fmt.Errorf("%v\n%v", err, string(metadataYaml)) } } return err } if len(versions) > 0 { metadata := map[string]interface{}{ "Matching Tools Versions": versions, "Resolve Metadata": *resolveInfo, } c.out.Write(context, metadata) } else { var sources []string for _, s := range params.Sources { url, err := s.URL("") if err == nil { sources = append(sources, fmt.Sprintf("- %s (%s)", s.Description(), url)) } } return fmt.Errorf("no matching tools using sources:\n%s", strings.Join(sources, "\n")) } return nil }
func (c *validateToolsMetadataCommand) Run(context *cmd.Context) error { var params *simplestreams.MetadataLookupParams if c.providerType == "" { environ, err := c.prepare(context) if err == nil { mdLookup, ok := environ.(simplestreams.MetadataValidator) if !ok { return errors.Errorf("%s provider does not support tools metadata validation", environ.Config().Type()) } params, err = mdLookup.MetadataLookupParams(c.region) if err != nil { return err } params.Sources, err = tools.GetMetadataSources(environ) if err != nil { return err } } else { if c.metadataDir == "" { return err } params = &simplestreams.MetadataLookupParams{} } } else { prov, err := environs.Provider(c.providerType) if err != nil { return err } mdLookup, ok := prov.(simplestreams.MetadataValidator) if !ok { return errors.Errorf("%s provider does not support tools metadata validation", c.providerType) } params, err = mdLookup.MetadataLookupParams(c.region) if err != nil { return err } } if len(params.Architectures) == 0 { params.Architectures = arch.AllSupportedArches } if c.series != "" { params.Series = c.series } if c.region != "" { params.Region = c.region } if c.endpoint != "" { params.Endpoint = c.endpoint } if c.metadataDir != "" { if _, err := os.Stat(c.metadataDir); err != nil { return err } toolsURL, err := tools.ToolsURL(c.metadataDir) if err != nil { return err } params.Sources = toolsDataSources(toolsURL) } params.Stream = c.stream versions, resolveInfo, err := tools.ValidateToolsMetadata(&tools.ToolsMetadataLookupParams{ MetadataLookupParams: *params, Version: c.exactVersion, Major: c.major, Minor: c.minor, }) if err != nil { if resolveInfo != nil { metadata := map[string]interface{}{ "Resolve Metadata": *resolveInfo, } buff := &bytes.Buffer{} if yamlErr := cmd.FormatYaml(buff, metadata); yamlErr == nil { err = errors.Errorf("%v\n%v", err, buff.String()) } } return err } if len(versions) > 0 { metadata := map[string]interface{}{ "Matching Tools Versions": versions, "Resolve Metadata": *resolveInfo, } c.out.Write(context, metadata) } else { var sources []string for _, s := range params.Sources { url, err := s.URL("") if err == nil { sources = append(sources, fmt.Sprintf("- %s (%s)", s.Description(), url)) } } return errors.Errorf("no matching tools using sources:\n%s", strings.Join(sources, "\n")) } return nil }