-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13113 from hashicorp/backport/feature/build-metad…
…ata-phase-2/entirely-up-ghoul This pull request was automerged via backport-assistant
- Loading branch information
Showing
12 changed files
with
487 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package metadata | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
) | ||
|
||
type GithubActions struct{} | ||
|
||
func (g *GithubActions) Detect() error { | ||
_, ok := os.LookupEnv("GITHUB_ACTIONS") | ||
if !ok { | ||
return fmt.Errorf("GITHUB_ACTIONS environment variable not found") | ||
} | ||
return nil | ||
} | ||
|
||
func (g *GithubActions) Details() map[string]interface{} { | ||
env := make(map[string]interface{}) | ||
keys := []string{ | ||
"GITHUB_REPOSITORY", | ||
"GITHUB_REPOSITORY_ID", | ||
"GITHUB_WORKFLOW_URL", | ||
"GITHUB_SHA", | ||
"GITHUB_REF", | ||
"GITHUB_ACTOR", | ||
"GITHUB_ACTOR_ID", | ||
"GITHUB_TRIGGERING_ACTOR", | ||
"GITHUB_EVENT_NAME", | ||
"GITHUB_JOB", | ||
} | ||
|
||
for _, key := range keys { | ||
if value, ok := os.LookupEnv(key); ok { | ||
env[key] = value | ||
} | ||
} | ||
|
||
env["GITHUB_WORKFLOW_URL"] = fmt.Sprintf("%s/%s/actions/runs/%s", os.Getenv("GITHUB_SERVER_URL"), os.Getenv("GITHUB_REPOSITORY"), os.Getenv("GITHUB_RUN_ID")) | ||
return env | ||
} | ||
|
||
func (g *GithubActions) Type() string { | ||
return "github-actions" | ||
} | ||
|
||
type GitlabCI struct{} | ||
|
||
func (g *GitlabCI) Detect() error { | ||
_, ok := os.LookupEnv("GITLAB_CI") | ||
if !ok { | ||
return fmt.Errorf("GITLAB_CI environment variable not found") | ||
} | ||
return nil | ||
} | ||
|
||
func (g *GitlabCI) Details() map[string]interface{} { | ||
env := make(map[string]interface{}) | ||
keys := []string{ | ||
"CI_PROJECT_NAME", | ||
"CI_PROJECT_ID", | ||
"CI_PROJECT_URL", | ||
"CI_COMMIT_SHA", | ||
"CI_COMMIT_REF_NAME", | ||
"GITLAB_USER_NAME", | ||
"GITLAB_USER_ID", | ||
"CI_PIPELINE_SOURCE", | ||
"CI_PIPELINE_URL", | ||
"CI_JOB_URL", | ||
"CI_SERVER_NAME", | ||
"CI_REGISTRY_IMAGE", | ||
} | ||
|
||
for _, key := range keys { | ||
if value, ok := os.LookupEnv(key); ok { | ||
env[key] = value | ||
} | ||
} | ||
|
||
return env | ||
} | ||
|
||
func (g *GitlabCI) Type() string { | ||
return "gitlab-ci" | ||
} | ||
|
||
func GetCicdMetadata() map[string]interface{} { | ||
cicd := []MetadataProvider{ | ||
&GithubActions{}, | ||
&GitlabCI{}, | ||
} | ||
|
||
for _, c := range cicd { | ||
err := c.Detect() | ||
if err == nil { | ||
return map[string]interface{}{ | ||
"type": c.Type(), | ||
"details": c.Details(), | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package metadata | ||
|
||
import ( | ||
"log" | ||
"os/exec" | ||
"runtime" | ||
"strings" | ||
"time" | ||
) | ||
|
||
type OSInfo struct { | ||
Name string | ||
Arch string | ||
Version string | ||
} | ||
|
||
// CommandExecutor is an interface for executing commands. | ||
type CommandExecutor interface { | ||
Exec(name string, arg ...string) ([]byte, error) | ||
} | ||
|
||
// DefaultExecutor is the default implementation of CommandExecutor. | ||
type DefaultExecutor struct{} | ||
|
||
// Exec executes a command and returns the combined output. | ||
func (d DefaultExecutor) Exec(name string, arg ...string) ([]byte, error) { | ||
cmd := exec.Command(name, arg...) | ||
return cmd.CombinedOutput() | ||
} | ||
|
||
var executor CommandExecutor = DefaultExecutor{} | ||
|
||
func GetOSMetadata() map[string]interface{} { | ||
var osInfo OSInfo | ||
|
||
switch runtime.GOOS { | ||
case "windows": | ||
osInfo = GetInfoForWindows(executor) | ||
case "darwin": | ||
osInfo = GetInfo(executor, "-srm") | ||
case "linux": | ||
osInfo = GetInfo(executor, "-srio") | ||
case "freebsd": | ||
osInfo = GetInfo(executor, "-sri") | ||
case "openbsd": | ||
osInfo = GetInfo(executor, "-srm") | ||
case "netbsd": | ||
osInfo = GetInfo(executor, "-srm") | ||
default: | ||
osInfo = OSInfo{ | ||
Name: runtime.GOOS, | ||
Arch: runtime.GOARCH, | ||
} | ||
} | ||
|
||
return map[string]interface{}{ | ||
"type": osInfo.Name, | ||
"details": map[string]interface{}{ | ||
"arch": osInfo.Arch, | ||
"version": osInfo.Version, | ||
}, | ||
} | ||
} | ||
|
||
func GetInfo(exec CommandExecutor, flags string) OSInfo { | ||
out, err := uname(exec, flags) | ||
tries := 0 | ||
for strings.Contains(out, "broken pipe") && tries < 3 { | ||
out, err = uname(exec, flags) | ||
time.Sleep(500 * time.Millisecond) | ||
tries++ | ||
} | ||
if strings.Contains(out, "broken pipe") || err != nil { | ||
out = "" | ||
} | ||
|
||
if err != nil { | ||
log.Printf("[ERROR] failed to get the OS info: %s", err) | ||
} | ||
core := retrieveCore(out) | ||
return OSInfo{ | ||
Name: runtime.GOOS, | ||
Arch: runtime.GOARCH, | ||
Version: core, | ||
} | ||
} | ||
|
||
func uname(exec CommandExecutor, flags string) (string, error) { | ||
output, err := exec.Exec("uname", flags) | ||
return string(output), err | ||
} | ||
|
||
func retrieveCore(osStr string) string { | ||
osStr = strings.Replace(osStr, "\n", "", -1) | ||
osStr = strings.Replace(osStr, "\r\n", "", -1) | ||
osInfo := strings.Split(osStr, " ") | ||
|
||
var core string | ||
if len(osInfo) > 1 { | ||
core = osInfo[1] | ||
} | ||
return core | ||
} | ||
|
||
func GetInfoForWindows(exec CommandExecutor) OSInfo { | ||
out, err := exec.Exec("cmd", "ver") | ||
if err != nil { | ||
log.Printf("[ERROR] failed to get the OS info: %s", err) | ||
return OSInfo{ | ||
Name: runtime.GOOS, | ||
Arch: runtime.GOARCH, | ||
} | ||
} | ||
|
||
osStr := strings.Replace(string(out), "\n", "", -1) | ||
osStr = strings.Replace(osStr, "\r\n", "", -1) | ||
tmp1 := strings.Index(osStr, "[Version") | ||
tmp2 := strings.Index(osStr, "]") | ||
var ver string | ||
if tmp1 == -1 || tmp2 == -1 { | ||
ver = "" | ||
} else { | ||
ver = osStr[tmp1+9 : tmp2] | ||
} | ||
|
||
osInfo := OSInfo{ | ||
Name: runtime.GOOS, | ||
Arch: runtime.GOARCH, | ||
Version: ver, | ||
} | ||
return osInfo | ||
} |
Oops, something went wrong.