// OfficialDataSources returns the simplestreams datasources where official // image metadata can be found. func OfficialDataSources(stream string) ([]simplestreams.DataSource, error) { var result []simplestreams.DataSource // New images metadata for centos and windows and existing clouds. defaultJujuURL, err := ImageMetadataURL(DefaultJujuBaseURL, stream) if err != nil { return nil, err } if defaultJujuURL != "" { publicKey, err := simplestreams.UserPublicSigningKey() if err != nil { return nil, err } if publicKey == "" { publicKey = keys.JujuPublicKey } result = append( result, simplestreams.NewURLSignedDataSource("default cloud images", defaultJujuURL, publicKey, utils.VerifySSLHostnames, simplestreams.DEFAULT_CLOUD_DATA, true)) } // Fallback to image metadata for existing Ubuntu images. defaultUbuntuURL, err := ImageMetadataURL(DefaultUbuntuBaseURL, stream) if err != nil { return nil, err } if defaultUbuntuURL != "" { result = append( result, simplestreams.NewURLSignedDataSource("default ubuntu cloud images", defaultUbuntuURL, SimplestreamsImagesPublicKey, utils.VerifySSLHostnames, simplestreams.DEFAULT_CLOUD_DATA, true)) } return result, nil }
// GetMetadataSources returns the sources to use when looking for // simplestreams tools metadata for the given stream. func GetMetadataSources(env environs.Environ) ([]simplestreams.DataSource, error) { config := env.Config() // Add configured and environment-specific datasources. var sources []simplestreams.DataSource if userURL, ok := config.AgentMetadataURL(); ok { verify := utils.VerifySSLHostnames if !config.SSLHostnameVerification() { verify = utils.NoVerifySSLHostnames } sources = append(sources, simplestreams.NewURLSignedDataSource(conf.AgentMetadataURLKey, userURL, juju.JujuPublicKey, verify, simplestreams.SPECIFIC_CLOUD_DATA, false)) } envDataSources, err := environmentDataSources(env) if err != nil { return nil, err } sources = append(sources, envDataSources...) // Add the default, public datasource. defaultURL, err := ToolsURL(DefaultBaseURL) if err != nil { return nil, err } if defaultURL != "" { sources = append(sources, simplestreams.NewURLSignedDataSource("default simplestreams", defaultURL, juju.JujuPublicKey, utils.VerifySSLHostnames, simplestreams.DEFAULT_CLOUD_DATA, true)) } return sources, nil }
// saveCustomImageMetadata reads the custom image metadata from disk, // and saves it in controller. func (c *BootstrapCommand) saveCustomImageMetadata(st *state.State, env environs.Environ) error { logger.Debugf("saving custom image metadata from %q", c.ImageMetadataDir) baseURL := fmt.Sprintf("file://%s", filepath.ToSlash(c.ImageMetadataDir)) publicKey, _ := simplestreams.UserPublicSigningKey() datasource := simplestreams.NewURLSignedDataSource("custom", baseURL, publicKey, utils.NoVerifySSLHostnames, simplestreams.CUSTOM_CLOUD_DATA, false) return storeImageMetadataFromFiles(st, env, datasource) }
// setPrivateMetadataSources sets the default tools metadata source // for tools syncing, and adds an image metadata source after verifying // the contents. func setPrivateMetadataSources(env environs.Environ, metadataDir string) ([]*imagemetadata.ImageMetadata, error) { logger.Infof("Setting default tools and image metadata sources: %s", metadataDir) tools.DefaultBaseURL = metadataDir imageMetadataDir := filepath.Join(metadataDir, storage.BaseImagesPath) if _, err := os.Stat(imageMetadataDir); err != nil { if !os.IsNotExist(err) { return nil, errors.Annotate(err, "cannot access image metadata") } return nil, nil } baseURL := fmt.Sprintf("file://%s", filepath.ToSlash(imageMetadataDir)) publicKey, _ := simplestreams.UserPublicSigningKey() datasource := simplestreams.NewURLSignedDataSource("bootstrap metadata", baseURL, publicKey, utils.NoVerifySSLHostnames, simplestreams.CUSTOM_CLOUD_DATA, false) // Read the image metadata, as we'll want to upload it to the environment. imageConstraint := imagemetadata.NewImageConstraint(simplestreams.LookupParams{}) existingMetadata, _, err := imagemetadata.Fetch([]simplestreams.DataSource{datasource}, imageConstraint) if err != nil && !errors.IsNotFound(err) { return nil, errors.Annotate(err, "cannot read image metadata") } // Add an image metadata datasource for constraint validation, etc. environs.RegisterUserImageDataSourceFunc("bootstrap metadata", func(environs.Environ) (simplestreams.DataSource, error) { return datasource, nil }) logger.Infof("custom image metadata added to search path") return existingMetadata, nil }
// ImageMetadataSources returns the sources to use when looking for // simplestreams image id metadata for the given stream. func ImageMetadataSources(env Environ) ([]simplestreams.DataSource, error) { config := env.Config() // Add configured and environment-specific datasources. var sources []simplestreams.DataSource if userURL, ok := config.ImageMetadataURL(); ok { verify := utils.VerifySSLHostnames if !config.SSLHostnameVerification() { verify = utils.NoVerifySSLHostnames } publicKey, _ := simplestreams.UserPublicSigningKey() sources = append(sources, simplestreams.NewURLSignedDataSource("image-metadata-url", userURL, publicKey, verify, simplestreams.SPECIFIC_CLOUD_DATA, false)) } envDataSources, err := environmentDataSources(env) if err != nil { return nil, err } sources = append(sources, envDataSources...) // Add the official image metadata datasources. officialDataSources, err := imagemetadata.OfficialDataSources(config.ImageStream()) if err != nil { return nil, err } for _, source := range officialDataSources { sources = append(sources, source) } for _, ds := range sources { logger.Debugf("obtained image datasource %q", ds.Description()) } return sources, nil }
// DataSource creates and returns a new simplestreams signed data source for // fetching Juju GUI archives, at the given URL. func NewDataSource(baseURL string) simplestreams.DataSource { requireSigned := true return simplestreams.NewURLSignedDataSource( sourceDescription, baseURL, juju.JujuPublicKey, utils.VerifySSLHostnames, simplestreams.DEFAULT_CLOUD_DATA, requireSigned) }
// 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 toolsDataSources(urls ...string) []simplestreams.DataSource { dataSources := make([]simplestreams.DataSource, len(urls)) for i, url := range urls { dataSources[i] = simplestreams.NewURLSignedDataSource( "local source", url, juju.JujuPublicKey, utils.VerifySSLHostnames, simplestreams.CUSTOM_CLOUD_DATA, false) } return dataSources }
func (s *signedSuite) TestSignedImageMetadata(c *gc.C) { signedSource := simplestreams.NewURLSignedDataSource("test", "test://host/signed", sstesting.SignedMetadataPublicKey, utils.VerifySSLHostnames, simplestreams.DEFAULT_CLOUD_DATA, true) imageConstraint := imagemetadata.NewImageConstraint(simplestreams.LookupParams{ CloudSpec: simplestreams.CloudSpec{"us-east-1", "https://ec2.us-east-1.amazonaws.com"}, Series: []string{"precise"}, Arches: []string{"amd64"}, }) images, resolveInfo, err := imagemetadata.Fetch([]simplestreams.DataSource{signedSource}, imageConstraint) c.Assert(err, jc.ErrorIsNil) c.Assert(len(images), gc.Equals, 1) c.Assert(images[0].Id, gc.Equals, "ami-123456") c.Check(resolveInfo, gc.DeepEquals, &simplestreams.ResolveInfo{ Source: "test", Signed: true, IndexURL: "test://host/signed/streams/v1/index.sjson", MirrorURL: "", }) }
func (s *signedSuite) TestSignedToolsMetadata(c *gc.C) { signedSource := simplestreams.NewURLSignedDataSource( "test", "signedtest://host/signed", sstesting.SignedMetadataPublicKey, utils.VerifySSLHostnames, simplestreams.DEFAULT_CLOUD_DATA, true) toolsConstraint := tools.NewVersionedToolsConstraint(version.MustParse("1.13.0"), simplestreams.LookupParams{ CloudSpec: simplestreams.CloudSpec{"us-east-1", "https://ec2.us-east-1.amazonaws.com"}, Series: []string{"precise"}, Arches: []string{"amd64"}, Stream: "released", }) toolsMetadata, resolveInfo, err := tools.Fetch( []simplestreams.DataSource{signedSource}, toolsConstraint) c.Assert(err, jc.ErrorIsNil) c.Assert(len(toolsMetadata), gc.Equals, 1) c.Assert(toolsMetadata[0].Path, gc.Equals, "tools/releases/20130806/juju-1.13.1-precise-amd64.tgz") c.Assert(resolveInfo, gc.DeepEquals, &simplestreams.ResolveInfo{ Source: "test", Signed: true, IndexURL: "signedtest://host/signed/streams/v1/index.sjson", MirrorURL: "", }) }
} if c.series != "" { params.Series = c.series } if c.region != "" { params.Region = c.region } if c.endpoint != "" { params.Endpoint = c.endpoint } if c.metadataDir != "" { dir := filepath.Join(c.metadataDir, "images") if _, err := os.Stat(dir); err != nil { return nil, err } params.Sources = imagesDataSources(dir) } return params, nil } var imagesDataSources = func(urls ...string) []simplestreams.DataSource { dataSources := make([]simplestreams.DataSource, len(urls)) publicKey, _ := simplestreams.UserPublicSigningKey() for i, url := range urls { dataSources[i] = simplestreams.NewURLSignedDataSource( "local metadata directory", "file://"+url, publicKey, utils.VerifySSLHostnames, simplestreams.CUSTOM_CLOUD_DATA, false) } return dataSources }