github.com/iaas-resource-provision/iaas-rpc@v1.0.7-0.20211021023331-ed21f798c408/internal/command/plugins_lock.go (about)

     1  package command
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"log"
     8  	"path/filepath"
     9  )
    10  
    11  func (m *Meta) providerPluginsLock() *pluginSHA256LockFile {
    12  	return &pluginSHA256LockFile{
    13  		Filename: filepath.Join(m.pluginDir(), "lock.json"),
    14  	}
    15  }
    16  
    17  type pluginSHA256LockFile struct {
    18  	Filename string
    19  }
    20  
    21  // Read loads the lock information from the file and returns it. If the file
    22  // cannot be read, an empty map is returned to indicate that _no_ providers
    23  // are acceptable, since the user must run "terraform init" to lock some
    24  // providers before a context can be created.
    25  func (pf *pluginSHA256LockFile) Read() map[string][]byte {
    26  	// Returning an empty map is different than nil because it causes
    27  	// us to reject all plugins as uninitialized, rather than applying no
    28  	// constraints at all.
    29  	//
    30  	// We don't surface any specific errors here because we want it to all
    31  	// roll up into our more-user-friendly error that appears when plugin
    32  	// constraint verification fails during context creation.
    33  	digests := make(map[string][]byte)
    34  
    35  	buf, err := ioutil.ReadFile(pf.Filename)
    36  	if err != nil {
    37  		// This is expected if the user runs any context-using command before
    38  		// running "terraform init".
    39  		log.Printf("[INFO] Failed to read plugin lock file %s: %s", pf.Filename, err)
    40  		return digests
    41  	}
    42  
    43  	var strDigests map[string]string
    44  	err = json.Unmarshal(buf, &strDigests)
    45  	if err != nil {
    46  		// This should never happen unless the user directly edits the file.
    47  		log.Printf("[WARN] Plugin lock file %s failed to parse as JSON: %s", pf.Filename, err)
    48  		return digests
    49  	}
    50  
    51  	for name, strDigest := range strDigests {
    52  		var digest []byte
    53  		_, err := fmt.Sscanf(strDigest, "%x", &digest)
    54  		if err == nil {
    55  			digests[name] = digest
    56  		} else {
    57  			// This should never happen unless the user directly edits the file.
    58  			log.Printf("[WARN] Plugin lock file %s has invalid digest for %q", pf.Filename, name)
    59  		}
    60  	}
    61  
    62  	return digests
    63  }