示例#1
0
func (s *providerSuite) TestNullAlias(c *gc.C) {
	p, err := environs.Provider("manual")
	c.Assert(p, gc.NotNil)
	c.Assert(err, gc.IsNil)
	p, err = environs.Provider("null")
	c.Assert(p, gc.NotNil)
	c.Assert(err, gc.IsNil)
}
示例#2
0
func (s *MainSuite) TestProvidersAreRegistered(c *gc.C) {
	// check that all the expected providers are registered
	for _, name := range expectedProviders {
		_, err := environs.Provider(name)
		c.Assert(err, gc.IsNil)
	}
}
示例#3
0
func (s *prepareSuite) TestPrepareProxySSH(c *gc.C) {
	s.PatchValue(local.DetectAptProxies, func() (osenv.ProxySettings, error) {
		return osenv.ProxySettings{}, nil
	})
	basecfg, err := config.New(config.UseDefaults, map[string]interface{}{
		"type": "local",
		"name": "test",
	})
	provider, err := environs.Provider("local")
	c.Assert(err, gc.IsNil)
	env, err := provider.Prepare(coretesting.Context(c), basecfg)
	c.Assert(err, gc.IsNil)
	// local provider sets proxy-ssh to false
	c.Assert(env.Config().ProxySSH(), gc.Equals, false)
}
示例#4
0
func (s *prepareSuite) TestPrepareNamespace(c *gc.C) {
	s.PatchValue(local.DetectAptProxies, func() (osenv.ProxySettings, error) {
		return osenv.ProxySettings{}, nil
	})
	basecfg, err := config.New(config.UseDefaults, map[string]interface{}{
		"type": "local",
		"name": "test",
	})
	provider, err := environs.Provider("local")
	c.Assert(err, gc.IsNil)

	type test struct {
		userEnv   string
		userOS    string
		userOSErr error
		namespace string
		err       string
	}
	tests := []test{{
		userEnv:   "someone",
		userOS:    "other",
		namespace: "someone-test",
	}, {
		userOS:    "other",
		namespace: "other-test",
	}, {
		userOSErr: errors.New("oh noes"),
		err:       "failed to determine username for namespace: oh noes",
	}}

	for i, test := range tests {
		c.Logf("test %d: %v", i, test)
		s.PatchEnvironment("USER", test.userEnv)
		s.PatchValue(local.UserCurrent, func() (*user.User, error) {
			return &user.User{Username: test.userOS}, test.userOSErr
		})
		env, err := provider.Prepare(coretesting.Context(c), basecfg)
		if test.err == "" {
			c.Assert(err, gc.IsNil)
			cfg := env.Config()
			c.Assert(cfg.UnknownAttrs()["namespace"], gc.Equals, test.namespace)
		} else {
			c.Assert(err, gc.ErrorMatches, test.err)
		}
	}
}
示例#5
0
func (s *BootstrapSuite) makeTestEnv(c *gc.C) {
	attrs := dummy.SampleConfig().Merge(
		testing.Attrs{
			"agent-version": version.Current.Number.String(),
		},
	).Delete("admin-secret", "ca-private-key")

	cfg, err := config.New(config.NoDefaults, attrs)
	c.Assert(err, gc.IsNil)
	provider, err := environs.Provider(cfg.Type())
	c.Assert(err, gc.IsNil)
	env, err := provider.Prepare(nullContext(), cfg)
	c.Assert(err, gc.IsNil)

	envtesting.MustUploadFakeTools(env.Storage())
	inst, _, _, err := jujutesting.StartInstance(env, "0")
	c.Assert(err, gc.IsNil)
	s.instanceId = inst.Id()
	s.bootstrapName, err = inst.DNSName()
	c.Assert(err, gc.IsNil)
	s.envcfg = b64yaml(env.Config().AllAttrs()).encode()
}
示例#6
0
func (s *suite) TestRegisterProvider(c *gc.C) {
	s.PatchValue(environs.Providers, make(map[string]environs.EnvironProvider))
	s.PatchValue(environs.ProviderAliases, make(map[string]string))
	type step struct {
		name    string
		aliases []string
		err     string
	}
	type test []step

	tests := []test{
		[]step{{
			name: "providerName",
		}},
		[]step{{
			name:    "providerName",
			aliases: []string{"providerName"},
			err:     "juju: duplicate provider alias \"providerName\"",
		}},
		[]step{{
			name:    "providerName",
			aliases: []string{"providerAlias", "providerAlias"},
			err:     "juju: duplicate provider alias \"providerAlias\"",
		}},
		[]step{{
			name:    "providerName",
			aliases: []string{"providerAlias1", "providerAlias2"},
		}},
		[]step{{
			name: "providerName",
		}, {
			name: "providerName",
			err:  "juju: duplicate provider name \"providerName\"",
		}},
		[]step{{
			name: "providerName1",
		}, {
			name:    "providerName2",
			aliases: []string{"providerName"},
		}},
		[]step{{
			name: "providerName1",
		}, {
			name:    "providerName2",
			aliases: []string{"providerName1"},
			err:     "juju: duplicate provider alias \"providerName1\"",
		}},
	}

	registerProvider := func(name string, aliases []string) (err error) {
		defer func() { err, _ = recover().(error) }()
		registered := &dummyProvider{}
		environs.RegisterProvider(name, registered, aliases...)
		p, err := environs.Provider(name)
		c.Assert(err, gc.IsNil)
		c.Assert(p, gc.Equals, registered)
		for _, alias := range aliases {
			p, err := environs.Provider(alias)
			c.Assert(err, gc.IsNil)
			c.Assert(p, gc.Equals, registered)
			c.Assert(p, gc.Equals, registered)
		}
		return nil
	}
	for i, test := range tests {
		c.Logf("test %d: %v", i, test)
		for k := range *environs.Providers {
			delete(*environs.Providers, k)
		}
		for k := range *environs.ProviderAliases {
			delete(*environs.ProviderAliases, k)
		}
		for _, step := range test {
			err := registerProvider(step.name, step.aliases)
			if step.err == "" {
				c.Assert(err, gc.IsNil)
			} else {
				c.Assert(err, gc.ErrorMatches, step.err)
			}
		}
	}
}
示例#7
0
func (*localSuite) TestProviderRegistered(c *gc.C) {
	provider, error := environs.Provider(provider.Local)
	c.Assert(error, gc.IsNil)
	c.Assert(provider, gc.DeepEquals, local.Provider)
}
示例#8
0
func (s *prepareSuite) TestPrepareCapturesEnvironment(c *gc.C) {
	baseConfig, err := config.New(config.UseDefaults, map[string]interface{}{
		"type": provider.Local,
		"name": "test",
	})
	c.Assert(err, gc.IsNil)
	provider, err := environs.Provider(provider.Local)
	c.Assert(err, gc.IsNil)

	for i, test := range []struct {
		message          string
		extraConfig      map[string]interface{}
		env              map[string]string
		aptOutput        string
		expectedProxy    osenv.ProxySettings
		expectedAptProxy osenv.ProxySettings
	}{{
		message: "nothing set",
	}, {
		message: "grabs proxy from environment",
		env: map[string]string{
			"http_proxy":  "http://[email protected]",
			"HTTPS_PROXY": "https://[email protected]",
			"ftp_proxy":   "ftp://[email protected]",
			"no_proxy":    "localhost,10.0.3.1",
		},
		expectedProxy: osenv.ProxySettings{
			Http:    "http://[email protected]",
			Https:   "https://[email protected]",
			Ftp:     "ftp://[email protected]",
			NoProxy: "localhost,10.0.3.1",
		},
		expectedAptProxy: osenv.ProxySettings{
			Http:  "http://[email protected]",
			Https: "https://[email protected]",
			Ftp:   "ftp://[email protected]",
		},
	}, {
		message: "skips proxy from environment if http-proxy set",
		extraConfig: map[string]interface{}{
			"http-proxy": "http://[email protected]",
		},
		env: map[string]string{
			"http_proxy":  "http://[email protected]",
			"HTTPS_PROXY": "https://[email protected]",
			"ftp_proxy":   "ftp://[email protected]",
		},
		expectedProxy: osenv.ProxySettings{
			Http: "http://[email protected]",
		},
		expectedAptProxy: osenv.ProxySettings{
			Http: "http://[email protected]",
		},
	}, {
		message: "skips proxy from environment if https-proxy set",
		extraConfig: map[string]interface{}{
			"https-proxy": "https://[email protected]",
		},
		env: map[string]string{
			"http_proxy":  "http://[email protected]",
			"HTTPS_PROXY": "https://[email protected]",
			"ftp_proxy":   "ftp://[email protected]",
		},
		expectedProxy: osenv.ProxySettings{
			Https: "https://[email protected]",
		},
		expectedAptProxy: osenv.ProxySettings{
			Https: "https://[email protected]",
		},
	}, {
		message: "skips proxy from environment if ftp-proxy set",
		extraConfig: map[string]interface{}{
			"ftp-proxy": "ftp://[email protected]",
		},
		env: map[string]string{
			"http_proxy":  "http://[email protected]",
			"HTTPS_PROXY": "https://[email protected]",
			"ftp_proxy":   "ftp://[email protected]",
		},
		expectedProxy: osenv.ProxySettings{
			Ftp: "ftp://[email protected]",
		},
		expectedAptProxy: osenv.ProxySettings{
			Ftp: "ftp://[email protected]",
		},
	}, {
		message: "skips proxy from environment if no-proxy set",
		extraConfig: map[string]interface{}{
			"no-proxy": "localhost,10.0.3.1",
		},
		env: map[string]string{
			"http_proxy":  "http://[email protected]",
			"HTTPS_PROXY": "https://[email protected]",
			"ftp_proxy":   "ftp://[email protected]",
		},
		expectedProxy: osenv.ProxySettings{
			NoProxy: "localhost,10.0.3.1",
		},
	}, {
		message: "apt-proxies detected",
		aptOutput: `CommandLine::AsString "apt-config dump";
Acquire::http::Proxy  "10.0.3.1:3142";
Acquire::https::Proxy "false";
Acquire::ftp::Proxy "none";
Acquire::magic::Proxy "none";
`,
		expectedAptProxy: osenv.ProxySettings{
			Http:  "10.0.3.1:3142",
			Https: "false",
			Ftp:   "none",
		},
	}, {
		message: "apt-proxies not used if apt-http-proxy set",
		extraConfig: map[string]interface{}{
			"apt-http-proxy": "value-set",
		},
		aptOutput: `CommandLine::AsString "apt-config dump";
Acquire::http::Proxy  "10.0.3.1:3142";
Acquire::https::Proxy "false";
Acquire::ftp::Proxy "none";
Acquire::magic::Proxy "none";
`,
		expectedAptProxy: osenv.ProxySettings{
			Http: "value-set",
		},
	}, {
		message: "apt-proxies not used if apt-https-proxy set",
		extraConfig: map[string]interface{}{
			"apt-https-proxy": "value-set",
		},
		aptOutput: `CommandLine::AsString "apt-config dump";
Acquire::http::Proxy  "10.0.3.1:3142";
Acquire::https::Proxy "false";
Acquire::ftp::Proxy "none";
Acquire::magic::Proxy "none";
`,
		expectedAptProxy: osenv.ProxySettings{
			Https: "value-set",
		},
	}, {
		message: "apt-proxies not used if apt-ftp-proxy set",
		extraConfig: map[string]interface{}{
			"apt-ftp-proxy": "value-set",
		},
		aptOutput: `CommandLine::AsString "apt-config dump";
Acquire::http::Proxy  "10.0.3.1:3142";
Acquire::https::Proxy "false";
Acquire::ftp::Proxy "none";
Acquire::magic::Proxy "none";
`,
		expectedAptProxy: osenv.ProxySettings{
			Ftp: "value-set",
		},
	}} {
		c.Logf("\n%v: %s", i, test.message)
		cleanup := []func(){}
		for key, value := range test.env {
			restore := testing.PatchEnvironment(key, value)
			cleanup = append(cleanup, restore)
		}
		_, restore := testing.HookCommandOutput(&utils.AptCommandOutput, []byte(test.aptOutput), nil)
		cleanup = append(cleanup, restore)
		testConfig := baseConfig
		if test.extraConfig != nil {
			testConfig, err = baseConfig.Apply(test.extraConfig)
			c.Assert(err, gc.IsNil)
		}
		env, err := provider.Prepare(coretesting.Context(c), testConfig)
		c.Assert(err, gc.IsNil)

		envConfig := env.Config()
		c.Assert(envConfig.HttpProxy(), gc.Equals, test.expectedProxy.Http)
		c.Assert(envConfig.HttpsProxy(), gc.Equals, test.expectedProxy.Https)
		c.Assert(envConfig.FtpProxy(), gc.Equals, test.expectedProxy.Ftp)
		c.Assert(envConfig.NoProxy(), gc.Equals, test.expectedProxy.NoProxy)

		c.Assert(envConfig.AptHttpProxy(), gc.Equals, test.expectedAptProxy.Http)
		c.Assert(envConfig.AptHttpsProxy(), gc.Equals, test.expectedAptProxy.Https)
		c.Assert(envConfig.AptFtpProxy(), gc.Equals, test.expectedAptProxy.Ftp)

		for _, clean := range cleanup {
			clean()
		}
	}
}
示例#9
0
func (s *prepareSuite) TestFastLXCClone(c *gc.C) {
	s.PatchValue(local.DetectAptProxies, func() (osenv.ProxySettings, error) {
		return osenv.ProxySettings{}, nil
	})
	s.PatchValue(&kvm.IsKVMSupported, func() (bool, error) {
		return true, nil
	})
	s.PatchValue(&local.VerifyPrerequisites, func(containerType instance.ContainerType) error {
		return nil
	})
	basecfg, err := config.New(config.UseDefaults, map[string]interface{}{
		"type": "local",
		"name": "test",
	})
	provider, err := environs.Provider("local")
	c.Assert(err, gc.IsNil)

	type test struct {
		systemDefault bool
		extraConfig   map[string]interface{}
		expectClone   bool
		expectAUFS    bool
	}
	tests := []test{{
		extraConfig: map[string]interface{}{
			"container": "lxc",
		},
	}, {
		extraConfig: map[string]interface{}{
			"container": "lxc",
			"lxc-clone": "true",
		},
		expectClone: true,
	}, {
		systemDefault: true,
		extraConfig: map[string]interface{}{
			"container": "lxc",
		},
		expectClone: true,
	}, {
		systemDefault: true,
		extraConfig: map[string]interface{}{
			"container": "kvm",
		},
	}, {
		systemDefault: true,
		extraConfig: map[string]interface{}{
			"container": "lxc",
			"lxc-clone": false,
		},
	}, {
		systemDefault: true,
		extraConfig: map[string]interface{}{
			"container":      "lxc",
			"lxc-clone-aufs": true,
		},
		expectClone: true,
		expectAUFS:  true,
	}}

	for i, test := range tests {
		c.Logf("test %d: %v", i, test)

		releaseVersion := "12.04"
		if test.systemDefault {
			releaseVersion = "14.04"
		}
		s.PatchValue(local.ReleaseVersion, func() string { return releaseVersion })
		testConfig, err := basecfg.Apply(test.extraConfig)
		c.Assert(err, gc.IsNil)
		env, err := provider.Open(testConfig)
		c.Assert(err, gc.IsNil)
		localAttributes := env.Config().UnknownAttrs()

		value, _ := localAttributes["lxc-clone"].(bool)
		c.Assert(value, gc.Equals, test.expectClone)
		value, _ = localAttributes["lxc-clone-aufs"].(bool)
		c.Assert(value, gc.Equals, test.expectAUFS)
	}
}
示例#10
0
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 := environs.PrepareFromName(c.EnvName, 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),
		}
	}

	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
}
示例#11
0
func (c *ValidateImageMetadataCommand) Run(context *cmd.Context) error {
	var params *simplestreams.MetadataLookupParams

	if c.providerType == "" {
		store, err := configstore.Default()
		if err != nil {
			return err
		}
		environ, err := environs.PrepareFromName(c.EnvName, context, store)
		if err != nil {
			return err
		}
		mdLookup, ok := environ.(simplestreams.MetadataValidator)
		if !ok {
			return fmt.Errorf("%s provider does not support image metadata validation", environ.Config().Type())
		}
		params, err = mdLookup.MetadataLookupParams(c.region)
		if err != nil {
			return err
		}
		oes := &overrideEnvStream{environ, c.stream}
		params.Sources, err = imagemetadata.GetMetadataSources(oes)
		if err != nil {
			return err
		}
	} 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 image 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 != "" {
		dir := filepath.Join(c.metadataDir, "images")
		if _, err := os.Stat(dir); err != nil {
			return err
		}
		params.Sources = []simplestreams.DataSource{
			simplestreams.NewURLDataSource(
				"local metadata directory", "file://"+dir, utils.VerifySSLHostnames),
		}
	}
	params.Stream = c.stream

	image_ids, resolveInfo, err := imagemetadata.ValidateImageMetadata(params)
	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(image_ids) > 0 {
		metadata := map[string]interface{}{
			"ImageIds":         image_ids,
			"Region":           params.Region,
			"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 image ids for region %s using sources:\n%s",
			params.Region, strings.Join(sources, "\n"))
	}
	return nil
}