Last active
October 30, 2018 02:38
-
-
Save kylebrandt/6860ae8de43edc917392cc3ed6d9fde4 to your computer and use it in GitHub Desktop.
Bosun git saving and pulling
This file contains hidden or 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
package main | |
import ( | |
"fmt" | |
"log" | |
"os" | |
"path/filepath" | |
"<replaceme>/bogit/util" | |
) | |
const Git = "git" | |
func main() { | |
if len(os.Args) < 4 { | |
log.Fatal("error: not enough arguments, expected filename, user, message") | |
} | |
fileArg := os.Args[1] | |
user := os.Args[2] | |
message := os.Args[3] | |
if fileArg == "" { | |
log.Fatal("error: missing config file name") | |
} | |
if user == "" { | |
log.Fatal("error: missing user") | |
} | |
if message == "" { | |
log.Fatal("error: missing message") | |
} | |
fileDir := filepath.Dir(fileArg) | |
gitCommand := util.GetGitExecuter("git", fileDir, "/opt/bosun/id_rsa") | |
// We clean (except maybe other files) | |
output, err := gitCommand("status", "-uno", "--porcelain") | |
if err != nil { | |
log.Fatal(fmt.Sprintf("failed to get git status to see if the working tree is clean")) | |
} | |
if output == "" { | |
log.Println("nothing to do since the working tree is clean") | |
os.Exit(0) | |
} | |
// Commit | |
output, err = gitCommand("commit", "-a", "-m", message, fmt.Sprintf("--author=%v <>", user)) // TODO check for exisiting <> in the future | |
if err != nil { | |
log.Fatal(fmt.Sprintf("could not issue commit: %v %v", err, output)) | |
} | |
// Push | |
output, err = gitCommand("push", "origin", "master") | |
if err != nil { | |
// Assume the commit worked above and restore the state. Bosun should reset the file when this fails, | |
// so the tree should be clean again | |
_, err2 := gitCommand("git", "reset", "HEAD~1") | |
gitReset := "successful" | |
if err2 != nil { | |
gitReset = "failed" | |
} | |
log.Fatal(fmt.Sprintf("could not issue commit (issued a git reset hard which was %v): %v %v", gitReset, err, output)) | |
} | |
} |
This file contains hidden or 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
package main | |
import ( | |
"bytes" | |
"flag" | |
"fmt" | |
"log" | |
"os" | |
"strings" | |
"strconv" | |
"encoding/json" | |
"net/http" | |
"<replaceme>/bogit/util" | |
) | |
var repoDirFlag = flag.String("repo", "", "location of the repo") | |
var keyFlag = flag.String("key", "", "path the the file that contains the private ssh key to access git") | |
var bosunURLFlag = flag.String("bosun", "", "url to bosun, i.e. http://bosun") | |
func main() { | |
flag.Parse() | |
if *repoDirFlag == "" || *keyFlag == "" || *bosunURLFlag == "" { | |
log.Fatal("all flags must be specified") | |
} | |
// check bosun and make sure save is not enabled | |
saveEnabled, err := checkBosunSave(*bosunURLFlag) | |
if err != nil { | |
log.Fatal(err) | |
} | |
if saveEnabled { | |
log.Println("save enabled on this bosun instance - taking no action") | |
os.Exit(0) | |
} | |
gitCommand := util.GetGitExecuter("git", *repoDirFlag, *keyFlag) | |
fetchOutput, err := gitCommand("fetch") | |
if err != nil { | |
log.Fatalf("failed to run git fetch: %v", fetchOutput) | |
} | |
ahead, err := revCount(gitCommand, "ahead") | |
if err != nil { | |
log.Fatal(err) | |
} | |
if ahead > 0 { | |
log.Fatal(fmt.Errorf("local master is ahead of origin, aborting")) | |
} | |
behind, err := revCount(gitCommand, "behind") | |
if err != nil { | |
log.Fatal(err) | |
} | |
if behind == 0 { | |
os.Exit(0) | |
} | |
if mergeOutput, err := gitCommand("merge", "origin/master", "--ff-only"); err != nil { | |
log.Fatalf("failed to fast forward only merge origin/master into master: %v", mergeOutput) | |
} | |
if err := reloadBosun(*bosunURLFlag); err != nil { | |
log.Fatalf("failed to reload bosun: %v", err) | |
} | |
} | |
func revCount(gitCommand func(args ...string) (string, error), ab string) (int, error) { | |
var rawCount string | |
var err error | |
switch ab { | |
case "ahead": | |
rawCount, err = gitCommand("rev-list", "--count", "origin/master..master") | |
case "behind": | |
rawCount, err = gitCommand("rev-list", "--count", "master..origin/master") | |
default: | |
return -1, fmt.Errorf("revCount must be behind or ahead, got %v", ab) | |
} | |
if err != nil { | |
return -1, fmt.Errorf("failed to get rev-list for commits %v count: %v", ab, err) | |
} | |
count, err := strconv.Atoi(strings.TrimSpace(rawCount)) | |
if err != nil { | |
return -1, fmt.Errorf("failed to parse rev-list for commits %v result: %v", ab, err) | |
} | |
return count, nil | |
} | |
func checkBosunSave(bosunAddr string) (bool, error) { | |
r, err := http.Get(bosunAddr + "/api/save_enabled") | |
var enabled bool | |
if err != nil { | |
return enabled, fmt.Errorf("unable to get bosun save status: %v", err) | |
} | |
defer r.Body.Close() | |
err = json.NewDecoder(r.Body).Decode(&enabled) | |
if err != nil { | |
return enabled, fmt.Errorf("unable to decode response for bosun's save status: %v", err) | |
} | |
return enabled, nil | |
} | |
func reloadBosun(bosunAddr string) error { | |
reload := struct{ Reload bool }{true} | |
b := new(bytes.Buffer) | |
json.NewEncoder(b).Encode(reload) | |
_, err := http.Post(bosunAddr+"/api/reload", "application/json", b) | |
if err != nil { | |
return fmt.Errorf("unable to issue reload request via HTTP POST to bosun: %v", err) | |
} | |
return nil | |
} |
This file contains hidden or 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
package util | |
import ( | |
"fmt" | |
"os" | |
"os/exec" | |
) | |
func GetGitExecuter(gitCmd, fileDir, keyFile string) func(args ...string) (string, error) { | |
gitSSHEnv := fmt.Sprintf("GIT_SSH_COMMAND=%v", fmt.Sprintf("ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i %v", keyFile)) | |
return func(args ...string) (string, error) { | |
args = append([]string{"-C", fileDir}, args...) | |
gitCmd := exec.Command(gitCmd, args...) | |
//fmt.Println(args) | |
if keyFile != "" { | |
gitCmd.Env = append(os.Environ(), gitSSHEnv) | |
} | |
output, err := gitCmd.CombinedOutput() | |
//fmt.Println(string(output)) | |
if err != nil { | |
return string(output), err | |
} | |
return string(output), nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment