Add cli option sync-on-signal to trigger git-sync with a signal. (#664)
Operation: git-sync --repo https://github.com/kubernetes/kubernetes --sync-on-signal SIGHUP git-sync --repo https://github.com/kubernetes/kubernetes --sync-on-signal HUP git-sync --repo https://github.com/kubernetes/kubernetes --sync-on-signal 1 Signals can be sent to docker containers with cmd: docker kill -signal SIGHUP <Container ID>
This commit is contained in:
parent
f7ff396716
commit
2b3f1bcdd7
|
|
@ -35,11 +35,13 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/spf13/pflag"
|
||||
"golang.org/x/sys/unix"
|
||||
"k8s.io/git-sync/pkg/cmd"
|
||||
"k8s.io/git-sync/pkg/hook"
|
||||
"k8s.io/git-sync/pkg/logging"
|
||||
|
|
@ -77,6 +79,8 @@ var flSyncTimeout = pflag.Duration("sync-timeout", envDuration("GIT_SYNC_SYNC_TI
|
|||
"the total time allowed for one complete sync, must be >= 10ms; --timeout overrides this")
|
||||
var flOneTime = pflag.Bool("one-time", envBool("GIT_SYNC_ONE_TIME", false),
|
||||
"exit after the first sync")
|
||||
var flSyncOnSignal = pflag.String("sync-on-signal", envString("GIT_SYNC_SYNC_ON_SIGNAL", ""),
|
||||
"sync on receipt of the specified signal (e.g. SIGHUP)")
|
||||
var flMaxFailures = pflag.Int("max-failures", envInt("GIT_SYNC_MAX_FAILURES", 0),
|
||||
"the number of consecutive failures allowed before aborting (the first sync must succeed, -1 will retry forever")
|
||||
var flChmod = pflag.Int("change-permissions", envInt("GIT_SYNC_PERMISSIONS", 0),
|
||||
|
|
@ -397,6 +401,24 @@ func main() {
|
|||
handleConfigError(log, true, "ERROR: --period must be at least 10ms")
|
||||
}
|
||||
|
||||
var syncSig syscall.Signal
|
||||
if *flSyncOnSignal != "" {
|
||||
if num, err := strconv.ParseInt(*flSyncOnSignal, 0, 0); err == nil {
|
||||
// sync-on-signal value is a number
|
||||
syncSig = syscall.Signal(num)
|
||||
} else {
|
||||
// sync-on-signal value is a name
|
||||
syncSig = unix.SignalNum(*flSyncOnSignal)
|
||||
if syncSig == 0 {
|
||||
// last resort - maybe they said "HUP", meaning "SIGHUP"
|
||||
syncSig = unix.SignalNum("SIG" + *flSyncOnSignal)
|
||||
}
|
||||
}
|
||||
if syncSig == 0 {
|
||||
handleConfigError(log, true, "ERROR: --sync-on-signal must be a valid signal name or number")
|
||||
}
|
||||
}
|
||||
|
||||
if *flTimeout != 0 {
|
||||
// Back-compat
|
||||
*flSyncTimeout = time.Duration(*flTimeout) * time.Second
|
||||
|
|
@ -670,6 +692,13 @@ func main() {
|
|||
go exechookRunner.Run(context.Background())
|
||||
}
|
||||
|
||||
// Setup signal notify channel
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
if syncSig != 0 {
|
||||
log.V(2).Info("installing signal handler", "signal", unix.SignalName(syncSig))
|
||||
signal.Notify(sigChan, syncSig)
|
||||
}
|
||||
|
||||
// Craft a function that can be called to refresh credentials when needed.
|
||||
refreshCreds := func(ctx context.Context) error {
|
||||
// These should all be mutually-exclusive configs.
|
||||
|
|
@ -772,7 +801,16 @@ func main() {
|
|||
|
||||
log.V(1).Info("next sync", "waitTime", flPeriod.String())
|
||||
cancel()
|
||||
time.Sleep(*flPeriod)
|
||||
|
||||
// Sleep until the next sync. If syncSig is set then the sleep may
|
||||
// be interrupted by that signal.
|
||||
t := time.NewTimer(*flPeriod)
|
||||
select {
|
||||
case <-t.C:
|
||||
case <-sigChan:
|
||||
log.V(2).Info("caught signal", "signal", unix.SignalName(syncSig))
|
||||
t.Stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2139,6 +2177,13 @@ OPTIONS
|
|||
The git submodule behavior: one of "recursive", "shallow", or
|
||||
"off". If not specified, this defaults to "recursive".
|
||||
|
||||
--sync-on-signal <string>, $GIT_SYNC_SYNC_ON_SIGNAL
|
||||
Indicates that a sync attempt should occur upon receipt of the
|
||||
specified signal name (e.g. SIGHUP) or number (e.g. 1). If a sync
|
||||
is already in progress, another sync will be triggered as soon as
|
||||
the current one completes. If not specified, signals will not
|
||||
trigger syncs.
|
||||
|
||||
--sync-timeout <duration>, $GIT_SYNC_SYNC_TIMEOUT
|
||||
The total time allowed for one complete sync. This must be at least
|
||||
10ms. This flag obsoletes --timeout, but if --timeout is specified,
|
||||
|
|
|
|||
110
test_e2e.sh
110
test_e2e.sh
|
|
@ -126,6 +126,14 @@ function docker_kill() {
|
|||
docker kill "$1" >/dev/null
|
||||
}
|
||||
|
||||
function docker_signal() {
|
||||
if [[ -z "$1" || -z "$2" ]]; then
|
||||
echo "usage: $0 <id> <signal>"
|
||||
return 1
|
||||
fi
|
||||
docker kill "--signal=$2" "$1" >/dev/null
|
||||
}
|
||||
|
||||
# E2E_TAG is the tag used for docker builds. This is needed because docker
|
||||
# tags are system-global, but one might have multiple repos checked out.
|
||||
E2E_TAG=$(git rev-parse --show-toplevel | sed 's|/|_|g')
|
||||
|
|
@ -1111,6 +1119,108 @@ function e2e::sync_slow_git_long_timeout() {
|
|||
assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 2
|
||||
}
|
||||
|
||||
##############################################
|
||||
# Test sync-on-signal with SIGHUP
|
||||
##############################################
|
||||
function e2e::sync_on_signal_sighup() {
|
||||
# First sync
|
||||
echo "$FUNCNAME 1" > "$REPO"/file
|
||||
git -C "$REPO" commit -qam "$FUNCNAME 1"
|
||||
|
||||
GIT_SYNC \
|
||||
--period=100s \
|
||||
--sync-on-signal="SIGHUP" \
|
||||
--repo="file://$REPO" \
|
||||
--branch="$MAIN_BRANCH" \
|
||||
--rev=HEAD \
|
||||
--root="$ROOT" \
|
||||
--link="link" \
|
||||
>> "$1" 2>&1 &
|
||||
wait_for_sync 3
|
||||
assert_link_exists "$ROOT"/link
|
||||
assert_file_exists "$ROOT"/link/file
|
||||
assert_file_eq "$ROOT"/link/file "$FUNCNAME 1"
|
||||
|
||||
# Move HEAD forward
|
||||
echo "$FUNCNAME 2" > "$REPO"/file
|
||||
git -C "$REPO" commit -qam "$FUNCNAME 2"
|
||||
# Send signal (note --period is 100s, signal should trigger sync)
|
||||
CTR=$(docker ps --filter label="git-sync-e2e=$RUNID" --format="{{.ID}}")
|
||||
docker_signal "$CTR" SIGHUP
|
||||
wait_for_sync 3
|
||||
assert_link_exists "$ROOT"/link
|
||||
assert_file_exists "$ROOT"/link/file
|
||||
assert_file_eq "$ROOT"/link/file "$FUNCNAME 2"
|
||||
}
|
||||
|
||||
##############################################
|
||||
# Test sync-on-signal with HUP
|
||||
##############################################
|
||||
function e2e::sync_on_signal_hup() {
|
||||
# First sync
|
||||
echo "$FUNCNAME 1" > "$REPO"/file
|
||||
git -C "$REPO" commit -qam "$FUNCNAME 1"
|
||||
|
||||
GIT_SYNC \
|
||||
--period=100s \
|
||||
--sync-on-signal="HUP" \
|
||||
--repo="file://$REPO" \
|
||||
--branch="$MAIN_BRANCH" \
|
||||
--rev=HEAD \
|
||||
--root="$ROOT" \
|
||||
--link="link" \
|
||||
>> "$1" 2>&1 &
|
||||
wait_for_sync 3
|
||||
assert_link_exists "$ROOT"/link
|
||||
assert_file_exists "$ROOT"/link/file
|
||||
assert_file_eq "$ROOT"/link/file "$FUNCNAME 1"
|
||||
|
||||
# Move HEAD forward
|
||||
echo "$FUNCNAME 2" > "$REPO"/file
|
||||
git -C "$REPO" commit -qam "$FUNCNAME 2"
|
||||
# Send signal (note --period is 100s, signal should trigger sync)
|
||||
CTR=$(docker ps --filter label="git-sync-e2e=$RUNID" --format="{{.ID}}")
|
||||
docker_signal "$CTR" SIGHUP
|
||||
wait_for_sync 3
|
||||
assert_link_exists "$ROOT"/link
|
||||
assert_file_exists "$ROOT"/link/file
|
||||
assert_file_eq "$ROOT"/link/file "$FUNCNAME 2"
|
||||
}
|
||||
|
||||
##############################################
|
||||
# Test sync-on-signal with 1 (SIGHUP)
|
||||
##############################################
|
||||
function e2e::sync_on_signal_1() {
|
||||
# First sync
|
||||
echo "$FUNCNAME 1" > "$REPO"/file
|
||||
git -C "$REPO" commit -qam "$FUNCNAME 1"
|
||||
|
||||
GIT_SYNC \
|
||||
--period=100s \
|
||||
--sync-on-signal=1 \
|
||||
--repo="file://$REPO" \
|
||||
--branch="$MAIN_BRANCH" \
|
||||
--rev=HEAD \
|
||||
--root="$ROOT" \
|
||||
--link="link" \
|
||||
>> "$1" 2>&1 &
|
||||
wait_for_sync 3
|
||||
assert_link_exists "$ROOT"/link
|
||||
assert_file_exists "$ROOT"/link/file
|
||||
assert_file_eq "$ROOT"/link/file "$FUNCNAME 1"
|
||||
|
||||
# Move HEAD forward
|
||||
echo "$FUNCNAME 2" > "$REPO"/file
|
||||
git -C "$REPO" commit -qam "$FUNCNAME 2"
|
||||
# Send signal (note --period is 100s, signal should trigger sync)
|
||||
CTR=$(docker ps --filter label="git-sync-e2e=$RUNID" --format="{{.ID}}")
|
||||
docker_signal "$CTR" SIGHUP
|
||||
wait_for_sync 3
|
||||
assert_link_exists "$ROOT"/link
|
||||
assert_file_exists "$ROOT"/link/file
|
||||
assert_file_eq "$ROOT"/link/file "$FUNCNAME 2"
|
||||
}
|
||||
|
||||
##############################################
|
||||
# Test depth syncing
|
||||
##############################################
|
||||
|
|
|
|||
Loading…
Reference in New Issue