diff --git a/command/init_test.go b/command/init_test.go index d5f6f3c33d..1e95e12414 100644 --- a/command/init_test.go +++ b/command/init_test.go @@ -997,6 +997,71 @@ func TestInit_providerLockFile(t *testing.T) { } } +func TestInit_pluginDirReset(t *testing.T) { + td, err := ioutil.TempDir("", "tf") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(td) + defer testChdir(t, td)() + + ui := new(cli.MockUi) + c := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + }, + providerInstaller: &mockProviderInstaller{}, + } + + // make our vendor paths + pluginPath := []string{"a", "b", "c"} + for _, p := range pluginPath { + if err := os.MkdirAll(p, 0755); err != nil { + t.Fatal(err) + } + } + + // run once and save the -plugin-dir + args := []string{"-plugin-dir", "a"} + if code := c.Run(args); code != 0 { + t.Fatalf("bad: \n%s", ui.ErrorWriter) + } + + pluginDirs, err := c.loadPluginPath() + if err != nil { + t.Fatal(err) + } + + if len(pluginDirs) != 1 || pluginDirs[0] != "a" { + t.Fatalf(`expected plugin dir ["a"], got %q`, pluginDirs) + } + + ui = new(cli.MockUi) + c = &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + }, + providerInstaller: &mockProviderInstaller{}, + } + + // make sure we remove the plugin-dir record + args = []string{"-plugin-dir="} + if code := c.Run(args); code != 0 { + t.Fatalf("bad: \n%s", ui.ErrorWriter) + } + + pluginDirs, err = c.loadPluginPath() + if err != nil { + t.Fatal(err) + } + + if len(pluginDirs) != 0 { + t.Fatalf("expected no plugin dirs got %q", pluginDirs) + } +} + // Test user-supplied -plugin-dir func TestInit_pluginDirProviders(t *testing.T) { td := tempDir(t) diff --git a/command/plugins.go b/command/plugins.go index 12449da2ea..467279ec81 100644 --- a/command/plugins.go +++ b/command/plugins.go @@ -117,6 +117,17 @@ func (m *Meta) storePluginPath(pluginPath []string) error { return nil } + path := filepath.Join(m.DataDir(), PluginPathFile) + + // remove the plugin dir record if the path was set to an empty string + if len(pluginPath) == 1 && (pluginPath[0] == "") { + err := os.Remove(path) + if !os.IsNotExist(err) { + return err + } + return nil + } + js, err := json.MarshalIndent(pluginPath, "", " ") if err != nil { return err @@ -125,7 +136,7 @@ func (m *Meta) storePluginPath(pluginPath []string) error { // if this fails, so will WriteFile os.MkdirAll(m.DataDir(), 0755) - return ioutil.WriteFile(filepath.Join(m.DataDir(), PluginPathFile), js, 0644) + return ioutil.WriteFile(path, js, 0644) } // Load the user-defined plugin search path into Meta.pluginPath if the file diff --git a/website/docs/commands/init.html.markdown b/website/docs/commands/init.html.markdown index 8c50b28e44..0916d40a82 100644 --- a/website/docs/commands/init.html.markdown +++ b/website/docs/commands/init.html.markdown @@ -133,7 +133,8 @@ The automatic plugin installation behavior can be overridden by extracting the desired providers into a local directory and using the additional option `-plugin-dir=PATH`. When this option is specified, _only_ the given directory is consulted, which prevents Terraform from making requests to the plugin -repository or looking for plugins in other local directories. +repository or looking for plugins in other local directories. Passing an empty +string to `-plugin-dir` removes any previously recorded paths. Custom plugins can be used along with automatically installed plugins by placing them in `terraform.d/plugins/OS_ARCH/` inside the directory being