func (s *syncToolsSuite) SetUpTest(c *C) { s.LoggingSuite.SetUpTest(c) s.origVersion = version.Current // It's important that this be v1 to match the test data. version.Current.Number = version.MustParse("1.2.3") // Create a target environments.yaml and make sure its environment is empty. s.home = testing.MakeFakeHome(c, ` environments: test-target: type: dummy state-server: false authorized-keys: "not-really-one" `) var err error s.targetEnv, err = environs.NewFromName("test-target") c.Assert(err, IsNil) envtesting.RemoveAllTools(c, s.targetEnv) // Create a source storage. s.storage, err = envtesting.NewEC2HTTPTestStorage("127.0.0.1") c.Assert(err, IsNil) // Create a local tools directory. s.localStorage = c.MkDir() // Populate both with the public tools. for _, vers := range vAll { s.storage.PutBinary(vers) putBinary(c, s.localStorage, vers) } s.origLocation = defaultToolsLocation defaultToolsLocation = s.storage.Location() }
// NewConnFromName returns a Conn pointing at the environName environment, or the // default environment if not specified. func NewConnFromName(environName string) (*Conn, error) { environ, err := environs.NewFromName(environName) if err != nil { return nil, err } return NewConn(environ) }
func (c *DestroyEnvironmentCommand) Run(_ *cmd.Context) error { environ, err := environs.NewFromName(c.EnvName) if err != nil { return err } return environ.Destroy(nil) }
// Run connects to the environment specified on the command line and bootstraps // a juju in that environment if none already exists. func (c *BootstrapCommand) Run(_ *cmd.Context) error { environ, err := environs.NewFromName(c.EnvName) if err != nil { return err } return environs.Bootstrap(environ, c.UploadTools, nil) }
func (OpenSuite) TestNewFromNameGetDefault(c *C) { defer testing.MakeFakeHome(c, testing.SingleEnvConfig, testing.SampleCertName).Restore() e, err := environs.NewFromName("") c.Assert(err, IsNil) c.Assert(e.Name(), Equals, "erewhemos") }
func build() error { environ, err := environs.NewFromName("") if err != nil { return err } err = environs.Bootstrap(environ, true, nil) if err != nil { return err } conn, err := juju.NewConn(environ) if err != nil { return err } repo := &charm.LocalRepository{filepath.Dir(os.Args[0])} curl := charm.MustParseURL("local:precise/builddb") ch, err := conn.PutCharm(curl, repo, false) if err != nil { return err } service, err := conn.AddService("builddb", ch) if err != nil { return err } if err := service.SetExposed(); err != nil { return err } units, err := conn.AddUnits(service, 1) if err != nil { return err } log.Printf("builddb: Waiting for unit to reach %q status...", state.UnitStarted) unit := units[0] last, info, err := unit.Status() if err != nil { return err } logStatus(last, info) for last != state.UnitStarted { time.Sleep(2 * time.Second) if err := unit.Refresh(); err != nil { return err } status, info, err := unit.Status() if err != nil { return err } if status != last { logStatus(status, info) last = status } } addr, ok := unit.PublicAddress() if !ok { return fmt.Errorf("cannot retrieve files: build unit lacks a public-address") } log.Printf("builddb: Built files published at http://%s", addr) log.Printf("builddb: Remember to destroy the environment when you're done...") return nil }
// makeEmptyFakeHome creates a faked home without tools. func makeEmptyFakeHome(c *gc.C) (environs.Environ, *coretesting.FakeHome) { fake := coretesting.MakeFakeHome(c, envConfig) dummy.Reset() env, err := environs.NewFromName("peckham") c.Assert(err, gc.IsNil) envtesting.RemoveAllTools(c, env) return env, fake }
func (*NewConnSuite) TestNewConnFromName(c *C) { home := c.MkDir() defer os.Setenv("HOME", os.Getenv("HOME")) os.Setenv("HOME", home) conn, err := juju.NewConnFromName("") c.Assert(conn, IsNil) c.Assert(err, ErrorMatches, ".*: no such file or directory") if err := os.Mkdir(filepath.Join(home, ".juju"), 0755); err != nil { c.Fatal("Could not create directory structure") } envs := filepath.Join(home, ".juju", "environments.yaml") err = ioutil.WriteFile(envs, []byte(` default: erewhemos environments: erewhemos: type: dummy state-server: true authorized-keys: i-am-a-key admin-secret: conn-from-name-secret `), 0644) err = ioutil.WriteFile(filepath.Join(home, ".juju", "erewhemos-cert.pem"), []byte(coretesting.CACert), 0600) c.Assert(err, IsNil) err = ioutil.WriteFile(filepath.Join(home, ".juju", "erewhemos-private-key.pem"), []byte(coretesting.CAKey), 0600) c.Assert(err, IsNil) // Just run through a few operations on the dummy provider and verify that // they behave as expected. conn, err = juju.NewConnFromName("") c.Assert(err, ErrorMatches, "dummy environment not bootstrapped") environ, err := environs.NewFromName("") c.Assert(err, IsNil) err = environs.Bootstrap(environ, false, panicWrite) c.Assert(err, IsNil) conn, err = juju.NewConnFromName("") c.Assert(err, IsNil) defer conn.Close() c.Assert(conn.Environ, NotNil) c.Assert(conn.Environ.Name(), Equals, "erewhemos") c.Assert(conn.State, NotNil) // Reset the admin password so the state db can be reused. err = conn.State.SetAdminMongoPassword("") c.Assert(err, IsNil) // Close the conn (thereby closing its state) a couple of times to // verify that multiple closes will not panic. We ignore the error, // as the underlying State will return an error the second // time. conn.Close() conn.Close() }
func (s *verifyStorageSuite) TestVerifyStorageFails(c *C) { defer testing.MakeFakeHome(c, existingEnv, "existing").Restore() environ, err := environs.NewFromName("test") c.Assert(err, IsNil) storage := environ.Storage() someError := errors.Unauthorizedf("you shall not pass") dummy.Poison(storage, "bootstrap-verify", someError) err = environs.VerifyStorage(storage) c.Assert(err, Equals, environs.VerifyStorageError) }
func (*EnvironsCertSuite) TestEnsureCertificate(c *C) { defer testing.MakeFakeHome(c, testing.SingleEnvConfig).Restore() env, err := environs.NewFromName(testing.SampleEnvName) c.Assert(err, IsNil) writeCalled := false created, err := environs.EnsureCertificate(env, func(name string, cert, key []byte) error { writeCalled = true return nil }) c.Assert(err, IsNil) c.Assert(created, Equals, environs.CertCreated) c.Assert(writeCalled, Equals, true) }
func (s *checkEnvironmentSuite) TestCheckEnvironment(c *C) { defer testing.MakeFakeHome(c, checkEnv, "existing").Restore() environ, err := environs.NewFromName("test") c.Assert(err, IsNil) // VerifyStorage is sufficient for our tests and much simpler // than Bootstrap which calls it. storage := environ.Storage() err = environs.VerifyStorage(storage) c.Assert(err, IsNil) err = environs.CheckEnvironment(environ) c.Assert(err, IsNil) }
// Run connects to the environment specified on the command line and bootstraps // a juju in that environment if none already exists. If there is as yet no environments.yaml file, // the user is informed how to create one. func (c *BootstrapCommand) Run(context *cmd.Context) error { environ, err := environs.NewFromName(c.EnvName) if err != nil { if os.IsNotExist(err) { out := context.Stderr fmt.Fprintln(out, "No juju environment configuration file exists.") fmt.Fprintln(out, "Please create a configuration by running:") fmt.Fprintln(out, " juju init -w") fmt.Fprintln(out, "then edit the file to configure your juju environment.") fmt.Fprintln(out, "You can then re-run bootstrap.") } return err } // TODO: if in verbose mode, write out to Stdout if a new cert was created. _, err = environs.EnsureCertificate(environ, environs.WriteCertAndKey) if err != nil { return err } // If we are using a local provider, always upload tools. if environ.Config().Type() == provider.Local { c.UploadTools = true } if c.UploadTools { // Force version.Current, for consistency with subsequent upgrade-juju // (see UpgradeJujuCommand). forceVersion := uploadVersion(version.Current.Number, nil) cfg := environ.Config() series := getUploadSeries(cfg, c.Series) tools, err := uploadTools(environ.Storage(), &forceVersion, series...) if err != nil { return err } cfg, err = cfg.Apply(map[string]interface{}{ "agent-version": tools.Version.Number.String(), }) if err == nil { err = environ.SetConfig(cfg) } if err != nil { return fmt.Errorf("failed to update environment configuration: %v", err) } } err = c.ensureToolsAvailability(environ, context) if err != nil { return err } return environs.Bootstrap(environ, c.Constraints) }
func (s *verifyStorageSuite) TestVerifyStorage(c *C) { defer testing.MakeFakeHome(c, existingEnv, "existing").Restore() environ, err := environs.NewFromName("test") c.Assert(err, IsNil) storage := environ.Storage() err = environs.VerifyStorage(storage) c.Assert(err, IsNil) reader, err := storage.Get("bootstrap-verify") c.Assert(err, IsNil) defer reader.Close() contents, err := ioutil.ReadAll(reader) c.Assert(err, IsNil) c.Check(string(contents), Equals, "juju-core storage writing verified: ok\n") }
func (s *syncToolsSuite) SetUpTest(c *gc.C) { s.LoggingSuite.SetUpTest(c) // Create a target environments.yaml and make sure its environment is empty. s.home = coretesting.MakeFakeHome(c, ` environments: test-target: type: dummy state-server: false authorized-keys: "not-really-one" `) var err error s.targetEnv, err = environs.NewFromName("test-target") c.Assert(err, gc.IsNil) envtesting.RemoveAllTools(c, s.targetEnv) s.origSyncTools = syncTools }
func (c *DestroyEnvironmentCommand) Run(ctx *cmd.Context) error { environ, err := environs.NewFromName(c.EnvName) if err != nil { return err } if !c.assumeYes { var answer string fmt.Fprintf(ctx.Stdout, destroyEnvMsg[1:], environ.Name(), environ.Config().Type()) fmt.Fscanln(ctx.Stdin, &answer) // ignore error, treat as "n" answer = strings.ToLower(answer) if answer != "y" && answer != "yes" { return errors.New("Environment destruction aborted") } } return environ.Destroy(nil) }
func (s *checkEnvironmentSuite) TestCheckEnvironmentBadContent(c *C) { defer testing.MakeFakeHome(c, checkEnv, "existing").Restore() environ, err := environs.NewFromName("test") c.Assert(err, IsNil) // We mock a bad (eg. from a Python-juju environment) bootstrap-verify. storage := environ.Storage() content := "bad verification content" reader := strings.NewReader(content) err = storage.Put("bootstrap-verify", reader, int64(len(content))) c.Assert(err, IsNil) // When the bootstrap-verify file contains unexpected content, // we get an InvalidEnvironmentError. err = environs.CheckEnvironment(environ) c.Assert(err, Equals, environs.InvalidEnvironmentError) }
func (s *JujuConnSuite) setUpConn(c *C) { if s.RootDir != "" { panic("JujuConnSuite.setUpConn without teardown") } s.RootDir = c.MkDir() s.oldHome = os.Getenv("HOME") home := filepath.Join(s.RootDir, "/home/ubuntu") err := os.MkdirAll(home, 0777) c.Assert(err, IsNil) os.Setenv("HOME", home) dataDir := filepath.Join(s.RootDir, "/var/lib/juju") err = os.MkdirAll(dataDir, 0777) c.Assert(err, IsNil) yaml := []byte(fmt.Sprintf(envConfig, version.Current.Number)) err = ioutil.WriteFile(config.JujuHomePath("environments.yaml"), yaml, 0600) c.Assert(err, IsNil) err = ioutil.WriteFile(config.JujuHomePath("dummyenv-cert.pem"), []byte(testing.CACert), 0666) c.Assert(err, IsNil) err = ioutil.WriteFile(config.JujuHomePath("dummyenv-private-key.pem"), []byte(testing.CAKey), 0600) c.Assert(err, IsNil) environ, err := environs.NewFromName("dummyenv") c.Assert(err, IsNil) // sanity check we've got the correct environment. c.Assert(environ.Name(), Equals, "dummyenv") c.Assert(environs.Bootstrap(environ, constraints.Value{}), IsNil) s.BackingState = environ.(GetStater).GetStateInAPIServer() conn, err := juju.NewConn(environ) c.Assert(err, IsNil) s.Conn = conn s.State = conn.State apiConn, err := juju.NewAPIConn(environ, api.DialOpts{}) c.Assert(err, IsNil) s.APIConn = apiConn s.APIState = apiConn.State s.environ = environ }
func (s *checkEnvironmentSuite) TestCheckEnvironmentGetFails(c *C) { defer testing.MakeFakeHome(c, checkEnv, "existing").Restore() environ, err := environs.NewFromName("test") c.Assert(err, IsNil) // VerifyStorage is sufficient for our tests and much simpler // than Bootstrap which calls it. storage := environ.Storage() err = environs.VerifyStorage(storage) c.Assert(err, IsNil) // When fetching the verification file from storage fails, // we get an InvalidEnvironmentError. someError := errors.Unauthorizedf("you shall not pass") dummy.Poison(storage, "bootstrap-verify", someError) err = environs.CheckEnvironment(environ) c.Assert(err, Equals, someError) }
func (*EnvironsCertSuite) TestEnsureCertificateMissingKey(c *C) { defer testing.MakeFakeHome(c, testing.SingleEnvConfig).Restore() envName := testing.SampleEnvName keyPath := testing.HomePath(".juju", envName+"-cert.pem") ioutil.WriteFile(keyPath, []byte(testing.CACert), 0600) // Need to create the environment after the cert has been written. env, err := environs.NewFromName(envName) c.Assert(err, IsNil) writeCalled := false _, err = environs.EnsureCertificate(env, func(name string, cert, key []byte) error { writeCalled = true return nil }) c.Assert(err, ErrorMatches, "environment configuration with a certificate but no CA private key") c.Assert(writeCalled, Equals, false) }
func (s *checkEnvironmentSuite) TestCheckEnvironmentFileNotFound(c *C) { defer testing.MakeFakeHome(c, checkEnv, "existing").Restore() environ, err := environs.NewFromName("test") c.Assert(err, IsNil) // VerifyStorage is sufficient for our tests and much simpler // than Bootstrap which calls it. storage := environ.Storage() err = environs.VerifyStorage(storage) c.Assert(err, IsNil) // When the bootstrap-verify file does not exist, it still believes // the environment is a juju-core one because earlier versions // did not create that file. err = storage.Remove("bootstrap-verify") c.Assert(err, IsNil) err = environs.CheckEnvironment(environ) c.Assert(err, IsNil) }
func (s *JujuConnSuite) setUpConn(c *C) { if s.RootDir != "" { panic("JujuConnSuite.setUpConn without teardown") } s.RootDir = c.MkDir() s.oldHome = os.Getenv("HOME") home := filepath.Join(s.RootDir, "/home/ubuntu") err := os.MkdirAll(home, 0777) c.Assert(err, IsNil) os.Setenv("HOME", home) dataDir := filepath.Join(s.RootDir, "/var/lib/juju") err = os.MkdirAll(dataDir, 0777) c.Assert(err, IsNil) err = os.Mkdir(filepath.Join(home, ".juju"), 0777) c.Assert(err, IsNil) err = ioutil.WriteFile(filepath.Join(home, ".juju", "environments.yaml"), config, 0600) c.Assert(err, IsNil) err = ioutil.WriteFile(filepath.Join(home, ".juju", "dummyenv-cert.pem"), []byte(testing.CACert), 0666) c.Assert(err, IsNil) err = ioutil.WriteFile(filepath.Join(home, ".juju", "dummyenv-private-key.pem"), []byte(testing.CAKey), 0600) c.Assert(err, IsNil) environ, err := environs.NewFromName("dummyenv") c.Assert(err, IsNil) // sanity check we've got the correct environment. c.Assert(environ.Name(), Equals, "dummyenv") c.Assert(environs.Bootstrap(environ, false, panicWrite), IsNil) conn, err := juju.NewConnFromName("dummyenv") c.Assert(err, IsNil) s.Conn = conn s.State = conn.State c.Assert(err, IsNil) }
func (c *SyncToolsCommand) Run(ctx *cmd.Context) error { sourceStorage, err := selectSourceStorage(c.source) if err != nil { log.Errorf("unable to select source: %v", err) return err } targetEnv, err := environs.NewFromName(c.EnvName) if err != nil { log.Errorf("unable to read %q from environment", c.EnvName) return err } fmt.Fprintf(ctx.Stderr, "listing the source bucket\n") majorVersion := version.Current.Major sourceTools, err := tools.ReadList(sourceStorage, majorVersion) if err != nil { return err } if !c.dev { filter := tools.Filter{Released: true} if sourceTools, err = sourceTools.Match(filter); err != nil { return err } } fmt.Fprintf(ctx.Stderr, "found %d tools\n", len(sourceTools)) if !c.allVersions { var latest version.Number latest, sourceTools = sourceTools.Newest() fmt.Fprintf(ctx.Stderr, "found %d recent tools (version %s)\n", len(sourceTools), latest) } for _, tool := range sourceTools { log.Debugf("found source tool: %s", tool) } fmt.Fprintf(ctx.Stderr, "listing target bucket\n") targetStorage := targetEnv.Storage() if c.publicBucket { switch _, err := tools.ReadList(targetStorage, majorVersion); err { case tools.ErrNoTools: case nil, tools.ErrNoMatches: return fmt.Errorf("private tools present: public tools would be ignored") default: return err } var ok bool if targetStorage, ok = targetEnv.PublicStorage().(environs.Storage); !ok { return fmt.Errorf("cannot write to public storage") } } targetTools, err := tools.ReadList(targetStorage, majorVersion) switch err { case nil, tools.ErrNoMatches, tools.ErrNoTools: default: return err } for _, tool := range targetTools { log.Debugf("found target tool: %s", tool) } missing := sourceTools.Exclude(targetTools) fmt.Fprintf(ctx.Stdout, "found %d tools in target; %d tools to be copied\n", len(targetTools), len(missing)) err = copyTools(missing, sourceStorage, targetStorage, c.dryRun, ctx) if err != nil { return err } fmt.Fprintf(ctx.Stderr, "copied %d tools\n", len(missing)) return nil }
func bootstrapEnv(c *C, envName string) { environ, err := environs.NewFromName(envName) c.Assert(err, IsNil) err = environs.Bootstrap(environ, constraints.Value{}) c.Assert(err, IsNil) }
// SyncTools copies the Juju tools tarball from the official bucket // or a specified source directory into the user's environment. func SyncTools(ctx *SyncContext) error { var err error ctx.sourceStorage, err = selectSourceStorage(ctx) if err != nil { return fmt.Errorf("unable to select source: %v", err) } targetEnv, err := environs.NewFromName(ctx.EnvName) if err != nil { return fmt.Errorf("unable to read %q from environment", ctx.EnvName) } logger.Infof("listing available tools") majorVersion := version.Current.Major sourceTools, err := tools.ReadList(ctx.sourceStorage, majorVersion) if err != nil { return err } if !ctx.Dev { // No development versions, only released ones. filter := tools.Filter{Released: true} if sourceTools, err = sourceTools.Match(filter); err != nil { return err } } logger.Infof("found %d tools", len(sourceTools)) if !ctx.AllVersions { var latest version.Number latest, sourceTools = sourceTools.Newest() logger.Infof("found %d recent tools (version %s)", len(sourceTools), latest) } for _, tool := range sourceTools { logger.Debugf("found source tool: %s", tool) } logger.Infof("listing target bucket") ctx.targetStorage = targetEnv.Storage() if ctx.PublicBucket { switch _, err := tools.ReadList(ctx.targetStorage, majorVersion); err { case tools.ErrNoTools: case nil, tools.ErrNoMatches: return fmt.Errorf("private tools present: public tools would be ignored") default: return err } var ok bool if ctx.targetStorage, ok = targetEnv.PublicStorage().(environs.Storage); !ok { return fmt.Errorf("cannot write to public storage") } } targetTools, err := tools.ReadList(ctx.targetStorage, majorVersion) switch err { case nil, tools.ErrNoMatches, tools.ErrNoTools: default: return err } for _, tool := range targetTools { logger.Debugf("found target tool: %s", tool) } missing := sourceTools.Exclude(targetTools) logger.Infof("found %d tools in target; %d tools to be copied", len(targetTools), len(missing)) err = copyTools(missing, ctx) if err != nil { return err } logger.Infof("copied %d tools", len(missing)) return nil }
func (test bootstrapTest) run(c *C) { defer testing.MakeFakeHome(c, envConfig).Restore() dummy.Reset() env, err := environs.NewFromName("peckham") c.Assert(err, IsNil) envtesting.RemoveAllTools(c, env) if test.version != "" { origVersion := version.Current version.Current = version.MustParseBinary(test.version) defer func() { version.Current = origVersion }() } uploadCount := len(test.uploads) if uploadCount == 0 { usefulVersion := version.Current usefulVersion.Series = env.Config().DefaultSeries() envtesting.UploadFakeToolsVersion(c, env.Storage(), usefulVersion) } // Run command and check for uploads. opc, errc := runCommand(new(BootstrapCommand), test.args...) if uploadCount > 0 { for i := 0; i < uploadCount; i++ { c.Check((<-opc).(dummy.OpPutFile).Env, Equals, "peckham") } list, err := environs.FindAvailableTools(env, version.Current.Major) c.Check(err, IsNil) c.Logf("found: " + list.String()) urls := list.URLs() c.Check(urls, HasLen, len(test.uploads)) for _, v := range test.uploads { c.Logf("seeking: " + v) vers := version.MustParseBinary(v) _, found := urls[vers] c.Check(found, Equals, true) } } // Check for remaining operations/errors. if test.err != "" { c.Check(<-errc, ErrorMatches, test.err) return } if !c.Check(<-errc, IsNil) { return } opPutBootstrapVerifyFile := (<-opc).(dummy.OpPutFile) c.Check(opPutBootstrapVerifyFile.Env, Equals, "peckham") c.Check(opPutBootstrapVerifyFile.FileName, Equals, "bootstrap-verify") opBootstrap := (<-opc).(dummy.OpBootstrap) c.Check(opBootstrap.Env, Equals, "peckham") c.Check(opBootstrap.Constraints, DeepEquals, test.constraints) // Check a CA cert/key was generated by reloading the environment. env, err = environs.NewFromName("peckham") c.Assert(err, IsNil) _, hasCert := env.Config().CACert() c.Check(hasCert, Equals, true) _, hasKey := env.Config().CAPrivateKey() c.Check(hasKey, Equals, true) }
func (c *ValidateImageMetadataCommand) Run(context *cmd.Context) error { var params *imagemetadata.MetadataLookupParams if c.providerType == "" { environ, err := environs.NewFromName(c.EnvName) if err != nil { return err } mdLookup, ok := environ.(imagemetadata.ImageMetadataValidator) 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 } } else { prov, err := environs.Provider(c.providerType) if err != nil { return err } mdLookup, ok := prov.(imagemetadata.ImageMetadataValidator) 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 the metadata files are to be loaded from a directory, we need to register // a file http transport. if c.metadataDir != "" { if _, err := os.Stat(c.metadataDir); err != nil { return err } params.BaseURLs = []string{"file://" + c.metadataDir} t := &http.Transport{} t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/"))) c := &http.Client{Transport: t} imagemetadata.SetHttpClient(c) } image_ids, err := imagemetadata.ValidateImageMetadata(params) if err != nil { return err } if len(image_ids) > 0 { fmt.Fprintf(context.Stdout, "matching image ids for region %q:\n%s\n", params.Region, strings.Join(image_ids, "\n")) } else { return fmt.Errorf("no matching image ids for region %s using URLs:\n%s", params.Region, strings.Join(params.BaseURLs, "\n")) } return nil }
func (OpenSuite) TestNewFromNameNoDefault(c *C) { defer testing.MakeFakeHome(c, testing.MultipleEnvConfigNoDefault, testing.SampleCertName).Restore() _, err := environs.NewFromName("") c.Assert(err, ErrorMatches, "no default environment found") }