func (c *DestroyEnvironmentCommand) Run(ctx *cmd.Context) (result error) { store, err := configstore.Default() if err != nil { return fmt.Errorf("cannot open environment info storage: %v", err) } environ, err := environs.NewFromName(c.envName, store) if err != nil { if environs.IsEmptyConfig(err) { // Delete the .jenv file and call it done. ctx.Infof("removing empty environment file") return environs.DestroyInfo(c.envName, store) } return err } if !c.assumeYes { fmt.Fprintf(ctx.Stdout, destroyEnvMsg, environ.Name(), environ.Config().Type()) scanner := bufio.NewScanner(ctx.Stdin) scanner.Scan() err := scanner.Err() if err != nil && err != io.EOF { return fmt.Errorf("Environment destruction aborted: %s", err) } answer := strings.ToLower(scanner.Text()) if answer != "y" && answer != "yes" { return errors.New("environment destruction aborted") } } // If --force is supplied, then don't attempt to use the API. // This is necessary to destroy broken environments, where the // API server is inaccessible or faulty. if !c.force { defer func() { if result == nil { return } logger.Errorf(`failed to destroy environment %q If the environment is unusable, then you may run juju destroy-environment --force to forcefully destroy the environment. Upon doing so, review your environment provider console for any resources that need to be cleaned up. `, c.envName) }() apiclient, err := juju.NewAPIClientFromName(c.envName) if err != nil { return fmt.Errorf("cannot connect to API: %v", err) } defer apiclient.Close() err = apiclient.DestroyEnvironment() if err != nil && !params.IsCodeNotImplemented(err) { return fmt.Errorf("destroying environment: %v", err) } } return environs.Destroy(environ, store) }
func (t *LiveTests) Destroy(c *gc.C) { if t.Env == nil { return } err := environs.Destroy(t.Env, t.ConfigStore) c.Assert(err, gc.IsNil) t.bootstrapped = false t.prepared = false t.Env = nil }
func (t *Tests) TestBootstrap(c *gc.C) { e := t.Prepare(c) t.UploadFakeTools(c, e.Storage()) err := bootstrap.EnsureNotBootstrapped(e) c.Assert(err, gc.IsNil) err = bootstrap.Bootstrap(coretesting.Context(c), e, environs.BootstrapParams{}) c.Assert(err, gc.IsNil) info, apiInfo, err := e.StateInfo() c.Check(info.Addrs, gc.Not(gc.HasLen), 0) c.Check(apiInfo.Addrs, gc.Not(gc.HasLen), 0) err = bootstrap.EnsureNotBootstrapped(e) c.Assert(err, gc.ErrorMatches, "environment is already bootstrapped") e2 := t.Open(c) t.UploadFakeTools(c, e2.Storage()) err = bootstrap.EnsureNotBootstrapped(e2) c.Assert(err, gc.ErrorMatches, "environment is already bootstrapped") info2, apiInfo2, err := e2.StateInfo() c.Check(info2, gc.DeepEquals, info) c.Check(apiInfo2, gc.DeepEquals, apiInfo) err = environs.Destroy(e2, t.ConfigStore) c.Assert(err, gc.IsNil) // Prepare again because Destroy invalidates old environments. e3 := t.Prepare(c) t.UploadFakeTools(c, e3.Storage()) err = bootstrap.EnsureNotBootstrapped(e3) c.Assert(err, gc.IsNil) err = bootstrap.Bootstrap(coretesting.Context(c), e3, environs.BootstrapParams{}) c.Assert(err, gc.IsNil) err = bootstrap.EnsureNotBootstrapped(e3) c.Assert(err, gc.ErrorMatches, "environment is already bootstrapped") }
func (t *LiveTests) TestBootstrapWithDefaultSeries(c *gc.C) { if !t.HasProvisioner { c.Skip("HasProvisioner is false; cannot test deployment") } current := version.Current other := current other.Series = "quantal" if current == other { other.Series = "precise" } dummyCfg, err := config.New(config.NoDefaults, dummy.SampleConfig().Merge(coretesting.Attrs{ "state-server": false, "name": "dummy storage", })) dummyenv, err := environs.Prepare(dummyCfg, coretesting.Context(c), configstore.NewMem()) c.Assert(err, gc.IsNil) defer dummyenv.Destroy() t.Destroy(c) attrs := t.TestConfig.Merge(coretesting.Attrs{"default-series": other.Series}) cfg, err := config.New(config.NoDefaults, attrs) c.Assert(err, gc.IsNil) env, err := environs.Prepare(cfg, coretesting.Context(c), t.ConfigStore) c.Assert(err, gc.IsNil) defer environs.Destroy(env, t.ConfigStore) currentName := envtools.StorageName(current) otherName := envtools.StorageName(other) envStorage := env.Storage() dummyStorage := dummyenv.Storage() defer envStorage.Remove(otherName) _, err = sync.Upload(dummyStorage, ¤t.Number) c.Assert(err, gc.IsNil) // This will only work while cross-compiling across releases is safe, // which depends on external elements. Tends to be safe for the last // few releases, but we may have to refactor some day. err = storageCopy(dummyStorage, currentName, envStorage, otherName) c.Assert(err, gc.IsNil) err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{}) c.Assert(err, gc.IsNil) conn, err := juju.NewConn(env) c.Assert(err, gc.IsNil) defer conn.Close() // Wait for machine agent to come up on the bootstrap // machine and ensure it deployed the proper series. m0, err := conn.State.Machine("0") c.Assert(err, gc.IsNil) mw0 := newMachineToolWaiter(m0) defer mw0.Stop() waitAgentTools(c, mw0, other) }