github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/checkpoint.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package main 5 6 import ( 7 "context" 8 "fmt" 9 "log" 10 "path/filepath" 11 12 "github.com/hashicorp/go-checkpoint" 13 "github.com/terramate-io/tf/command" 14 "github.com/terramate-io/tf/command/cliconfig" 15 "go.opentelemetry.io/otel/codes" 16 ) 17 18 func init() { 19 checkpointResult = make(chan *checkpoint.CheckResponse, 1) 20 } 21 22 var checkpointResult chan *checkpoint.CheckResponse 23 24 // runCheckpoint runs a HashiCorp Checkpoint request. You can read about 25 // Checkpoint here: https://github.com/hashicorp/go-checkpoint. 26 func runCheckpoint(ctx context.Context, c *cliconfig.Config) { 27 // If the user doesn't want checkpoint at all, then return. 28 if c.DisableCheckpoint { 29 log.Printf("[INFO] Checkpoint disabled. Not running.") 30 checkpointResult <- nil 31 return 32 } 33 34 ctx, span := tracer.Start(ctx, "HashiCorp Checkpoint") 35 _ = ctx // prevent staticcheck from complaining to avoid a maintenence hazard of having the wrong ctx in scope here 36 defer span.End() 37 38 configDir, err := cliconfig.ConfigDir() 39 if err != nil { 40 log.Printf("[ERR] Checkpoint setup error: %s", err) 41 checkpointResult <- nil 42 return 43 } 44 45 version := Version 46 if VersionPrerelease != "" { 47 version += fmt.Sprintf("-%s", VersionPrerelease) 48 } 49 50 signaturePath := filepath.Join(configDir, "checkpoint_signature") 51 if c.DisableCheckpointSignature { 52 log.Printf("[INFO] Checkpoint signature disabled") 53 signaturePath = "" 54 } 55 56 resp, err := checkpoint.Check(&checkpoint.CheckParams{ 57 Product: "terraform", 58 Version: version, 59 SignatureFile: signaturePath, 60 CacheFile: filepath.Join(configDir, "checkpoint_cache"), 61 }) 62 if err != nil { 63 log.Printf("[ERR] Checkpoint error: %s", err) 64 span.SetStatus(codes.Error, err.Error()) 65 resp = nil 66 } else { 67 span.SetStatus(codes.Ok, "checkpoint request succeeded") 68 } 69 70 checkpointResult <- resp 71 } 72 73 // commandVersionCheck implements command.VersionCheckFunc and is used 74 // as the version checker. 75 func commandVersionCheck() (command.VersionCheckInfo, error) { 76 // Wait for the result to come through 77 info := <-checkpointResult 78 if info == nil { 79 var zero command.VersionCheckInfo 80 return zero, nil 81 } 82 83 // Build the alerts that we may have received about our version 84 alerts := make([]string, len(info.Alerts)) 85 for i, a := range info.Alerts { 86 alerts[i] = a.Message 87 } 88 89 return command.VersionCheckInfo{ 90 Outdated: info.Outdated, 91 Latest: info.CurrentVersion, 92 Alerts: alerts, 93 }, nil 94 }