github.com/hugorut/terraform@v1.1.3/src/providercache/installer_events.go (about)

     1  package providercache
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/hugorut/terraform/src/addrs"
     7  	"github.com/hugorut/terraform/src/getproviders"
     8  )
     9  
    10  // InstallerEvents is a collection of function references that can be
    11  // associated with an Installer object in order to be notified about various
    12  // installation lifecycle events during an install operation.
    13  //
    14  // The set of supported events is primarily motivated by allowing ongoing
    15  // progress reports in the UI of the command running provider installation,
    16  // and so this only exposes information interesting to display and does not
    17  // allow the recipient of the events to influence the ongoing process.
    18  //
    19  // Any of the fields may be left as nil to signal that the caller is not
    20  // interested in the associated event. It's better to leave a field set to
    21  // nil than to assign a do-nothing function into it because the installer
    22  // may choose to skip preparing certain temporary data structures if it can see
    23  // that a particular event is not used.
    24  type InstallerEvents struct {
    25  	// The PendingProviders event is called prior to other events to give
    26  	// the recipient prior notice of the full set of distinct provider
    27  	// addresses it can expect to see mentioned in the other events.
    28  	//
    29  	// A recipient driving a UI might, for example, use this to pre-allocate
    30  	// UI space for status reports for all of the providers and then update
    31  	// those positions in-place as other events arrive.
    32  	PendingProviders func(reqs map[addrs.Provider]getproviders.VersionConstraints)
    33  
    34  	// ProviderAlreadyInstalled is called for any provider that was included
    35  	// in PendingProviders but requires no further action because a suitable
    36  	// version is already present in the local provider cache directory.
    37  	//
    38  	// This event can also appear after the QueryPackages... series if
    39  	// querying determines that a version already available is the newest
    40  	// available version.
    41  	ProviderAlreadyInstalled func(provider addrs.Provider, selectedVersion getproviders.Version)
    42  
    43  	// The BuiltInProvider... family of events describe the outcome for any
    44  	// requested providers that are built in to Terraform. Only one of these
    45  	// methods will be called for each such provider, and no other method
    46  	// will be called for them except that they are included in the
    47  	// aggregate PendingProviders map.
    48  	//
    49  	// The "Available" event reports that the requested builtin provider is
    50  	// available in this release of Terraform. The "Failure" event reports
    51  	// either that the provider is unavailable or that the request for it
    52  	// is invalid somehow.
    53  	BuiltInProviderAvailable func(provider addrs.Provider)
    54  	BuiltInProviderFailure   func(provider addrs.Provider, err error)
    55  
    56  	// The QueryPackages... family of events delimit the operation of querying
    57  	// a provider source for information about available packages matching
    58  	// a particular version constraint, prior to selecting a single version
    59  	// to install.
    60  	//
    61  	// A particular install operation includes only one query per distinct
    62  	// provider, so a caller can use the provider argument as a unique
    63  	// identifier to correlate between successive events.
    64  	//
    65  	// The Begin, Success, and Failure events will each occur only once per
    66  	// distinct provider.
    67  	//
    68  	// The Warning event is unique to the registry source
    69  	QueryPackagesBegin   func(provider addrs.Provider, versionConstraints getproviders.VersionConstraints, locked bool)
    70  	QueryPackagesSuccess func(provider addrs.Provider, selectedVersion getproviders.Version)
    71  	QueryPackagesFailure func(provider addrs.Provider, err error)
    72  	QueryPackagesWarning func(provider addrs.Provider, warn []string)
    73  
    74  	// The LinkFromCache... family of events delimit the operation of linking
    75  	// a selected provider package from the system-wide shared cache into the
    76  	// current configuration's local cache.
    77  	//
    78  	// This sequence occurs instead of the FetchPackage... sequence if the
    79  	// QueryPackages... sequence selects a version that is already in the
    80  	// system-wide cache, and thus we will skip fetching it from the
    81  	// originating provider source and take it from the shared cache instead.
    82  	//
    83  	// Linking should, in most cases, be a much faster operation than
    84  	// fetching. However, it could still potentially be slow in some unusual
    85  	// cases like a particularly large source package on a system where symlinks
    86  	// are impossible, or when either of the cache directories are on a network
    87  	// filesystem accessed over a slow link.
    88  	LinkFromCacheBegin   func(provider addrs.Provider, version getproviders.Version, cacheRoot string)
    89  	LinkFromCacheSuccess func(provider addrs.Provider, version getproviders.Version, localDir string)
    90  	LinkFromCacheFailure func(provider addrs.Provider, version getproviders.Version, err error)
    91  
    92  	// The FetchPackage... family of events delimit the operation of retrieving
    93  	// a package from a particular source location.
    94  	//
    95  	// A particular install operation includes only one fetch per distinct
    96  	// provider, so a caller can use the provider argument as a unique
    97  	// identifier to correlate between successive events.
    98  	//
    99  	// A particular provider will either notify the LinkFromCache... events
   100  	// or the FetchPackage... events, never both in the same install operation.
   101  	//
   102  	// The Query, Begin, Success, and Failure events will each occur only once
   103  	// per distinct provider.
   104  	FetchPackageMeta    func(provider addrs.Provider, version getproviders.Version) // fetching metadata prior to real download
   105  	FetchPackageBegin   func(provider addrs.Provider, version getproviders.Version, location getproviders.PackageLocation)
   106  	FetchPackageSuccess func(provider addrs.Provider, version getproviders.Version, localDir string, authResult *getproviders.PackageAuthenticationResult)
   107  	FetchPackageFailure func(provider addrs.Provider, version getproviders.Version, err error)
   108  
   109  	// The ProvidersFetched event is called after all fetch operations if at
   110  	// least one provider was fetched successfully.
   111  	ProvidersFetched func(authResults map[addrs.Provider]*getproviders.PackageAuthenticationResult)
   112  
   113  	// HashPackageFailure is called if the installer is unable to determine
   114  	// the hash of the contents of an installed package after installation.
   115  	// In that case, the selection will not be recorded in the target cache
   116  	// directory's lock file.
   117  	HashPackageFailure func(provider addrs.Provider, version getproviders.Version, err error)
   118  }
   119  
   120  // OnContext produces a context with all of the same behaviors as the given
   121  // context except that it will additionally carry the receiving
   122  // InstallerEvents.
   123  //
   124  // Passing the resulting context to an installer request will cause the
   125  // installer to send event notifications via the callbacks inside.
   126  func (e *InstallerEvents) OnContext(ctx context.Context) context.Context {
   127  	return context.WithValue(ctx, ctxInstallerEvents, e)
   128  }
   129  
   130  // installerEventsForContext looks on the given context for a registered
   131  // InstallerEvents and returns a pointer to it if so.
   132  //
   133  // For caller convenience, if there is no events object attached to the
   134  // given context this function will construct one that has all of its
   135  // fields set to nil and return that, freeing the caller from having to
   136  // do a nil check on the result before dereferencing it.
   137  func installerEventsForContext(ctx context.Context) *InstallerEvents {
   138  	v := ctx.Value(ctxInstallerEvents)
   139  	if v != nil {
   140  		return v.(*InstallerEvents)
   141  	}
   142  	return &InstallerEvents{}
   143  }
   144  
   145  type ctxInstallerEventsType int
   146  
   147  const ctxInstallerEvents = ctxInstallerEventsType(0)