2020-03-12 02:00:43 +01:00
|
|
|
package providercache
|
|
|
|
|
|
|
|
import (
|
2020-03-13 22:46:44 +01:00
|
|
|
"context"
|
2020-03-12 02:00:43 +01:00
|
|
|
"fmt"
|
2020-03-25 20:22:39 +01:00
|
|
|
"log"
|
2020-03-12 02:00:43 +01:00
|
|
|
|
|
|
|
"github.com/hashicorp/terraform/internal/getproviders"
|
|
|
|
)
|
|
|
|
|
2020-03-12 02:10:25 +01:00
|
|
|
// InstallPackage takes a metadata object describing a package available for
|
|
|
|
// installation, retrieves that package, and installs it into the receiving
|
|
|
|
// cache directory.
|
2020-03-13 22:46:44 +01:00
|
|
|
func (d *Dir) InstallPackage(ctx context.Context, meta getproviders.PackageMeta) error {
|
|
|
|
if meta.TargetPlatform != d.targetPlatform {
|
|
|
|
return fmt.Errorf("can't install %s package into cache directory expecting %s", meta.TargetPlatform, d.targetPlatform)
|
|
|
|
}
|
|
|
|
newPath := getproviders.UnpackedDirectoryPathForPackage(
|
|
|
|
d.baseDir, meta.Provider, meta.Version, d.targetPlatform,
|
|
|
|
)
|
|
|
|
|
2020-03-27 00:05:27 +01:00
|
|
|
// Invalidate our metaCache so that subsequent read calls will re-scan to
|
|
|
|
// incorporate any changes we make here.
|
|
|
|
d.metaCache = nil
|
|
|
|
|
2020-04-03 21:11:57 +02:00
|
|
|
// TODO: If meta.Authentication is non-nil, we should call it at some point
|
|
|
|
// in the rest of this process (perhaps inside installFromLocalArchive and
|
|
|
|
// installFromLocalDir, so we already have the local copy?) and return an
|
|
|
|
// error if the authentication fails.
|
|
|
|
|
2020-03-25 20:22:39 +01:00
|
|
|
log.Printf("[TRACE] providercache.Dir.InstallPackage: installing %s v%s from %s", meta.Provider, meta.Version, meta.Location)
|
2020-03-13 22:46:44 +01:00
|
|
|
switch location := meta.Location.(type) {
|
|
|
|
case getproviders.PackageHTTPURL:
|
|
|
|
return installFromHTTPURL(ctx, string(location), newPath)
|
|
|
|
case getproviders.PackageLocalArchive:
|
|
|
|
return installFromLocalArchive(ctx, string(location), newPath)
|
|
|
|
case getproviders.PackageLocalDir:
|
|
|
|
return installFromLocalDir(ctx, string(location), newPath)
|
|
|
|
default:
|
|
|
|
// Should not get here, because the above should be exhaustive for
|
|
|
|
// all implementations of getproviders.Location.
|
|
|
|
return fmt.Errorf("don't know how to install from a %T location", location)
|
|
|
|
}
|
2020-03-12 02:10:25 +01:00
|
|
|
}
|
|
|
|
|
2020-03-12 02:00:43 +01:00
|
|
|
// LinkFromOtherCache takes a CachedProvider value produced from another Dir
|
|
|
|
// and links it into the cache represented by the receiver Dir.
|
|
|
|
//
|
|
|
|
// This is used to implement tiered caching, where new providers are first
|
|
|
|
// populated into a system-wide shared cache and then linked from there into
|
|
|
|
// a configuration-specific local cache.
|
|
|
|
//
|
|
|
|
// It's invalid to link a CachedProvider from a particular Dir into that same
|
|
|
|
// Dir, because that would otherwise potentially replace a real package
|
|
|
|
// directory with a circular link back to itself.
|
|
|
|
func (d *Dir) LinkFromOtherCache(entry *CachedProvider) error {
|
|
|
|
newPath := getproviders.UnpackedDirectoryPathForPackage(
|
|
|
|
d.baseDir, entry.Provider, entry.Version, d.targetPlatform,
|
|
|
|
)
|
|
|
|
currentPath := entry.PackageDir
|
2020-03-25 20:22:39 +01:00
|
|
|
log.Printf("[TRACE] providercache.Dir.LinkFromOtherCache: linking %s v%s from existing cache %s to %s", entry.Provider, entry.Version, currentPath, newPath)
|
2020-03-12 02:00:43 +01:00
|
|
|
|
|
|
|
// Invalidate our metaCache so that subsequent read calls will re-scan to
|
|
|
|
// incorporate any changes we make here.
|
|
|
|
d.metaCache = nil
|
|
|
|
|
2020-04-01 19:25:48 +02:00
|
|
|
// We re-use the process of installing from a local directory here, because
|
|
|
|
// the two operations are fundamentally the same: symlink if possible,
|
|
|
|
// deep-copy otherwise.
|
|
|
|
return installFromLocalDir(context.TODO(), currentPath, newPath)
|
2020-03-12 02:00:43 +01:00
|
|
|
}
|