Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 28 additions & 12 deletions internal/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -314,28 +315,43 @@ func fetchAPIResources() ([]string, error) {
return lines, nil
}

func IsInStackroxRepository() bool {
// TODO(#91): This assumes that:
// - origin is the name of the upstream remote (not true if someone cloned their fork)
// - the git transport was used
// How about instead looking for "# StackRox Kubernetes Security Platform" in README?
cmd := exec.Command("git", "remote", "get-url", "origin")
outputBytes, err := cmd.Output()
if err != nil {
func IsInStackroxRepository(log *logger.Logger) bool {
out, err := exec.Command("git", "remote", "-v").Output()
if exitErr, ok := errors.AsType[*exec.ExitError](err); ok {
log.Dimf("Not a git repository, ignoring ('git remote' returned %d)", exitErr.ExitCode())
return false
}
outputLines := strings.Split(string(outputBytes), "\n")
if len(outputLines) == 0 {
if err != nil {
log.Dimf("Invoking 'git remote' failed: %v", err)
return false
}
return outputLines[0] == "git@github.com:stackrox/stackrox.git"
for line := range strings.SplitSeq(string(out), "\n") {
fields := strings.Fields(line)
if len(fields) < 2 {
continue
}
remote := fields[1]
if isStackRoxRepositoryRemote(remote) {
log.Dimf("Identified repository as a clone of stackrox/stackrox based on the configured git remote %q", remote)
return true
}
}
log.Dim("Repository does not seem to be a clone of stackrox/stackrox based on the configured git remotes")
return false
}

var stackroxRepoPattern = regexp.MustCompile(`[/:]stackrox/stackrox(\.git)?$`)

func isStackRoxRepositoryRemote(remote string) bool {
return stackroxRepoPattern.MatchString(remote)
}

func GetStackroxRepositoryTag() (string, error) {
func GetStackroxRepositoryTag(log *logger.Logger) (string, error) {
topLevelDir, err := getStackRoxTopLevelDir()
if err != nil {
return "", fmt.Errorf("getting stackrox top level directory: %w", err)
}
log.Dimf("Invoking 'make tag' in directory %q", topLevelDir)
cmd := exec.Command("make", "-s", "-C", topLevelDir, "tag")
outputBytes, err := cmd.Output()
if err != nil {
Expand Down
27 changes: 27 additions & 0 deletions internal/env/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,33 @@ func TestClusterTypeString(t *testing.T) {
}
}

func TestIsStackRoxRepositoryRemote(t *testing.T) {
tests := []struct {
remote string
want bool
}{
{"git@github.com:stackrox/stackrox.git", true},
{"git@github.com:stackrox/stackrox", true},
{"https://github.com/stackrox/stackrox.git", true},
{"https://github.com/stackrox/stackrox", true},
{"ssh://git@github.com/stackrox/stackrox.git", true},
{"ssh://git@github.com/stackrox/stackrox", true},
{"git@github.com:someone/stackrox.git", false},
{"git@github.com:stackrox/other.git", false},
{"git@github.com:foo-stackrox/stackrox-bar.git", false},
{"git@github.com:foo-stackrox/stackrox.git", false},
{"git@github.com:stackrox/stackrox-bar.git", false},
{"", false},
}

for _, tt := range tests {
t.Run(tt.remote, func(t *testing.T) {
got := isStackRoxRepositoryRemote(tt.remote)
assert.Equal(t, tt.want, got, "isStackRoxRepositoryRemote(%q)", tt.remote)
})
}
}

func TestDefaultDetector_Detect(t *testing.T) {
tests := []struct {
name string
Expand Down
17 changes: 10 additions & 7 deletions internal/helpers/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,32 @@ import (
)

func LookupMainImageTag(ctx context.Context, log *logger.Logger) (string, error) {
log.Info("Looking up main image tag")
log.Dim("Checking if main image tag is defined in the environment")
if tag := os.Getenv("MAIN_IMAGE_TAG"); tag != "" {
log.Dimf("Using MAIN_IMAGE_TAG from environment: %s", tag)
log.Infof("Using MAIN_IMAGE_TAG from environment: %s", tag)
return tag, nil
}
if env.IsInStackroxRepository() {
tag, err := env.GetStackroxRepositoryTag()
log.Dim("Checking if current working directory is checkout of stackrox/stackrox repository")
if env.IsInStackroxRepository(log) {
tag, err := env.GetStackroxRepositoryTag(log)
if err != nil {
log.Dimf("Error retrieving stackrox repository tag: %v", err)
return "", err
}
log.Dimf("Using stackrox repository tag: %s", tag)
log.Infof("Using stackrox repository tag: %s", tag)
return tag, nil
}

log.Warningf("No MAIN_IMAGE_TAG found in the environment, looking up latest release tag on registry")
log.Warning("To use a different tag, set the MAIN_IMAGE_TAG environment variable")
log.Warning("No tag specific and no MAIN_IMAGE_TAG found in the environment, looking up latest release tag on registry")
log.Warning("To use a different tag, use `--tag` or set the MAIN_IMAGE_TAG environment variable")
log.Warning("Alternatively, execute roxie from within the stackrox repository, in which case the currently checked out stackrox tag will be used")

log.Dim("Checking what the latest released version tag is")
latestTag, err := LookupLatestTag(ctx, log)
if err != nil {
return "", fmt.Errorf("looking up latest release tag: %w", err)
}
log.Infof("Using latest released tag %v", latestTag)

return latestTag, nil
}
Expand Down
Loading