This change updates our configuration model to make it simpler to understand by removing some features and changing how things are persisted in files. Notable changes: - We've removed the notion of "workspace" vs "project" config. Now, configuration is always stored in a file next to `Pulumi.yaml` named `Pulumi.<stack-name>.yaml` (the same file we'd use for an other stack specific information we would need to persist in the future). - We've removed the notion of project wide configuration. Every new stack gets a completely empty set of configuration and there's no way to share common values across stacks, instead the common value has to be set on each stack. We retain some of the old code for the configuration system so we can support upgrading a project in place. That will happen with the next change. This change fixes some issues and allows us to close some others (since they are no longer possible). Fixes #866 Closes #872 Closes #731
83 lines
2.3 KiB
Go
83 lines
2.3 KiB
Go
// Copyright 2016-2017, Pulumi Corporation. All rights reserved.
|
|
|
|
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/pulumi/pulumi/pkg/backend/state"
|
|
"github.com/pulumi/pulumi/pkg/diag/colors"
|
|
"github.com/pulumi/pulumi/pkg/tokens"
|
|
"github.com/pulumi/pulumi/pkg/util/cmdutil"
|
|
"github.com/pulumi/pulumi/pkg/workspace"
|
|
)
|
|
|
|
func newStackRmCmd() *cobra.Command {
|
|
var yes bool
|
|
var force bool
|
|
var cmd = &cobra.Command{
|
|
Use: "rm [<stack-name>]",
|
|
Args: cmdutil.MaximumNArgs(1),
|
|
Short: "Remove a stack and its configuration",
|
|
Long: "Remove a stack and its configuration\n" +
|
|
"\n" +
|
|
"This command removes a stack and its configuration state. Please refer to the\n" +
|
|
"`destroy` command for removing a resources, as this is a distinct operation.\n" +
|
|
"\n" +
|
|
"After this command completes, the stack will no longer be available for updates.",
|
|
Run: cmdutil.RunFunc(func(cmd *cobra.Command, args []string) error {
|
|
// Use the stack provided or, if missing, default to the current one.
|
|
var stack tokens.QName
|
|
if len(args) > 0 {
|
|
stack = tokens.QName(args[0])
|
|
}
|
|
s, err := requireStack(stack, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Ensure the user really wants to do this.
|
|
prompt := fmt.Sprintf("This will permanently remove the '%s' stack!", s.Name())
|
|
if !yes && !confirmPrompt(prompt, string(s.Name())) {
|
|
return errors.New("confirmation declined")
|
|
}
|
|
|
|
hasResources, err := s.Remove(force)
|
|
if err != nil {
|
|
if hasResources {
|
|
return errors.Errorf(
|
|
"'%v' still has resources; removal rejected; pass --force to override", s.Name())
|
|
}
|
|
return err
|
|
}
|
|
|
|
// Blow away stack specific settings if they exist
|
|
path, err := workspace.DetectProjectStackPath(s.Name())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
|
|
return err
|
|
}
|
|
|
|
msg := fmt.Sprintf("%sStack '%s' has been removed!%s", colors.SpecAttention, s.Name(), colors.Reset)
|
|
fmt.Println(colors.ColorizeText(msg))
|
|
|
|
return state.SetCurrentStack("")
|
|
}),
|
|
}
|
|
|
|
cmd.PersistentFlags().BoolVarP(
|
|
&force, "force", "f", false,
|
|
"By default, removal of a stack with resources will be rejected; this forces it")
|
|
cmd.PersistentFlags().BoolVar(
|
|
&yes, "yes", false,
|
|
"Skip confirmation prompts, and proceed with removal anyway")
|
|
|
|
return cmd
|
|
}
|