configload

package
v0.12.0-alpha3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 6, 2018 License: MPL-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package configload knows how to install modules into the .terraform/modules directory and to load modules from those installed locations. It is used in conjunction with the LoadConfig function in the parent package.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// ModulesDir is a path to a directory where descendent modules are
	// (or should be) installed. (This is usually the
	// .terraform/modules directory, in the common case where this package
	// is being loaded from the main Terraform CLI package.)
	ModulesDir string

	// Services is the service discovery client to use when locating remote
	// module registry endpoints. If this is nil then registry sources are
	// not supported, which should be true only in specialized circumstances
	// such as in tests.
	Services *disco.Disco
}

Config is used with NewLoader to specify configuration arguments for the loader.

type InstallHooks

type InstallHooks interface {
	// Download is called for modules that are retrieved from a remote source
	// before that download begins, to allow a caller to give feedback
	// on progress through a possibly-long sequence of downloads.
	Download(moduleAddr, packageAddr string, version *version.Version)

	// Install is called for each module that is installed, even if it did
	// not need to be downloaded from a remote source.
	Install(moduleAddr string, version *version.Version, localPath string)
}

InstallHooks is an interface used to provide notifications about the installation process being orchestrated by InstallModules.

This interface may have new methods added in future, so implementers should embed InstallHooksImpl to get no-op implementations of any unimplemented methods.

type InstallHooksImpl

type InstallHooksImpl struct {
}

InstallHooksImpl is a do-nothing implementation of InstallHooks that can be embedded in another implementation struct to allow only partial implementation of the interface.

func (InstallHooksImpl) Download

func (h InstallHooksImpl) Download(moduleAddr, packageAddr string, version *version.Version)

func (InstallHooksImpl) Install

func (h InstallHooksImpl) Install(moduleAddr string, version *version.Version, localPath string)

type Loader

type Loader struct {
	// contains filtered or unexported fields
}

A Loader instance is the main entry-point for loading configurations via this package.

It extends the general config-loading functionality in the parent package "configs" to support installation of modules from remote sources and loading full configurations using modules that were previously installed.

func LoadConfigForTests

func LoadConfigForTests(t *testing.T, rootDir string) (*configs.Config, *Loader, func(), tfdiags.Diagnostics)

LoadConfigForTests is a convenience wrapper around NewLoaderForTests, Loader.InstallModules and Loader.LoadConfig that allows a test configuration to be loaded in a single step.

If module installation fails, t.Fatal (or similar) is called to halt execution of the test, under the assumption that installation failures are not expected. If installation failures _are_ expected then use NewLoaderForTests and work with the loader object directly. If module installation succeeds but generates warnings, these warnings are discarded.

If installation succeeds but errors are detected during loading then a possibly-incomplete config is returned along with error diagnostics. The test run is not aborted in this case, so that the caller can make assertions against the returned diagnostics.

As with NewLoaderForTests, a cleanup function is returned which must be called before the test completes in order to remove the temporary modules directory.

func MustLoadConfigForTests

func MustLoadConfigForTests(t *testing.T, rootDir string) (*configs.Config, *Loader, func())

MustLoadConfigForTests is a variant of LoadConfigForTests which calls t.Fatal (or similar) if there are any errors during loading, and thus does not return diagnostics at all.

This is useful for concisely writing tests that don't expect errors at all. For tests that expect errors and need to assert against them, use LoadConfigForTests instead.

func NewLoader

func NewLoader(config *Config) (*Loader, error)

NewLoader creates and returns a loader that reads configuration from the real OS filesystem.

The loader has some internal state about the modules that are currently installed, which is read from disk as part of this function. If that manifest cannot be read then an error will be returned.

func NewLoaderForTests added in v0.12.0

func NewLoaderForTests(t *testing.T) (*Loader, func())

NewLoaderForTests is a variant of NewLoader that is intended to be more convenient for unit tests.

The loader's modules directory is a separate temporary directory created for each call. Along with the created loader, this function returns a cleanup function that should be called before the test completes in order to remove that temporary directory.

In the case of any errors, t.Fatal (or similar) will be called to halt execution of the test, so the calling test does not need to handle errors itself.

func NewLoaderFromSnapshot added in v0.12.0

func NewLoaderFromSnapshot(snap *Snapshot) *Loader

NewLoaderFromSnapshot creates a Loader that reads files only from the given snapshot.

A snapshot-based loader cannot install modules, so calling InstallModules on the return value will cause a panic.

A snapshot-based loader also has access only to configuration files. Its underlying parser does not have access to other files in the native filesystem, such as values files. For those, either use a normal loader (created by NewLoader) or use the configs.Parser API directly.

func (*Loader) CanInstallModules

func (l *Loader) CanInstallModules() bool

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 (*Loader) ImportSources added in v0.12.0

func (l *Loader) ImportSources(sources map[string][]byte)

ImportSources writes into the receiver's source code the given source code buffers.

This is useful in the situation where an ancillary loader is created for some reason (e.g. loading config from a plan file) but the cached source code from that loader must be imported into the "main" loader in order to return source code snapshots in diagnostic messages.

loader.ImportSources(otherLoader.Sources())

func (*Loader) ImportSourcesFromSnapshot added in v0.12.0

