adding changes from previous PR, updated README

This commit is contained in:
Zac 2018-08-30 14:49:01 -07:00 committed by Thomas Jackson
parent 01f007a753
commit e437d8e9a3
2 changed files with 95 additions and 14 deletions

View File

@ -11,6 +11,7 @@ it re-pulls, it updates the destination directory atomically. In order to do
this, it uses a git worktree in a subdirectory of the `--root` and flips a this, it uses a git worktree in a subdirectory of the `--root` and flips a
symlink. symlink.
git-sync can also be configured to make webhook call upon sucessful git repo syncronisation. The call is made when right after the symlink is updated.
## Usage ## Usage
``` ```
@ -32,4 +33,26 @@ docker run -d \
nginx nginx
``` ```
## Example of webhooks usage
**Webhook config example**
A webhook config must be valid JSON. If ```success``` is not specified in the config, git-sync will not wait for a response.
```json
{
"url": "http://localhost:9090/-/reload",
"method": "POST|GET",
"success": 200
}
```
**Usage**
```
docker run -d \
-v /tmp/git-data:/git \
registry/git-sync:tag \
--repo=https://github.com/kubernetes/git-sync
--branch=master
--wait=30
--webhook='[{"url": "http://localhost:9090/-/reload", "method": "POST", "success": 200}]'
--webhook='[{"url": "http://1.2.3.4:9090/-/reload", "method": "POST"}]'
```
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/git-sync/README.md?pixel)]() [![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/git-sync/README.md?pixel)]()

View File

