configs/configload: some loaders can't install modules

Originally the hope was to use the afero filesystem abstraction for all
loader operations, but since we install modules using go-getter we cannot
(without a lot of refactoring) support vfs for installation.

The vfs use-case is for reading configuration from plan zip files anyway,
and so we have no real reason to support installation into a vfs. For now
at least we will just add the possibility that a loader might not be
install-capable. At the moment we have no non-install-capable loaders, but
we'll add one later once we get to loading configuration from plan files.
This commit is contained in:
Martin Atkins 2018-02-14 14:35:03 -08:00
parent 59939cf320
commit 74afcb4a7f
3 changed files with 32 additions and 5 deletions

View File

@ -59,11 +59,12 @@ func NewLoader(config *Config) (*Loader, error) {
ret := &Loader{
parser: parser,
modules: moduleMgr{
FS: afero.Afero{fs},
Dir: config.ModulesDir,
Services: config.Services,
Creds: config.Creds,
Registry: reg,
FS: afero.Afero{Fs: fs},
CanInstall: true,
Dir: config.ModulesDir,
Services: config.Services,
Creds: config.Creds,
Registry: reg,
},
}

View File

@ -38,7 +38,16 @@ import (
// may have wholly or partially completed. Modules must be loaded in order
// to find their dependencies, so this function does many of the same checks
// as LoadConfig as a side-effect.
//
// This function will panic if called on a loader that cannot install modules.
// Use CanInstallModules to determine if a loader can install modules, or
// refer to the documentation for that method for situations where module
// installation capability is guaranteed.
func (l *Loader) InstallModules(rootDir string, upgrade bool, hooks InstallHooks) hcl.Diagnostics {
if !l.CanInstallModules() {
panic(fmt.Errorf("InstallModules called on loader that cannot install modules"))
}
rootMod, diags := l.parser.LoadConfigDir(rootDir)
if rootMod == nil {
return diags
@ -183,6 +192,16 @@ func (l *Loader) InstallModules(rootDir string, upgrade bool, hooks InstallHooks
return diags
}
// CanInstallModules returns true if InstallModules can be used with this
// loader.
//
// Loaders created with NewLoader can always install modules. Loaders created
// from plan files (where the configuration is embedded in the plan file itself)
// cannot install modules, because the plan file is read-only.
func (l *Loader) CanInstallModules() bool {
return l.modules.CanInstall
}
func (l *Loader) installLocalModule(req *configs.ModuleRequest, key string, hooks InstallHooks) (*configs.Module, hcl.Diagnostics) {
var diags hcl.Diagnostics

View File

@ -10,6 +10,13 @@ import (
type moduleMgr struct {
FS afero.Afero
// CanInstall is true for a module manager that can support installation.
//
// This must be set only if FS is an afero.OsFs, because the installer
// (which uses go-getter) is not aware of the virtual filesystem
// abstraction and will always write into the "real" filesystem.
CanInstall bool
// Dir is the path where descendent modules are (or will be) installed.
Dir string