func (l *Loader) ImportSourcesFromSnapshot(snap *Snapshot)

ImportSourcesFromSnapshot writes into the receiver's source code the source files from the given snapshot.

This is similar to ImportSources but knows how to unpack and flatten a snapshot data structure to get the corresponding flat source file map.

func (*Loader) InitDirFromModule

func (l *Loader) InitDirFromModule(rootDir, sourceAddr string, hooks InstallHooks) hcl.Diagnostics

InitDirFromModule populates the given directory (which must exist and be empty) with the contents of the module at the given source address.

It does this by installing the given module and all of its descendent modules in a temporary root directory and then copying the installed files into suitable locations. As a consequence, any diagnostics it generates will reveal the location of this temporary directory to the user.

This rather roundabout installation approach is taken to ensure that installation proceeds in a manner identical to normal module installation.

If the given source address specifies a sub-directory of the given package then only the sub-directory and its descendents will be copied into the given root directory, which will cause any relative module references using ../ from that module to be unresolvable. Error diagnostics are produced in that case, to prompt the user to rewrite the source strings to be absolute references to the original remote module.

This can be installed only on a loder that can install modules, and will panic otherwise. Use CanInstallModules to determine if this method can be used, or refer to the documentation of that method for situations where install ability is guaranteed.

func (*Loader) InstallModules

func (l *Loader) InstallModules(rootDir string, upgrade bool, hooks InstallHooks) hcl.Diagnostics

InstallModules analyses the root module in the given directory and installs all of its direct and transitive dependencies into the loader's modules directory, which must already exist.

Since InstallModules makes possibly-time-consuming calls to remote services, a hook interface is supported to allow the caller to be notified when each module is installed and, for remote modules, when downloading begins. LoadConfig guarantees that two hook calls will not happen concurrently but it does not guarantee any particular ordering of hook calls. This mechanism is for UI feedback only and does not give the caller any control over the process.

If modules are already installed in the target directory, they will be skipped unless their source address or version have changed or unless the upgrade flag is set.

InstallModules never deletes any directory, except in the case where it needs to replace a directory that is already present with a newly-extracted package.

If the returned diagnostics contains errors then the module installation 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 (*Loader) IsConfigDir added in v0.12.0

func (l *Loader) IsConfigDir(path string) bool

IsConfigDir returns true if and only if the given directory contains at least one Terraform configuration file. This is a wrapper around calling the same method name on the loader's parser.

func (*Loader) LoadConfig

func (l *Loader) LoadConfig(rootDir string) (*configs.Config, hcl.Diagnostics)

LoadConfig reads the Terraform module in the given directory and uses it as the root module to build the static module tree that represents a configuration, assuming that all required descendent modules have already been installed.

If error diagnostics are returned, the returned configuration may be either nil or incomplete. In the latter case, cautious static analysis is possible in spite of the errors.

LoadConfig performs the basic syntax and uniqueness validations that are required to process the individual modules, and also detects

func (*Loader) LoadConfigWithSnapshot added in v0.12.0

func (l *Loader) LoadConfigWithSnapshot(rootDir string) (*configs.Config, *Snapshot, hcl.Diagnostics)

LoadConfigWithSnapshot is a variant of LoadConfig that also simultaneously creates an in-memory snapshot of the configuration files used, which can be later used to create a loader that may read only from this snapshot.

func (*Loader) Parser

func (l *Loader) Parser() *configs.Parser

Parser returns the underlying parser for this loader.

This is useful for loading other sorts of files than the module directories that a loader deals with, since then they will share the source code cache for this loader and can thus be shown as snippets in diagnostic messages.

func (*Loader) Sources

func (l *Loader) Sources() map[string][]byte

Sources returns the source code cache for the underlying parser of this loader. This is a shorthand for l.Parser().Sources().

type Snapshot added in v0.12.0

type Snapshot struct {
	// Modules is a map from opaque module keys (suitable for use as directory
	// names on all supported operating systems) to the snapshot information
	// about each module.
	Modules map[string]*SnapshotModule
}

Snapshot is an in-memory representation of the source files from a configuration, which can be used as an alternative configurations source for a loader with NewLoaderFromSnapshot.

The primary purpose of a Snapshot is to build the configuration portion of a plan file (see ../../plans/planfile) so that it can later be reloaded and used to recover the exact configuration that the plan was built from.

func NewEmptySnapshot added in v0.12.0

func NewEmptySnapshot() *Snapshot

NewEmptySnapshot constructs and returns a snapshot containing only an empty root module. This is not useful for anything except placeholders in tests.

type SnapshotModule added in v0.12.0

type SnapshotModule struct {
	// Dir is the path, relative to the root directory given when the
	// snapshot was created, where the module appears in the snapshot's
	// virtual filesystem.
	Dir string

	// Files is a map from each configuration file filename for the
	// module to a raw byte representation of the source file contents.
	Files map[string][]byte

	// SourceAddr is the source address given for this module in configuration.
	SourceAddr string `json:"Source"`

	// Version is the version of the module that is installed, or nil if
	// the module is installed from a source that does not support versions.
	Version *version.Version `json:"-"`
}

SnapshotModule represents a single module within a Snapshot.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL