Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up output, implement timeout, do not update the whole index when deploying a branch #127

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
3 changes: 2 additions & 1 deletion g10k.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,11 @@ type ForgeResult struct {
fileSize int64
}

// ExecResult contains the exit code and output of an external command (e.g. git)
// ExecResult contains the exit code, output of an external command (e.g. git), and the error (if any)
type ExecResult struct {
returnCode int
output string
err error
}

func init() {
Expand Down
14 changes: 9 additions & 5 deletions git.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func resolveGitRepositories(uniqueGitModules map[string]GitModule) {
repoDir := strings.Replace(strings.Replace(url, "/", "_", -1), ":", "-", -1)
workDir := config.ModulesCacheDir + repoDir

doMirrorOrUpdate(url, workDir, privateKey, gm.ignoreUnreachable, 1)
doMirrorOrUpdate(url, workDir, privateKey, "", gm.ignoreUnreachable, 1)
// doCloneOrPull(source, workDir, targetDir, sa.Remote, branch, sa.PrivateKey)
}(url, privateKey, gm, bar)
done <- true
Expand All @@ -89,16 +89,20 @@ func resolveGitRepositories(uniqueGitModules map[string]GitModule) {
wg.Wait()
}

func doMirrorOrUpdate(url string, workDir string, sshPrivateKey string, allowFail bool, retryCount int) bool {
func doMirrorOrUpdate(url string, workDir string, sshPrivateKey string, envBranch string, allowFail bool, retryCount int) bool {
needSSHKey := true
if strings.Contains(url, "github.com") || len(sshPrivateKey) == 0 {
needSSHKey = false
}

er := ExecResult{}
gitCmd := "git clone --mirror " + url + " " + workDir
gitCmd := fmt.Sprintf(`git clone --mirror %s %s && git --git-dir %s remote update --prune`, url, workDir, workDir)
if isDir(workDir) {
gitCmd = "git --git-dir " + workDir + " remote update --prune"
if envBranch == "" {
gitCmd = "git --git-dir " + workDir + " remote update --prune"
} else {
gitCmd = "git --git-dir " + workDir + " fetch --force origin " + envBranch + ":" + envBranch
}
}

if needSSHKey {
Expand All @@ -114,7 +118,7 @@ func doMirrorOrUpdate(url string, workDir string, sshPrivateKey string, allowFai
} else if config.RetryGitCommands && retryCount > 0 {
Warnf("WARN: git command failed: " + gitCmd + " deleting local cached repository and retrying...")
purgeDir(workDir, "doMirrorOrUpdate, because git command failed, retrying")
return doMirrorOrUpdate(url, workDir, sshPrivateKey, false, retryCount-1)
return doMirrorOrUpdate(url, workDir, sshPrivateKey, envBranch, false, retryCount-1)
}
Warnf("WARN: git repository " + url + " does not exist or is unreachable at this moment!")
return false
Expand Down
23 changes: 19 additions & 4 deletions helper.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"context"
"crypto/sha256"
"fmt"
"io"
Expand Down Expand Up @@ -165,7 +166,6 @@ func purgeDir(dir string, callingFunction string) {
}

func executeCommand(command string, timeout int, allowFail bool) ExecResult {
Debugf("Executing " + command)
parts := strings.SplitN(command, " ", 2)
cmd := parts[0]
cmdArgs := []string{}
Expand All @@ -178,10 +178,26 @@ func executeCommand(command string, timeout int, allowFail bool) ExecResult {
}
}

var ctx context.Context
var cancel context.CancelFunc
if timeout > 0 {
ctx, cancel = context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
} else {
ctx = context.Background()
}

before := time.Now()
out, err := exec.Command(cmd, cmdArgs...).CombinedOutput()
out, err := exec.CommandContext(ctx, cmd, cmdArgs...).CombinedOutput()
duration := time.Since(before).Seconds()
er := ExecResult{0, string(out)}

var errmsg string
if err != nil {
errmsg = err.Error()
}
Debugf("Executing " + command + " gave output: " + string(out) + ", and error: " + errmsg)

er := ExecResult{0, string(out), err}
if msg, ok := err.(*exec.ExitError); ok { // there is error code
er.returnCode = msg.Sys().(syscall.WaitStatus).ExitStatus()
}
Expand All @@ -200,7 +216,6 @@ func executeCommand(command string, timeout int, allowFail bool) ExecResult {
}
} else {
er.returnCode = 1
er.output = fmt.Sprint(err)
Copy link
Owner

@xorpaul xorpaul Apr 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you want to print the error output if there was an error?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error and the program's output are two different things. We don't want to overwrite the actual output if it was there and that's why another field, err has been introduced to ExecResult.

}
}
return er
Expand Down
2 changes: 1 addition & 1 deletion puppetfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func resolvePuppetEnvironment(envBranch string, tags bool, outputNameTag string)
// check if sa.Basedir exists
checkDirAndCreate(sa.Basedir, "basedir")

if success := doMirrorOrUpdate(sa.Remote, workDir, sa.PrivateKey, true, 1); success {
if success := doMirrorOrUpdate(sa.Remote, workDir, sa.PrivateKey, envBranch, true, 1); success {

// get all branches
er := executeCommand("git --git-dir "+workDir+" branch", config.Timeout, false)
Expand Down