mirror of https://github.com/hashicorp/packer
parent
749162e0c0
commit
73e0167a57
@ -0,0 +1,103 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
type CICD interface {
|
||||
Detect() bool
|
||||
Env() map[string]string
|
||||
Type() string
|
||||
}
|
||||
|
||||
type GithubActions struct{}
|
||||
|
||||
func (g *GithubActions) Detect() bool {
|
||||
_, ok := os.LookupEnv("GITHUB_ACTIONS")
|
||||
return ok
|
||||
}
|
||||
|
||||
func (g *GithubActions) Env() map[string]string {
|
||||
env := make(map[string]string)
|
||||
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() bool {
|
||||
_, ok := os.LookupEnv("GITLAB_CI")
|
||||
return ok
|
||||
}
|
||||
|
||||
func (g *GitlabCI) Env() map[string]string {
|
||||
env := make(map[string]string)
|
||||
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 := []CICD{
|
||||
&GithubActions{},
|
||||
&GitlabCI{},
|
||||
}
|
||||
|
||||
for _, c := range cicd {
|
||||
if c.Detect() {
|
||||
return map[string]interface{}{
|
||||
"type": c.Type(),
|
||||
"details": c.Env(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -0,0 +1,129 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type OSInfo struct {
|
||||
Name string
|
||||
Arch string
|
||||
Version string
|
||||
}
|
||||
|
||||
func GetOSMetadata() map[string]interface{} {
|
||||
var osInfo OSInfo
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
osInfo = GetInfoForWindows()
|
||||
case "darwin":
|
||||
osInfo = GetInfo("-srm")
|
||||
case "linux":
|
||||
osInfo = GetInfo("-srio")
|
||||
case "freebsd":
|
||||
osInfo = GetInfo("-sri")
|
||||
case "openbsd":
|
||||
osInfo = GetInfo("-srm")
|
||||
case "netbsd":
|
||||
osInfo = GetInfo("-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(flags string) OSInfo {
|
||||
out, err := _uname(flags)
|
||||
tries := 0
|
||||
for strings.Contains(out, "broken pipe") && tries < 3 {
|
||||
out, err = _uname(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(flags string) (string, error) {
|
||||
cmd := exec.Command("uname", flags)
|
||||
cmd.Stdin = strings.NewReader("some input")
|
||||
var out bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
cmd.Stderr = &stderr
|
||||
err := cmd.Run()
|
||||
return out.String(), 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() OSInfo {
|
||||
cmd := exec.Command("cmd", "ver")
|
||||
cmd.Stdin = strings.NewReader("some input")
|
||||
var out bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
cmd.Stderr = &stderr
|
||||
err := cmd.Run()
|
||||
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(out.String(), "\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
|
||||
}
|
||||
@ -0,0 +1,93 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
gt "github.com/go-git/go-git/v5"
|
||||
)
|
||||
|
||||
type VCS interface {
|
||||
Detect(wd string) error
|
||||
Details() map[string]interface{}
|
||||
Type() string
|
||||
}
|
||||
|
||||
type Git struct {
|
||||
repo *gt.Repository
|
||||
}
|
||||
|
||||
func (g *Git) Detect(wd string) error {
|
||||
repo, err := gt.PlainOpenWithOptions(wd, >.PlainOpenOptions{DetectDotGit: true})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
g.repo = repo
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Git) hasUncommittedChanges() bool {
|
||||
worktree, err := g.repo.Worktree()
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] failed to get the git worktree: %s", err)
|
||||
return false
|
||||
}
|
||||
|
||||
status, err := worktree.Status()
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] failed to get the git worktree status: %s", err)
|
||||
return false
|
||||
}
|
||||
return !status.IsClean()
|
||||
}
|
||||
|
||||
func (g *Git) Type() string {
|
||||
return "git"
|
||||
}
|
||||
|
||||
func (g *Git) Details() map[string]interface{} {
|
||||
resp := map[string]interface{}{}
|
||||
|
||||
headRef, err := g.repo.Head()
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] failed to get the git branch name: %s", err)
|
||||
} else {
|
||||
resp["ref"] = headRef.Name().Short()
|
||||
}
|
||||
|
||||
commit, err := g.repo.CommitObject(headRef.Hash())
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] failed to get the git commit hash: %s", err)
|
||||
} else {
|
||||
resp["commit"] = commit.Hash.String()
|
||||
resp["author"] = commit.Author.Name + " <" + commit.Author.Email + ">"
|
||||
}
|
||||
|
||||
resp["has_uncommitted_changes"] = g.hasUncommittedChanges()
|
||||
return resp
|
||||
}
|
||||
|
||||
func GetVcsMetadata() map[string]interface{} {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] unable to retrieve current directory: %s", err)
|
||||
return map[string]interface{}{}
|
||||
}
|
||||
|
||||
vcsSystems := []VCS{
|
||||
&Git{},
|
||||
}
|
||||
|
||||
for _, vcs := range vcsSystems {
|
||||
err := vcs.Detect(wd)
|
||||
if err == nil {
|
||||
return map[string]interface{}{
|
||||
"type": vcs.Type(),
|
||||
"details": vcs.Details(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Loading…
Reference in new issue