command + backend: rename various API objects to "Workspace" terminology

We're shifting terminology from "environment" to "workspace". This takes
care of some of the main internal API surface that was using the old
terminology, though is not intended to be entirely comprehensive and is
mainly just to minimize the amount of confusion for maintainers as we
continue moving towards eliminating the old terminology.
This commit is contained in:
Martin Atkins 2017-05-30 17:13:43 -07:00
parent 33a266d61c
commit 418a8a8bc9
26 changed files with 96 additions and 95 deletions

View File

@ -19,8 +19,8 @@ import (
)
const (
DefaultEnvDir = "terraform.tfstate.d"
DefaultEnvFile = "environment"
DefaultWorkspaceDir = "terraform.tfstate.d"
DefaultWorkspaceFile = "environment"
DefaultStateFilename = "terraform.tfstate"
DefaultDataDir = ".terraform"
DefaultBackupExtension = ".backup"
@ -35,8 +35,8 @@ type Local struct {
CLI cli.Ui
CLIColor *colorstring.Colorize
// The State* paths are set from the CLI options, and may be left blank to
// use the defaults. If the actual paths for the local backend state are
// The State* paths are set from the backend config, and may be left blank
// to use the defaults. If the actual paths for the local backend state are
// needed, use the StatePaths method.
//
// StatePath is the local path where state is read from.
@ -47,12 +47,12 @@ type Local struct {
// StateBackupPath is the local path where a backup file will be written.
// Set this to "-" to disable state backup.
//
// StateEnvPath is the path to the folder containing environments. This
// defaults to DefaultEnvDir if not set.
StatePath string
StateOutPath string
StateBackupPath string
StateEnvDir string
// StateWorkspaceDir is the path to the folder containing data for
// non-default workspaces. This defaults to DefaultWorkspaceDir if not set.
StatePath string
StateOutPath string
StateBackupPath string
StateWorkspaceDir string
// We only want to create a single instance of a local state, so store them
// here as they're loaded.
@ -126,7 +126,7 @@ func (b *Local) States() ([]string, error) {
// the listing always start with "default"
envs := []string{backend.DefaultStateName}
entries, err := ioutil.ReadDir(b.stateEnvDir())
entries, err := ioutil.ReadDir(b.stateWorkspaceDir())
// no error if there's no envs configured
if os.IsNotExist(err) {
return envs, nil
@ -165,7 +165,7 @@ func (b *Local) DeleteState(name string) error {
}
delete(b.states, name)
return os.RemoveAll(filepath.Join(b.stateEnvDir(), name))
return os.RemoveAll(filepath.Join(b.stateWorkspaceDir(), name))
}
func (b *Local) State(name string) (state.State, error) {
@ -329,7 +329,7 @@ func (b *Local) schemaConfigure(ctx context.Context) error {
if raw, ok := d.GetOk("workspace_dir"); ok {
path := raw.(string)
if path != "" {
b.StateEnvDir = path
b.StateWorkspaceDir = path
}
}
@ -337,7 +337,7 @@ func (b *Local) schemaConfigure(ctx context.Context) error {
if raw, ok := d.GetOk("environment_dir"); ok {
path := raw.(string)
if path != "" {
b.StateEnvDir = path
b.StateWorkspaceDir = path
}
}
@ -360,7 +360,7 @@ func (b *Local) StatePaths(name string) (string, string, string) {
statePath = DefaultStateFilename
}
} else {
statePath = filepath.Join(b.stateEnvDir(), name, DefaultStateFilename)
statePath = filepath.Join(b.stateWorkspaceDir(), name, DefaultStateFilename)
}
if stateOutPath == "" {
@ -383,7 +383,7 @@ func (b *Local) createState(name string) error {
return nil
}
stateDir := filepath.Join(b.stateEnvDir(), name)
stateDir := filepath.Join(b.stateWorkspaceDir(), name)
s, err := os.Stat(stateDir)
if err == nil && s.IsDir() {
// no need to check for os.IsNotExist, since that is covered by os.MkdirAll
@ -399,11 +399,11 @@ func (b *Local) createState(name string) error {
return nil
}
// stateEnvDir returns the directory where state environments are stored.
func (b *Local) stateEnvDir() string {
if b.StateEnvDir != "" {
return b.StateEnvDir
// stateWorkspaceDir returns the directory where state environments are stored.
func (b *Local) stateWorkspaceDir() string {
if b.StateWorkspaceDir != "" {
return b.StateWorkspaceDir
}
return DefaultEnvDir
return DefaultWorkspaceDir
}

View File

@ -69,7 +69,7 @@ func TestLocal_StatePaths(t *testing.T) {
testEnv := "test_env"
path, out, back = b.StatePaths(testEnv)
expectedPath := filepath.Join(DefaultEnvDir, testEnv, DefaultStateFilename)
expectedPath := filepath.Join(DefaultWorkspaceDir, testEnv, DefaultStateFilename)
expectedOut := expectedPath
expectedBackup := expectedPath + DefaultBackupExtension
@ -261,7 +261,7 @@ func TestLocal_remoteStateBackup(t *testing.T) {
t.Fatal("remote state is not backed up")
}
if bs.Path != filepath.Join(DefaultEnvDir, "test", DefaultStateFilename+DefaultBackupExtension) {
if bs.Path != filepath.Join(DefaultWorkspaceDir, "test", DefaultStateFilename+DefaultBackupExtension) {
t.Fatal("bad backup location:", bs.Path)
}
}

View File

@ -18,11 +18,11 @@ import (
func TestLocal(t *testing.T) *Local {
tempDir := testTempDir(t)
return &Local{
StatePath: filepath.Join(tempDir, "state.tfstate"),
StateOutPath: filepath.Join(tempDir, "state.tfstate"),
StateBackupPath: filepath.Join(tempDir, "state.tfstate.bak"),
StateEnvDir: filepath.Join(tempDir, "state.tfstate.d"),
ContextOpts: &terraform.ContextOpts{},
StatePath: filepath.Join(tempDir, "state.tfstate"),
StateOutPath: filepath.Join(tempDir, "state.tfstate"),
StateBackupPath: filepath.Join(tempDir, "state.tfstate.bak"),
StateWorkspaceDir: filepath.Join(tempDir, "state.tfstate.d"),
ContextOpts: &terraform.ContextOpts{},
}
}

View File

@ -177,7 +177,7 @@ func (c *InitCommand) Run(args []string) int {
// Now that we have loaded all modules, check the module tree for missing providers
if flagGetPlugins {
sMgr, err := back.State(c.Env())
sMgr, err := back.State(c.Workspace())
if err != nil {
c.Ui.Error(fmt.Sprintf(
"Error loading state: %s", err))

View File

@ -247,7 +247,7 @@ func (m *Meta) contextOpts() *terraform.ContextOpts {
opts.ProviderSHA256s = m.providerPluginsLock().Read()
opts.Meta = &terraform.ContextMeta{
Env: m.Env(),
Env: m.Workspace(),
}
return &opts
@ -454,25 +454,26 @@ func (m *Meta) outputShadowError(err error, output bool) bool {
return true
}
// EnvironmentNameEnvVar is the name of the environment variable (ie, the POSIX
// feature) that can be used to set the name of the Terraform workspace
// (overriding the workspace chosen by `terraform workspace select`). Note that
// this environment variable is ignored by `terraform workspace new` and
// `terraform workspace delete`.
const EnvironmentNameEnvVar = "TF_WORKSPACE"
// WorkspaceNameEnvVar is the name of the environment variable that can be used
// to set the name of the Terraform workspace, overriding the workspace chosen
// by `terraform workspace select`.
//
// Note that this environment variable is ignored by `terraform workspace new`
// and `terraform workspace delete`.
const WorkspaceNameEnvVar = "TF_WORKSPACE"
// Env returns the name of the currently configured workspace, corresponding
// Workspace returns the name of the currently configured workspace, corresponding
// to the desired named state.
func (m *Meta) Env() string {
current, _ := m.EnvOverridden()
func (m *Meta) Workspace() string {
current, _ := m.WorkspaceOverridden()
return current
}
// EnvOverridden returns the name of the currently configured workspace,
// WorkspaceOverridden returns the name of the currently configured workspace,
// corresponding to the desired named state, as well as a bool saying whether
// this was set via the TF_WORKSPACE environment variable.
func (m *Meta) EnvOverridden() (string, bool) {
if envVar := os.Getenv(EnvironmentNameEnvVar); envVar != "" {
func (m *Meta) WorkspaceOverridden() (string, bool) {
if envVar := os.Getenv(WorkspaceNameEnvVar); envVar != "" {
return envVar, true
}
@ -481,7 +482,7 @@ func (m *Meta) EnvOverridden() (string, bool) {
dataDir = DefaultDataDir
}
envData, err := ioutil.ReadFile(filepath.Join(dataDir, local.DefaultEnvFile))
envData, err := ioutil.ReadFile(filepath.Join(dataDir, local.DefaultWorkspaceFile))
current := string(bytes.TrimSpace(envData))
if current == "" {
current = backend.DefaultStateName
@ -495,9 +496,9 @@ func (m *Meta) EnvOverridden() (string, bool) {
return current, false
}
// SetEnv saves the given name as the current workspace in the local
// SetWorkspace saves the given name as the current workspace in the local
// filesystem.
func (m *Meta) SetEnv(name string) error {
func (m *Meta) SetWorkspace(name string) error {
dataDir := m.dataDir
if m.dataDir == "" {
dataDir = DefaultDataDir
@ -508,7 +509,7 @@ func (m *Meta) SetEnv(name string) error {
return err
}
err = ioutil.WriteFile(filepath.Join(dataDir, local.DefaultEnvFile), []byte(name), 0644)
err = ioutil.WriteFile(filepath.Join(dataDir, local.DefaultWorkspaceFile), []byte(name), 0644)
if err != nil {
return err
}

View File

@ -168,7 +168,7 @@ func (m *Meta) Operation() *backend.Operation {
PlanOutBackend: m.backendState,
Targets: m.targets,
UIIn: m.UIInput(),
Environment: m.Env(),
Environment: m.Workspace(),
LockState: m.stateLock,
StateLockTimeout: m.stateLockTimeout,
}
@ -572,7 +572,7 @@ func (m *Meta) backendFromPlan(opts *BackendOpts) (backend.Backend, error) {
return nil, err
}
env := m.Env()
env := m.Workspace()
// Get the state so we can determine the effect of using this plan
realMgr, err := b.State(env)
@ -967,7 +967,7 @@ func (m *Meta) backend_C_r_s(
return nil, fmt.Errorf(errBackendLocalRead, err)
}
env := m.Env()
env := m.Workspace()
localState, err := localB.State(env)
if err != nil {

View File

@ -162,7 +162,7 @@ func (m *Meta) backendMigrateState_S_S(opts *backendMigrateOpts) error {
// Multi-state to single state.
func (m *Meta) backendMigrateState_S_s(opts *backendMigrateOpts) error {
currentEnv := m.Env()
currentEnv := m.Workspace()
migrate := opts.force
if !migrate {
@ -192,7 +192,7 @@ func (m *Meta) backendMigrateState_S_s(opts *backendMigrateOpts) error {
opts.oneEnv = currentEnv
// now switch back to the default env so we can acccess the new backend
m.SetEnv(backend.DefaultStateName)
m.SetWorkspace(backend.DefaultStateName)
return m.backendMigrateState_s_s(opts)
}

View File

@ -1250,13 +1250,13 @@ func TestMetaBackend_configuredChangeCopy_multiToSingle(t *testing.T) {
}
// Verify existing workspaces exist
envPath := filepath.Join(backendlocal.DefaultEnvDir, "env2", backendlocal.DefaultStateFilename)
envPath := filepath.Join(backendlocal.DefaultWorkspaceDir, "env2", backendlocal.DefaultStateFilename)
if _, err := os.Stat(envPath); err != nil {
t.Fatal("env should exist")
}
// Verify we are now in the default env, or we may not be able to access the new backend
if env := m.Env(); env != backend.DefaultStateName {
if env := m.Workspace(); env != backend.DefaultStateName {
t.Fatal("using non-default env with single-env backend")
}
}
@ -1285,7 +1285,7 @@ func TestMetaBackend_configuredChangeCopy_multiToSingleCurrentEnv(t *testing.T)
m := testMetaBackend(t, nil)
// Change env
if err := m.SetEnv("env2"); err != nil {
if err := m.SetWorkspace("env2"); err != nil {
t.Fatalf("bad: %s", err)
}
@ -1322,7 +1322,7 @@ func TestMetaBackend_configuredChangeCopy_multiToSingleCurrentEnv(t *testing.T)
}
// Verify existing workspaces exist
envPath := filepath.Join(backendlocal.DefaultEnvDir, "env2", backendlocal.DefaultStateFilename)
envPath := filepath.Join(backendlocal.DefaultWorkspaceDir, "env2", backendlocal.DefaultStateFilename)
if _, err := os.Stat(envPath); err != nil {
t.Fatal("env should exist")
}
@ -1407,7 +1407,7 @@ func TestMetaBackend_configuredChangeCopy_multiToMulti(t *testing.T) {
{
// Verify existing workspaces exist
envPath := filepath.Join(backendlocal.DefaultEnvDir, "env2", backendlocal.DefaultStateFilename)
envPath := filepath.Join(backendlocal.DefaultWorkspaceDir, "env2", backendlocal.DefaultStateFilename)
if _, err := os.Stat(envPath); err != nil {
t.Fatal("env should exist")
}

View File

@ -282,27 +282,27 @@ func TestMeta_Env(t *testing.T) {
m := new(Meta)
env := m.Env()
env := m.Workspace()
if env != backend.DefaultStateName {
t.Fatalf("expected env %q, got env %q", backend.DefaultStateName, env)
}
testEnv := "test_env"
if err := m.SetEnv(testEnv); err != nil {
if err := m.SetWorkspace(testEnv); err != nil {
t.Fatal("error setting env:", err)
}
env = m.Env()
env = m.Workspace()
if env != testEnv {
t.Fatalf("expected env %q, got env %q", testEnv, env)
}
if err := m.SetEnv(backend.DefaultStateName); err != nil {
if err := m.SetWorkspace(backend.DefaultStateName); err != nil {
t.Fatal("error setting env:", err)
}
env = m.Env()
env = m.Workspace()
if env != backend.DefaultStateName {
t.Fatalf("expected env %q, got env %q", backend.DefaultStateName, env)
}

View File

@ -50,7 +50,7 @@ func (c *OutputCommand) Run(args []string) int {
return 1
}
env := c.Env()
env := c.Workspace()
// Get the state
stateStore, err := b.State(env)

View File

@ -61,7 +61,7 @@ func (c *ProvidersCommand) Run(args []string) int {
}
// Get the state
env := c.Env()
env := c.Workspace()
state, err := b.State(env)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))

View File

@ -74,7 +74,7 @@ func (c *ShowCommand) Run(args []string) int {
return 1
}
env := c.Env()
env := c.Workspace()
// Get the state
stateStore, err := b.State(env)

View File

@ -32,7 +32,7 @@ func (c *StateListCommand) Run(args []string) int {
return 1
}
env := c.Env()
env := c.Workspace()
// Get the state
state, err := b.State(env)
if err != nil {

View File

@ -24,7 +24,7 @@ func (c *StateMeta) State(m *Meta) (state.State, error) {
return nil, err
}
env := m.Env()
env := m.Workspace()
// Get the state
s, err := b.State(env)
if err != nil {

View File

@ -32,7 +32,7 @@ func (c *StatePullCommand) Run(args []string) int {
}
// Get the state
env := c.Env()
env := c.Workspace()
state, err := b.State(env)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))

View File

@ -67,7 +67,7 @@ func (c *StatePushCommand) Run(args []string) int {
}
// Get the state
env := c.Env()
env := c.Workspace()
state, err := b.State(env)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load destination state: %s", err))

View File

@ -34,7 +34,7 @@ func (c *StateShowCommand) Run(args []string) int {
}
// Get the state
env := c.Env()
env := c.Workspace()
state, err := b.State(env)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))

View File

@ -69,7 +69,7 @@ func (c *TaintCommand) Run(args []string) int {
}
// Get the state
env := c.Env()
env := c.Workspace()
st, err := b.State(env)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))

View File

@ -58,7 +58,7 @@ func (c *UnlockCommand) Run(args []string) int {
return 1
}
env := c.Env()
env := c.Workspace()
st, err := b.State(env)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))

View File

@ -57,7 +57,7 @@ func (c *UntaintCommand) Run(args []string) int {
}
// Get the state
env := c.Env()
env := c.Workspace()
st, err := b.State(env)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load state: %s", err))

View File

@ -47,10 +47,10 @@ func (c *WorkspaceCommand) Synopsis() string {
return "Workspace management"
}
// validEnvName returns true is this name is valid to use as a workspace name.
// validWorkspaceName returns true is this name is valid to use as a workspace name.
// Since most named states are accessed via a filesystem path or URL, check if
// escaping the name would be required.
func validEnvName(name string) bool {
func validWorkspaceName(name string) bool {
return name == url.PathEscape(name)
}

View File

@ -23,7 +23,7 @@ func TestWorkspace_createAndChange(t *testing.T) {
newCmd := &WorkspaceNewCommand{}
current := newCmd.Env()
current := newCmd.Workspace()
if current != backend.DefaultStateName {
t.Fatal("current workspace should be 'default'")
}
@ -35,7 +35,7 @@ func TestWorkspace_createAndChange(t *testing.T) {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
}
current = newCmd.Env()
current = newCmd.Workspace()
if current != "test" {
t.Fatalf("current workspace should be 'test', got %q", current)
}
@ -48,7 +48,7 @@ func TestWorkspace_createAndChange(t *testing.T) {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
}
current = newCmd.Env()
current = newCmd.Workspace()
if current != backend.DefaultStateName {
t.Fatal("current workspace should be 'default'")
}
@ -178,7 +178,7 @@ func TestWorkspace_createWithState(t *testing.T) {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter)
}
newPath := filepath.Join(local.DefaultEnvDir, "test", DefaultStateFilename)
newPath := filepath.Join(local.DefaultWorkspaceDir, "test", DefaultStateFilename)
envState := state.LocalState{Path: newPath}
err = envState.RefreshState()
if err != nil {
@ -198,7 +198,7 @@ func TestWorkspace_delete(t *testing.T) {
defer testChdir(t, td)()
// create the workspace directories
if err := os.MkdirAll(filepath.Join(local.DefaultEnvDir, "test"), 0755); err != nil {
if err := os.MkdirAll(filepath.Join(local.DefaultWorkspaceDir, "test"), 0755); err != nil {
t.Fatal(err)
}
@ -206,7 +206,7 @@ func TestWorkspace_delete(t *testing.T) {
if err := os.MkdirAll(DefaultDataDir, 0755); err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(filepath.Join(DefaultDataDir, local.DefaultEnvFile), []byte("test"), 0644); err != nil {
if err := ioutil.WriteFile(filepath.Join(DefaultDataDir, local.DefaultWorkspaceFile), []byte("test"), 0644); err != nil {
t.Fatal(err)
}
@ -215,7 +215,7 @@ func TestWorkspace_delete(t *testing.T) {
Meta: Meta{Ui: ui},
}
current := delCmd.Env()
current := delCmd.Workspace()
if current != "test" {
t.Fatal("wrong workspace:", current)
}
@ -227,7 +227,7 @@ func TestWorkspace_delete(t *testing.T) {
}
// change back to default
if err := delCmd.SetEnv(backend.DefaultStateName); err != nil {
if err := delCmd.SetWorkspace(backend.DefaultStateName); err != nil {
t.Fatal(err)
}
@ -238,7 +238,7 @@ func TestWorkspace_delete(t *testing.T) {
t.Fatalf("error deleting workspace: %s", ui.ErrorWriter)
}
current = delCmd.Env()
current = delCmd.Workspace()
if current != backend.DefaultStateName {
t.Fatalf("wrong workspace: %q", current)
}
@ -250,7 +250,7 @@ func TestWorkspace_deleteWithState(t *testing.T) {
defer testChdir(t, td)()
// create the workspace directories
if err := os.MkdirAll(filepath.Join(local.DefaultEnvDir, "test"), 0755); err != nil {
if err := os.MkdirAll(filepath.Join(local.DefaultWorkspaceDir, "test"), 0755); err != nil {
t.Fatal(err)
}
@ -271,7 +271,7 @@ func TestWorkspace_deleteWithState(t *testing.T) {
},
}
envStatePath := filepath.Join(local.DefaultEnvDir, "test", DefaultStateFilename)
envStatePath := filepath.Join(local.DefaultWorkspaceDir, "test", DefaultStateFilename)
err := (&state.LocalState{Path: envStatePath}).WriteState(originalState)
if err != nil {
t.Fatal(err)
@ -294,7 +294,7 @@ func TestWorkspace_deleteWithState(t *testing.T) {
t.Fatalf("failure: %s", ui.ErrorWriter)
}
if _, err := os.Stat(filepath.Join(local.DefaultEnvDir, "test")); !os.IsNotExist(err) {
if _, err := os.Stat(filepath.Join(local.DefaultWorkspaceDir, "test")); !os.IsNotExist(err) {
t.Fatal("env 'test' still exists!")
}
}

View File

@ -35,7 +35,7 @@ func (c *WorkspaceDeleteCommand) Run(args []string) int {
delEnv := args[0]
if !validEnvName(delEnv) {
if !validWorkspaceName(delEnv) {
c.Ui.Error(fmt.Sprintf(envInvalidName, delEnv))
return 1
}
@ -81,7 +81,7 @@ func (c *WorkspaceDeleteCommand) Run(args []string) int {
return 1
}
if delEnv == c.Env() {
if delEnv == c.Workspace() {
c.Ui.Error(fmt.Sprintf(strings.TrimSpace(envDelCurrent), delEnv))
return 1
}

View File

@ -51,7 +51,7 @@ func (c *WorkspaceListCommand) Run(args []string) int {
return 1
}
env, isOverridden := c.EnvOverridden()
env, isOverridden := c.WorkspaceOverridden()
var out bytes.Buffer
for _, s := range states {

View File

@ -38,14 +38,14 @@ func (c *WorkspaceNewCommand) Run(args []string) int {
newEnv := args[0]
if !validEnvName(newEnv) {
if !validWorkspaceName(newEnv) {
c.Ui.Error(fmt.Sprintf(envInvalidName, newEnv))
return 1
}
// You can't ask to create a workspace when you're overriding the
// workspace name to be something different.
if current, isOverridden := c.EnvOverridden(); current != newEnv && isOverridden {
if current, isOverridden := c.WorkspaceOverridden(); current != newEnv && isOverridden {
c.Ui.Error(envIsOverriddenNewError)
return 1
}
@ -86,7 +86,7 @@ func (c *WorkspaceNewCommand) Run(args []string) int {
}
// now set the current workspace locally
if err := c.SetEnv(newEnv); err != nil {
if err := c.SetWorkspace(newEnv); err != nil {
c.Ui.Error(fmt.Sprintf("Error selecting new workspace: %s", err))
return 1
}

View File

@ -39,7 +39,7 @@ func (c *WorkspaceSelectCommand) Run(args []string) int {
c.Ui.Error(fmt.Sprintf("Failed to load root config module: %s", err))
}
current, isOverridden := c.EnvOverridden()
current, isOverridden := c.WorkspaceOverridden()
if isOverridden {
c.Ui.Error(envIsOverriddenSelectError)
return 1
@ -56,7 +56,7 @@ func (c *WorkspaceSelectCommand) Run(args []string) int {
}
name := args[0]
if !validEnvName(name) {
if !validWorkspaceName(name) {
c.Ui.Error(fmt.Sprintf(envInvalidName, name))
return 1
}
@ -85,7 +85,7 @@ func (c *WorkspaceSelectCommand) Run(args []string) int {
return 1
}
err = c.SetEnv(name)
err = c.SetWorkspace(name)
if err != nil {
c.Ui.Error(err.Error())
return 1