@ -34,6 +34,7 @@ import (
"strings" "strings"
"time" "time"
"net/http" "net/http"
"encoding/json"
"github.com/thockin/glogr" "github.com/thockin/glogr"
"github.com/thockin/logr" "github.com/thockin/logr"
@ -62,8 +63,11 @@ var flMaxSyncFailures = flag.Int("max-sync-failures", envInt("GIT_SYNC_MAX_SYNC_
"the number of consecutive failures allowed before aborting (the first pull must succeed, -1 disables aborting for any number of failures after the initial sync)") "the number of consecutive failures allowed before aborting (the first pull must succeed, -1 disables aborting for any number of failures after the initial sync)")
var flChmod = flag.Int("change-permissions", envInt("GIT_SYNC_PERMISSIONS", 0), var flChmod = flag.Int("change-permissions", envInt("GIT_SYNC_PERMISSIONS", 0),
"the file permissions to apply to the checked-out files") "the file permissions to apply to the checked-out files")
var flSymlinkUpdatePostUrl = flag.String("symlink-update-post-url", envString("GIT_SYNC_SYMLINK_UPDATE_POST_URL", ""),
"a command to run when the symlink is updated") var flWebhooks = flag.String("webhook", envString("GIT_SYNC_WEBHOOK", ""),
"the JSON formatted array of webhooks to be sent when git is synced")
var flWebhookTimeout = flag.Int("webhook-timeout", envInt("GIT_SYNC_WEBHOOK_TIMEOUT", 60),
"timeout for webhook http/s requests")
var flUsername = flag.String("username", envString("GIT_SYNC_USERNAME", ""), var flUsername = flag.String("username", envString("GIT_SYNC_USERNAME", ""),
"the username to use") "the username to use")
@ -84,6 +88,24 @@ var flCookieFile = flag.Bool("cookie-file", envBool("GIT_COOKIE_FILE", false),
var flGitCmd = flag.String("git", envString("GIT_SYNC_GIT", "git"), var flGitCmd = flag.String("git", envString("GIT_SYNC_GIT", "git"),
"the git command to run (subject to PATH search)") "the git command to run (subject to PATH search)")
// WebHook structure
type Webhook struct {
// URL for the http/s request
URL string `json:"url"`
// Method for the http/s request
Method string `json:"method"`
// Code to look for when determining if the request was successful.
// If this is not specified, request is sent and forgotten about.
Success int `json:"success"`
}
// Create an http client that has our timeout by default
var netClient = &http.Client{
Timeout: time.Duration(time.Second * time.Duration(*flWebhookTimeout) ),
}
// Webhook collection
var WebhookArray = []Webhook{}
var log = newLoggerOrDie() var log = newLoggerOrDie()
@ -174,6 +196,13 @@ func main() {
} }
} }
if *flWebhooks != "" {
if err := json.Unmarshal([]byte(*flWebhooks), &WebhookArray); err != nil {
fmt.Fprintf(os.Stderr, "Error parsing webhooks JSON: %v\n", err)
os.Exit(1)
}
}
if *flSSH { if *flSSH {
if err := setupGitSSH(*flSSHKnownHosts); err != nil { if err := setupGitSSH(*flSSHKnownHosts); err != nil {
fmt.Fprintf(os.Stderr, "ERROR: can't configure SSH: %v\n", err) fmt.Fprintf(os.Stderr, "ERROR: can't configure SSH: %v\n", err)
@ -188,6 +217,7 @@ func main() {
} }
} }
// From here on, output goes through logging. // From here on, output goes through logging.
log.V(0).Infof("starting up: %q", os.Args) log.V(0).Infof("starting up: %q", os.Args)
@ -229,6 +259,24 @@ func main() {
} }
} }
// WebhookCall Do webhook call
func WebHookCall(url string, method string, statusCode int) error {
req, err := http.NewRequest(method, url, nil)
if err != nil {
return err
}
resp, err := netClient.Do(req)
if err != nil {
return err
}
resp.Body.Close()
if resp.StatusCode != statusCode {
return fmt.Errorf("received response code %q expected %q", resp.StatusCode, statusCode)
}
return nil
}
func waitTime(seconds float64) time.Duration { func waitTime(seconds float64) time.Duration {
return time.Duration(int(seconds*1000)) * time.Millisecond return time.Duration(int(seconds*1000)) * time.Millisecond
} }
@ -277,18 +325,18 @@ func updateSymlink(ctx context.Context, gitRoot, link, newDir string) error {
} }
log.V(1).Infof("renamed symlink %s to %s", "tmp-link", link) log.V(1).Infof("renamed symlink %s to %s", "tmp-link", link)
// If there is a symlink update callback, call it // // If there is a symlink update callback, call it
if len(*flSymlinkUpdatePostUrl) > 0 { // if len(*flSymlinkUpdatePostUrl) > 0 {
log.V(1).Infof("sending post request to %s", *flSymlinkUpdatePostUrl) // log.V(1).Infof("sending post request to %s", *flSymlinkUpdatePostUrl)
// Send the post request // // Send the post request
req, err := http.NewRequest("POST", *flSymlinkUpdatePostUrl, nil) // req, err := http.NewRequest("POST", *flSymlinkUpdatePostUrl, nil)
if err != nil { // if err != nil {
fmt.Errorf("error sending post request (after symlink update): %v", err) // fmt.Errorf("error sending post request (after symlink update): %v", err)
} // }
c := &http.Client{} // c := &http.Client{}
resp, err := c.Do(req) // resp, err := c.Do(req)
resp.Body.Close() // resp.Body.Close()
} // }
// Clean up previous worktree // Clean up previous worktree
if len(currentDir) > 0 { if len(currentDir) > 0 {
@ -306,6 +354,16 @@ func updateSymlink(ctx context.Context, gitRoot, link, newDir string) error {
log.V(1).Infof("pruned old worktrees") log.V(1).Infof("pruned old worktrees")
} }
// Calling webhook only after new symlink created - one after another
for _, v := range WebhookArray {
log.V(0).Infof("calling webhook %v\n", v.URL)
if err := WebHookCall(v.URL, v.Method, v.Success); err != nil {
log.Errorf("error calling webhook %v: %v", v.URL, err)
} else {
log.V(0).Infof("calling webhook %v was: OK\n", v.URL)
}
}
return nil return nil
} }