Merge branch 'master' into streaming-log-stats
This commit is contained in:
commit
871bcca2e9
@ -91,6 +91,8 @@ func pull(remote string, filter *filepathfilter.Filter) {
|
|||||||
|
|
||||||
processQueue := time.Now()
|
processQueue := time.Now()
|
||||||
if err := gitscanner.ScanTree(ref.Sha); err != nil {
|
if err := gitscanner.ScanTree(ref.Sha); err != nil {
|
||||||
|
singleCheckout.Close()
|
||||||
|
|
||||||
ExitWithError(err)
|
ExitWithError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,8 @@ func statusCommand(cmd *cobra.Command, args []string) {
|
|||||||
|
|
||||||
scanner, err := lfs.NewPointerScanner()
|
scanner, err := lfs.NewPointerScanner()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
scanner.Close()
|
||||||
|
|
||||||
ExitWithError(err)
|
ExitWithError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,8 +48,9 @@ type uploadContext struct {
|
|||||||
trackedLocksMu *sync.Mutex
|
trackedLocksMu *sync.Mutex
|
||||||
|
|
||||||
// ALL verifiable locks
|
// ALL verifiable locks
|
||||||
ourLocks map[string]locking.Lock
|
lockVerifyState verifyState
|
||||||
theirLocks map[string]locking.Lock
|
ourLocks map[string]locking.Lock
|
||||||
|
theirLocks map[string]locking.Lock
|
||||||
|
|
||||||
// locks from ourLocks that were modified in this push
|
// locks from ourLocks that were modified in this push
|
||||||
ownedLocks []locking.Lock
|
ownedLocks []locking.Lock
|
||||||
@ -101,7 +102,8 @@ func newUploadContext(remote string, dryRun bool) *uploadContext {
|
|||||||
ctx.tq = newUploadQueue(ctx.Manifest, ctx.Remote, tq.WithProgress(ctx.meter), tq.DryRun(ctx.DryRun))
|
ctx.tq = newUploadQueue(ctx.Manifest, ctx.Remote, tq.WithProgress(ctx.meter), tq.DryRun(ctx.DryRun))
|
||||||
ctx.committerName, ctx.committerEmail = cfg.CurrentCommitter()
|
ctx.committerName, ctx.committerEmail = cfg.CurrentCommitter()
|
||||||
|
|
||||||
ourLocks, theirLocks := verifyLocks(remote)
|
ourLocks, theirLocks, verifyState := verifyLocks(remote)
|
||||||
|
ctx.lockVerifyState = verifyState
|
||||||
for _, l := range theirLocks {
|
for _, l := range theirLocks {
|
||||||
ctx.theirLocks[l.Path] = l
|
ctx.theirLocks[l.Path] = l
|
||||||
}
|
}
|
||||||
@ -112,13 +114,9 @@ func newUploadContext(remote string, dryRun bool) *uploadContext {
|
|||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyLocks(remote string) (ours, theirs []locking.Lock) {
|
func verifyLocks(remote string) (ours, theirs []locking.Lock, st verifyState) {
|
||||||
endpoint := getAPIClient().Endpoints.Endpoint("upload", remote)
|
endpoint := getAPIClient().Endpoints.Endpoint("upload", remote)
|
||||||
|
|
||||||
state := getVerifyStateFor(endpoint)
|
state := getVerifyStateFor(endpoint)
|
||||||
if state == verifyStateDisabled {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
lockClient := newLockClient(remote)
|
lockClient := newLockClient(remote)
|
||||||
|
|
||||||
@ -126,22 +124,27 @@ func verifyLocks(remote string) (ours, theirs []locking.Lock) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.IsNotImplementedError(err) {
|
if errors.IsNotImplementedError(err) {
|
||||||
disableFor(endpoint)
|
disableFor(endpoint)
|
||||||
} else if !errors.IsAuthError(err) {
|
} else if state == verifyStateUnknown || state == verifyStateEnabled {
|
||||||
Print("Remote %q does not support the LFS locking API. Consider disabling it with:", remote)
|
if errors.IsAuthError(err) {
|
||||||
Print(" $ git config 'lfs.%s.locksverify' false", endpoint.Url)
|
if state == verifyStateUnknown {
|
||||||
|
Error("WARNING: Authentication error: %s", err)
|
||||||
if state == verifyStateEnabled {
|
} else if state == verifyStateEnabled {
|
||||||
ExitWithError(err)
|
Exit("ERROR: Authentication error: %s", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Print("Remote %q does not support the LFS locking API. Consider disabling it with:", remote)
|
||||||
|
Print(" $ git config 'lfs.%s.locksverify' false", endpoint.Url)
|
||||||
|
if state == verifyStateEnabled {
|
||||||
|
ExitWithError(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ExitWithError(err)
|
|
||||||
}
|
}
|
||||||
} else if state == verifyStateUnknown {
|
} else if state == verifyStateUnknown {
|
||||||
Print("Locking support detected on remote %q. Consider enabling it with:", remote)
|
Print("Locking support detected on remote %q. Consider enabling it with:", remote)
|
||||||
Print(" $ git config 'lfs.%s.locksverify' true", endpoint.Url)
|
Print(" $ git config 'lfs.%s.locksverify' true", endpoint.Url)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ours, theirs
|
return ours, theirs, state
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *uploadContext) scannerError() error {
|
func (c *uploadContext) scannerError() error {
|
||||||
@ -223,7 +226,16 @@ func (c *uploadContext) prepareUpload(unfiltered ...*lfs.WrappedPointer) (*tq.Tr
|
|||||||
c.trackedLocksMu.Lock()
|
c.trackedLocksMu.Lock()
|
||||||
c.unownedLocks = append(c.unownedLocks, lock)
|
c.unownedLocks = append(c.unownedLocks, lock)
|
||||||
c.trackedLocksMu.Unlock()
|
c.trackedLocksMu.Unlock()
|
||||||
canUpload = false
|
|
||||||
|
// If the verification state is enabled, this failed
|
||||||
|
// locks verification means that the push should fail.
|
||||||
|
//
|
||||||
|
// If the state is disabled, the verification error is
|
||||||
|
// silent and the user can upload.
|
||||||
|
//
|
||||||
|
// If the state is undefined, the verification error is
|
||||||
|
// sent as a warning and the user can upload.
|
||||||
|
canUpload = c.lockVerifyState != verifyStateEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
if lock, ok := c.ourLocks[p.Name]; ok {
|
if lock, ok := c.ourLocks[p.Name]; ok {
|
||||||
@ -308,16 +320,18 @@ func (c *uploadContext) Await() {
|
|||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
var avoidPush bool
|
|
||||||
|
|
||||||
c.trackedLocksMu.Lock()
|
c.trackedLocksMu.Lock()
|
||||||
if ul := len(c.unownedLocks); ul > 0 {
|
if ul := len(c.unownedLocks); ul > 0 {
|
||||||
avoidPush = true
|
|
||||||
|
|
||||||
Print("Unable to push %d locked file(s):", ul)
|
Print("Unable to push %d locked file(s):", ul)
|
||||||
for _, unowned := range c.unownedLocks {
|
for _, unowned := range c.unownedLocks {
|
||||||
Print("* %s - %s", unowned.Path, unowned.Owner)
|
Print("* %s - %s", unowned.Path, unowned.Owner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.lockVerifyState == verifyStateEnabled {
|
||||||
|
Exit("ERROR: Cannot update locked files.")
|
||||||
|
} else {
|
||||||
|
Error("WARNING: The above files would have halted this push.")
|
||||||
|
}
|
||||||
} else if len(c.ownedLocks) > 0 {
|
} else if len(c.ownedLocks) > 0 {
|
||||||
Print("Consider unlocking your own locked file(s): (`git lfs unlock <path>`)")
|
Print("Consider unlocking your own locked file(s): (`git lfs unlock <path>`)")
|
||||||
for _, owned := range c.ownedLocks {
|
for _, owned := range c.ownedLocks {
|
||||||
@ -325,10 +339,6 @@ func (c *uploadContext) Await() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.trackedLocksMu.Unlock()
|
c.trackedLocksMu.Unlock()
|
||||||
|
|
||||||
if avoidPush {
|
|
||||||
Error("WARNING: The above files would have halted this push.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -42,6 +42,22 @@ type extCommand struct {
|
|||||||
|
|
||||||
func pipeExtensions(request *pipeRequest) (response pipeResponse, err error) {
|
func pipeExtensions(request *pipeRequest) (response pipeResponse, err error) {
|
||||||
var extcmds []*extCommand
|
var extcmds []*extCommand
|
||||||
|
defer func() {
|
||||||
|
// In the case of an early return before the end of this
|
||||||
|
// function (in response to an error, etc), kill all running
|
||||||
|
// processes. Errors are ignored since the function has already
|
||||||
|
// returned.
|
||||||
|
//
|
||||||
|
// In the happy path, the commands will have already been
|
||||||
|
// `Wait()`-ed upon and e.cmd.Process.Kill() will return an
|
||||||
|
// error, but we can ignore it.
|
||||||
|
for _, e := range extcmds {
|
||||||
|
if e.cmd.Process != nil {
|
||||||
|
e.cmd.Process.Kill()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
for _, e := range request.extensions {
|
for _, e := range request.extensions {
|
||||||
var pieces []string
|
var pieces []string
|
||||||
switch request.action {
|
switch request.action {
|
||||||
|
@ -19,6 +19,8 @@ import (
|
|||||||
func runCatFileBatch(pointerCh chan *WrappedPointer, lockableCh chan string, lockableSet *lockableNameSet, revs *StringChannelWrapper, errCh chan error) error {
|
func runCatFileBatch(pointerCh chan *WrappedPointer, lockableCh chan string, lockableSet *lockableNameSet, revs *StringChannelWrapper, errCh chan error) error {
|
||||||
scanner, err := NewPointerScanner()
|
scanner, err := NewPointerScanner()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
scanner.Close()
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,8 @@ func runScanTree(cb GitScannerFoundPointer, ref string, filter *filepathfilter.F
|
|||||||
func catFileBatchTree(treeblobs *TreeBlobChannelWrapper) (*PointerChannelWrapper, error) {
|
func catFileBatchTree(treeblobs *TreeBlobChannelWrapper) (*PointerChannelWrapper, error) {
|
||||||
scanner, err := NewPointerScanner()
|
scanner, err := NewPointerScanner()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
scanner.Close()
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,6 +517,7 @@ begin_test "pre-push with their lock on lfs file"
|
|||||||
|
|
||||||
pushd "$TRASHDIR" >/dev/null
|
pushd "$TRASHDIR" >/dev/null
|
||||||
clone_repo "$reponame" "$reponame-assert"
|
clone_repo "$reponame" "$reponame-assert"
|
||||||
|
git config lfs.locksverify true
|
||||||
|
|
||||||
printf "unauthorized changes" >> locked_theirs.dat
|
printf "unauthorized changes" >> locked_theirs.dat
|
||||||
git add locked_theirs.dat
|
git add locked_theirs.dat
|
||||||
@ -524,9 +525,17 @@ begin_test "pre-push with their lock on lfs file"
|
|||||||
git commit --no-verify -m "add unauthorized changes"
|
git commit --no-verify -m "add unauthorized changes"
|
||||||
|
|
||||||
git push origin master 2>&1 | tee push.log
|
git push origin master 2>&1 | tee push.log
|
||||||
|
res="${PIPESTATUS[0]}"
|
||||||
|
if [ "0" -eq "$res" ]; then
|
||||||
|
echo "push should fail"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
grep "Unable to push 1 locked file(s)" push.log
|
grep "Unable to push 1 locked file(s)" push.log
|
||||||
grep "* locked_theirs.dat - Git LFS Tests" push.log
|
grep "* locked_theirs.dat - Git LFS Tests" push.log
|
||||||
|
|
||||||
|
grep "ERROR: Cannot update locked files." push.log
|
||||||
|
refute_server_object "$reponame" "$(calc_oid_file locked_theirs.dat)"
|
||||||
popd >/dev/null
|
popd >/dev/null
|
||||||
)
|
)
|
||||||
end_test
|
end_test
|
||||||
@ -562,6 +571,7 @@ begin_test "pre-push with their lock on non-lfs lockable file"
|
|||||||
|
|
||||||
pushd "$TRASHDIR" >/dev/null
|
pushd "$TRASHDIR" >/dev/null
|
||||||
clone_repo "$reponame" "$reponame-assert"
|
clone_repo "$reponame" "$reponame-assert"
|
||||||
|
git config lfs.locksverify true
|
||||||
|
|
||||||
git lfs update # manually add pre-push hook, since lfs clean hook is not used
|
git lfs update # manually add pre-push hook, since lfs clean hook is not used
|
||||||
echo "other changes" >> readme.txt
|
echo "other changes" >> readme.txt
|
||||||
@ -571,10 +581,19 @@ begin_test "pre-push with their lock on non-lfs lockable file"
|
|||||||
git commit --no-verify -am "add unauthorized changes"
|
git commit --no-verify -am "add unauthorized changes"
|
||||||
|
|
||||||
git push origin master 2>&1 | tee push.log
|
git push origin master 2>&1 | tee push.log
|
||||||
|
res="${PIPESTATUS[0]}"
|
||||||
|
if [ "0" -eq "$res" ]; then
|
||||||
|
echo "push should fail"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
grep "Unable to push 2 locked file(s)" push.log
|
grep "Unable to push 2 locked file(s)" push.log
|
||||||
grep "* large_locked_theirs.dat - Git LFS Tests" push.log
|
grep "* large_locked_theirs.dat - Git LFS Tests" push.log
|
||||||
grep "* tiny_locked_theirs.dat - Git LFS Tests" push.log
|
grep "* tiny_locked_theirs.dat - Git LFS Tests" push.log
|
||||||
|
grep "ERROR: Cannot update locked files." push.log
|
||||||
|
|
||||||
|
refute_server_object "$reponame" "$(calc_oid_file large_locked_theirs.dat)"
|
||||||
|
refute_server_object "$reponame" "$(calc_oid_file tiny_locked_theirs.dat)"
|
||||||
popd >/dev/null
|
popd >/dev/null
|
||||||
)
|
)
|
||||||
end_test
|
end_test
|
||||||
@ -784,6 +803,7 @@ begin_test "pre-push locks verify 403 with verification enabled"
|
|||||||
git config "lfs.$endpoint.locksverify" true
|
git config "lfs.$endpoint.locksverify" true
|
||||||
|
|
||||||
git push origin master 2>&1 | tee push.log
|
git push origin master 2>&1 | tee push.log
|
||||||
|
grep "ERROR: Authentication error" push.log
|
||||||
|
|
||||||
refute_server_object "$reponame" "$contents_oid"
|
refute_server_object "$reponame" "$contents_oid"
|
||||||
[ "true" = "$(git config "lfs.$endpoint.locksverify")" ]
|
[ "true" = "$(git config "lfs.$endpoint.locksverify")" ]
|
||||||
@ -836,8 +856,9 @@ begin_test "pre-push locks verify 403 with verification unset"
|
|||||||
[ -z "$(git config "lfs.$endpoint.locksverify")" ]
|
[ -z "$(git config "lfs.$endpoint.locksverify")" ]
|
||||||
|
|
||||||
git push origin master 2>&1 | tee push.log
|
git push origin master 2>&1 | tee push.log
|
||||||
|
grep "WARNING: Authentication error" push.log
|
||||||
|
|
||||||
refute_server_object "$reponame" "$contents_oid"
|
assert_server_object "$reponame" "$contents_oid"
|
||||||
[ -z "$(git config "lfs.$endpoint.locksverify")" ]
|
[ -z "$(git config "lfs.$endpoint.locksverify")" ]
|
||||||
)
|
)
|
||||||
end_test
|
end_test
|
||||||
|
Loading…
Reference in New Issue
Block a user