func destroyEnvironment(st *state.State, environTag names.EnvironTag, destroyHostedEnvirons bool) error { var err error if environTag != st.EnvironTag() { if st, err = st.ForEnviron(environTag); err != nil { return errors.Trace(err) } defer st.Close() } if destroyHostedEnvirons { envs, err := st.AllEnvironments() if err != nil { return errors.Trace(err) } for _, env := range envs { envSt, err := st.ForEnviron(env.EnvironTag()) defer envSt.Close() if err != nil { return errors.Trace(err) } check := NewBlockChecker(envSt) if err = check.DestroyAllowed(); err != nil { return errors.Trace(err) } } } else { check := NewBlockChecker(st) if err = check.DestroyAllowed(); err != nil { return errors.Trace(err) } } env, err := st.Environment() if err != nil { return errors.Trace(err) } if destroyHostedEnvirons { if err := env.DestroyIncludingHosted(); err != nil { return err } } else { if err = env.Destroy(); err != nil { return errors.Trace(err) } } err = sendMetrics(st) if err != nil { logger.Warningf("failed to send leftover metrics: %v", err) } // Return to the caller. If it's the CLI, it will finish up by calling the // provider's Destroy method, which will destroy the state servers, any // straggler instances, and other provider-specific resources. Once all // resources are torn down, the Undertaker worker handles the removal of // the environment. return nil }
// DestroyEnvironment destroys all services and non-manager machine // instances in the specified environment. This function assumes that all // necessary authentication checks have been done. func DestroyEnvironment(st *state.State, environTag names.EnvironTag) error { var err error if environTag != st.EnvironTag() { if st, err = st.ForEnviron(environTag); err != nil { return errors.Trace(err) } defer st.Close() } check := NewBlockChecker(st) if err = check.DestroyAllowed(); err != nil { return errors.Trace(err) } env, err := st.Environment() if err != nil { return errors.Trace(err) } if err = env.Destroy(); err != nil { return errors.Trace(err) } machines, err := st.AllMachines() if err != nil { return errors.Trace(err) } err = sendMetrics(st) if err != nil { logger.Warningf("failed to send leftover metrics: %v", err) } // We must destroy instances server-side to support JES (Juju Environment // Server), as there's no CLI to fall back on. In that case, we only ever // destroy non-state machines; we leave destroying state servers in non- // hosted environments to the CLI, as otherwise the API server may get cut // off. if err := destroyNonManagerMachines(st, machines); err != nil { return errors.Trace(err) } // If this is not the state server environment, remove all documents from // state associated with the environment. if env.EnvironTag() != env.ServerTag() { return errors.Trace(st.RemoveAllEnvironDocs()) } // Return to the caller. If it's the CLI, it will finish up // by calling the provider's Destroy method, which will // destroy the state servers, any straggler instances, and // other provider-specific resources. return nil }
func (c *dumpLogsCommand) dumpLogsForEnv(ctx *cmd.Context, st0 *state.State, tag names.EnvironTag) error { st, err := st0.ForEnviron(tag) if err != nil { return errors.Annotate(err, "failed open environment") } defer st.Close() logName := ctx.AbsPath(filepath.Join(c.outDir, fmt.Sprintf("%s.log", tag.Id()))) ctx.Infof("writing to %s", logName) file, err := os.Create(logName) if err != nil { return errors.Annotate(err, "failed to open output file") } defer file.Close() writer := bufio.NewWriter(file) defer writer.Flush() tailer := state.NewLogTailer(st, &state.LogTailerParams{NoTail: true}) logs := tailer.Logs() for { rec, ok := <-logs if !ok { break } writer.WriteString(c.format( rec.Time, rec.Level, rec.Entity, rec.Module, rec.Message, ) + "\n") } return nil }