github.com/kevinklinger/open_terraform@v1.3.6/noninternal/providercache/dir_modify.go (about) 1 package providercache 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 8 "github.com/kevinklinger/open_terraform/noninternal/getproviders" 9 ) 10 11 // InstallPackage takes a metadata object describing a package available for 12 // installation, retrieves that package, and installs it into the receiving 13 // cache directory. 14 // 15 // If the allowedHashes set has non-zero length then at least one of the hashes 16 // in the set must match the package that "entry" refers to. If none of the 17 // hashes match then the returned error message assumes that the hashes came 18 // from a lock file. 19 func (d *Dir) InstallPackage(ctx context.Context, meta getproviders.PackageMeta, allowedHashes []getproviders.Hash) (*getproviders.PackageAuthenticationResult, error) { 20 if meta.TargetPlatform != d.targetPlatform { 21 return nil, fmt.Errorf("can't install %s package into cache directory expecting %s", meta.TargetPlatform, d.targetPlatform) 22 } 23 newPath := getproviders.UnpackedDirectoryPathForPackage( 24 d.baseDir, meta.Provider, meta.Version, d.targetPlatform, 25 ) 26 27 // Invalidate our metaCache so that subsequent read calls will re-scan to 28 // incorporate any changes we make here. 29 d.metaCache = nil 30 31 log.Printf("[TRACE] providercache.Dir.InstallPackage: installing %s v%s from %s", meta.Provider, meta.Version, meta.Location) 32 switch meta.Location.(type) { 33 case getproviders.PackageHTTPURL: 34 return installFromHTTPURL(ctx, meta, newPath, allowedHashes) 35 case getproviders.PackageLocalArchive: 36 return installFromLocalArchive(ctx, meta, newPath, allowedHashes) 37 case getproviders.PackageLocalDir: 38 return installFromLocalDir(ctx, meta, newPath, allowedHashes) 39 default: 40 // Should not get here, because the above should be exhaustive for 41 // all implementations of getproviders.Location. 42 return nil, fmt.Errorf("don't know how to install from a %T location", meta.Location) 43 } 44 } 45 46 // LinkFromOtherCache takes a CachedProvider value produced from another Dir 47 // and links it into the cache represented by the receiver Dir. 48 // 49 // This is used to implement tiered caching, where new providers are first 50 // populated into a system-wide shared cache and then linked from there into 51 // a configuration-specific local cache. 52 // 53 // It's invalid to link a CachedProvider from a particular Dir into that same 54 // Dir, because that would otherwise potentially replace a real package 55 // directory with a circular link back to itself. 56 // 57 // If the allowedHashes set has non-zero length then at least one of the hashes 58 // in the set must match the package that "entry" refers to. If none of the 59 // hashes match then the returned error message assumes that the hashes came 60 // from a lock file. 61 func (d *Dir) LinkFromOtherCache(entry *CachedProvider, allowedHashes []getproviders.Hash) error { 62 if len(allowedHashes) > 0 { 63 if matches, err := entry.MatchesAnyHash(allowedHashes); err != nil { 64 return fmt.Errorf( 65 "failed to calculate checksum for cached copy of %s %s in %s: %s", 66 entry.Provider, entry.Version, d.baseDir, err, 67 ) 68 } else if !matches { 69 return fmt.Errorf( 70 "the provider cache at %s has a copy of %s %s that doesn't match any of the checksums recorded in the dependency lock file", 71 d.baseDir, entry.Provider, entry.Version, 72 ) 73 } 74 } 75 76 newPath := getproviders.UnpackedDirectoryPathForPackage( 77 d.baseDir, entry.Provider, entry.Version, d.targetPlatform, 78 ) 79 currentPath := entry.PackageDir 80 log.Printf("[TRACE] providercache.Dir.LinkFromOtherCache: linking %s v%s from existing cache %s to %s", entry.Provider, entry.Version, currentPath, newPath) 81 82 // Invalidate our metaCache so that subsequent read calls will re-scan to 83 // incorporate any changes we make here. 84 d.metaCache = nil 85 86 // We re-use the process of installing from a local directory here, because 87 // the two operations are fundamentally the same: symlink if possible, 88 // deep-copy otherwise. 89 meta := getproviders.PackageMeta{ 90 Provider: entry.Provider, 91 Version: entry.Version, 92 93 // FIXME: How do we populate this? 94 ProtocolVersions: nil, 95 TargetPlatform: d.targetPlatform, 96 97 // Because this is already unpacked, the filename is synthetic 98 // based on the standard naming scheme. 99 Filename: fmt.Sprintf("terraform-provider-%s_%s_%s.zip", 100 entry.Provider.Type, entry.Version, d.targetPlatform), 101 Location: getproviders.PackageLocalDir(currentPath), 102 } 103 // No further hash check here because we already checked the hash 104 // of the source directory above. 105 _, err := installFromLocalDir(context.TODO(), meta, newPath, nil) 106 return err 107 }