| package workdir |
| |
| import ( |
| "encoding/json" |
| "io/ioutil" |
| "os" |
| "path/filepath" |
| ) |
| |
| const PluginPathFilename = "plugin_path" |
| |
| // ProviderLocalCacheDir returns the directory we'll use as the |
| // working-directory-specific local cache of providers. |
| // |
| // The provider installer's job is to make sure that all providers needed for |
| // a particular working directory are available in this cache directory. No |
| // other component may write here, and in particular a Dir object itself |
| // never reads or writes into this directory, instead just delegating all of |
| // that responsibility to other components. |
| // |
| // Typically, the caller will ultimately pass the result of this method either |
| // directly or indirectly into providercache.NewDir, to get an object |
| // responsible for managing the contents. |
| func (d *Dir) ProviderLocalCacheDir() string { |
| return filepath.Join(d.dataDir, "providers") |
| } |
| |
| // ForcedPluginDirs returns a list of directories to use to find plugins, |
| // instead of the default locations. |
| // |
| // Returns an zero-length list and no error in the normal case where there |
| // are no overridden search directories. If ForcedPluginDirs returns a |
| // non-empty list with no errors then the result totally replaces the default |
| // search directories. |
| func (d *Dir) ForcedPluginDirs() ([]string, error) { |
| raw, err := ioutil.ReadFile(filepath.Join(d.dataDir, PluginPathFilename)) |
| if os.IsNotExist(err) { |
| return nil, nil |
| } |
| |
| if err != nil { |
| return nil, err |
| } |
| |
| var pluginPath []string |
| if err := json.Unmarshal(raw, &pluginPath); err != nil { |
| return nil, err |
| } |
| return pluginPath, nil |
| } |
| |
| // SetForcedPluginDirs records an overridden list of directories to search |
| // to find plugins, instead of the default locations. See ForcePluginDirs |
| // for more information. |
| // |
| // Pass a zero-length list to deactivate forced plugin directories altogether, |
| // thus allowing the working directory to return to using the default |
| // search directories. |
| func (d *Dir) SetForcedPluginDirs(dirs []string) error { |
| |
| filePath := filepath.Join(d.dataDir, PluginPathFilename) |
| switch { |
| case len(dirs) == 0: |
| err := os.Remove(filePath) |
| if !os.IsNotExist(err) { |
| return err |
| } |
| return nil |
| default: |
| // We'll ignore errors from this one, because if we fail to create |
| // the directory then we'll fail to create the file below too, |
| // and that subsequent error will more directly reflect what we |
| // are trying to do here. |
| d.ensureDataDir() |
| |
| raw, err := json.MarshalIndent(dirs, "", " ") |
| if err != nil { |
| return err |
| } |
| |
| return ioutil.WriteFile(filePath, raw, 0644) |
| } |
| } |