// handleBootstrapError cleans up after a failed bootstrap. func handleBootstrapError(err error, ctx environs.BootstrapContext, inst instance.Instance, env environs.Environ) { if err == nil { return } logger.Errorf("bootstrap failed: %v", err) ch := make(chan os.Signal, 1) ctx.InterruptNotify(ch) defer ctx.StopInterruptNotify(ch) defer close(ch) go func() { for _ = range ch { fmt.Fprintln(ctx.GetStderr(), "Cleaning up failed bootstrap") } }() if inst != nil { fmt.Fprintln(ctx.GetStderr(), "Stopping instance...") if stoperr := env.StopInstances(inst.Id()); stoperr != nil { logger.Errorf("cannot stop failed bootstrap instance %q: %v", inst.Id(), stoperr) } else { // set to nil so we know we can safely delete the state file inst = nil } } // We only delete the bootstrap state file if either we didn't // start an instance, or we managed to cleanly stop it. if inst == nil { if rmerr := bootstrap.DeleteStateFile(env.Storage()); rmerr != nil { logger.Errorf("cannot delete bootstrap state file: %v", rmerr) } } }
func (suite *StateSuite) TestDeleteStateFile(c *gc.C) { closer, stor, dataDir := envtesting.CreateLocalTestStorage(c) defer closer.Close() err := bootstrap.DeleteStateFile(stor) c.Assert(err, gc.IsNil) // doesn't exist, juju don't care _, err = bootstrap.CreateStateFile(stor) c.Assert(err, gc.IsNil) _, err = os.Stat(filepath.Join(dataDir, bootstrap.StateFile)) c.Assert(err, gc.IsNil) err = bootstrap.DeleteStateFile(stor) c.Assert(err, gc.IsNil) _, err = os.Stat(filepath.Join(dataDir, bootstrap.StateFile)) c.Assert(err, jc.Satisfies, os.IsNotExist) }