Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md244
-rw-r--r--Dangerfile35
-rw-r--r--Makefile2
-rw-r--r--VERSION2
-rwxr-xr-x_support/changelog243
-rwxr-xr-x_support/generate_changelog71
-rwxr-xr-x_support/release18
-rw-r--r--changelogs/unreleased/.keep0
-rw-r--r--changelogs/unreleased/1165-rewrite-is-rabase-in-progress.yml5
-rw-r--r--changelogs/unreleased/grpc-1-11.yml5
-rw-r--r--changelogs/unreleased/pin-faraday-0-12.yml5
-rw-r--r--config.toml.example3
-rw-r--r--doc/MIGRATION_PROCESS.md20
-rw-r--r--doc/configuration/README.md2
-rw-r--r--internal/helper/fieldextractors/fieldextractor.go14
-rw-r--r--internal/rubyserver/balancer/balancer.go84
-rw-r--r--internal/rubyserver/balancer/balancer_test.go177
-rw-r--r--internal/rubyserver/balancer/pool.go59
-rw-r--r--internal/rubyserver/rubyserver.go5
-rw-r--r--internal/service/register.go2
-rw-r--r--internal/service/repository/create_test.go25
-rw-r--r--internal/service/repository/rebase_in_progress.go44
-rw-r--r--internal/service/repository/rebase_in_progress_test.go34
-rw-r--r--internal/service/repository/search_files.go11
-rw-r--r--internal/service/repository/search_files_test.go24
-rw-r--r--internal/service/repository/squash_in_progress.go19
-rw-r--r--internal/service/repository/squash_in_progress_test.go2
-rw-r--r--internal/service/storage/.gitignore1
-rw-r--r--internal/service/storage/deleteall.go69
-rw-r--r--internal/service/storage/deleteall_test.go133
-rw-r--r--internal/service/storage/server.go12
-rw-r--r--internal/service/storage/testhelper_test.go74
-rw-r--r--internal/tempdir/tempdir.go45
-rw-r--r--internal/tempdir/tempdir_test.go4
-rw-r--r--internal/testhelper/testhelper.go6
-rw-r--r--ruby/Gemfile1
-rw-r--r--ruby/Gemfile.lock3
-rwxr-xr-xruby/bin/gitaly-ruby1
-rwxr-xr-xruby/bin/ruby-cd2
-rw-r--r--ruby/lib/gitaly_server/repository_service.rb2
-rw-r--r--ruby/lib/gitlab/git/repository.rb65
-rw-r--r--vendor/gitlab.com/gitlab-org/gitaly-proto/go/VERSION2
-rw-r--r--vendor/gitlab.com/gitlab-org/gitaly-proto/go/blob.pb.go3
-rw-r--r--vendor/gitlab.com/gitlab-org/gitaly-proto/go/storage.pb.go135
-rw-r--r--vendor/gitlab.com/gitlab-org/gitaly-proto/go/wiki.pb.go42
-rw-r--r--vendor/vendor.json10
46 files changed, 1521 insertions, 244 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e686e8938..53aa1d563 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,47 @@
# Gitaly changelog
-v0.100.1
+## v0.103.0
+
+#### Added
+- Add StorageService::DeleteAllRepositories RPC
+ https://gitlab.com/gitlab-org/gitaly/merge_requests/726
+
+#### Other
+- Fix Dangerfile bad changelog detection
+ https://gitlab.com/gitlab-org/gitaly/merge_requests/724
+
+## v0.102.0
+
+#### Changed
+- Unvendor Repository#add_branch
+ https://gitlab.com/gitlab-org/gitaly/merge_requests/717
+
+#### Fixed
+- Fix matching bug in SearchFilesByContent
+ https://gitlab.com/gitlab-org/gitaly/merge_requests/722
+
+## v0.101.0
+
+#### Changed
+- Add gitaly-ruby installation debug log messages
+ https://gitlab.com/gitlab-org/gitaly/merge_requests/710
+
+#### Fixed
+- Use round robin load balancing instead of 'pick first' for gitaly-ruby
+ https://gitlab.com/gitlab-org/gitaly/merge_requests/700
+
+#### Other
+- Generate changelog when releasing a tag to prevent merge conflicts
+ https://gitlab.com/gitlab-org/gitaly/merge_requests/719
+- Unvendor Repository#create implementation
+ https://gitlab.com/gitlab-org/gitaly/merge_requests/713
+
+## v0.100.1
- Use grpc 1.11.0 in gitaly-ruby
https://gitlab.com/gitlab-org/gitaly/merge_requests/732
-v0.100.0
+## v0.100.0
- Fix WikiFindPage when the page has invalidly-encoded content
https://gitlab.com/gitlab-org/gitaly/merge_requests/712
@@ -17,8 +53,10 @@ v0.100.0
https://gitlab.com/gitlab-org/gitaly/merge_requests/715
- Introduce src-d/go-git as dependency
https://gitlab.com/gitlab-org/gitaly/merge_requests/709
+- Lower spawn log level to 'debug'
+ https://gitlab.com/gitlab-org/gitaly/merge_requests/714
-v0.99.0
+## v0.99.0
- Improve changelog entry checks using Danger
https://gitlab.com/gitlab-org/gitaly/merge_requests/705
@@ -31,7 +69,7 @@ v0.99.0
- Return DataLoss error for non-valid git repositories when calculating the checksum
https://gitlab.com/gitlab-org/gitaly/merge_requests/697
-v0.98.0
+## v0.98.0
- Server implementation for repository raw_changes
https://gitlab.com/gitlab-org/gitaly/merge_requests/699
@@ -54,7 +92,7 @@ v0.98.0
- Catch CommitErrors while rebasing
https://gitlab.com/gitlab-org/gitaly/merge_requests/680
-v0.97.0
+## v0.97.0
- Use gitaly-proto 0.97.0
https://gitlab.com/gitlab-org/gitaly/merge_requests/683
@@ -65,7 +103,7 @@ v0.97.0
- Add config option to point to languages.json
https://gitlab.com/gitlab-org/gitaly/merge_requests/652
-v0.96.1
+## v0.96.1
- Vendor gitlab_git at 7e3bb679a92156304
https://gitlab.com/gitlab-org/gitaly/merge_requests/669
@@ -76,17 +114,17 @@ v0.96.1
- Add {Get,CreateRepositoryFrom}Snapshot RPCs
https://gitlab.com/gitlab-org/gitaly/merge_requests/644
-v0.96.0
+## v0.96.0
Skipped. We cut and pushed the wrong tag.
-v0.95.0
+## v0.95.0
- Fix fragile checksum test
https://gitlab.com/gitlab-org/gitaly/merge_requests/661
- Use rugged 0.27.0
https://gitlab.com/gitlab-org/gitaly/merge_requests/660
-v0.94.0
+## v0.94.0
- Send gitaly-ruby exceptions to their own DSN
https://gitlab.com/gitlab-org/gitaly/merge_requests/656
@@ -99,7 +137,7 @@ v0.94.0
- Fix directory permission walker for Go 1.10
https://gitlab.com/gitlab-org/gitaly/merge_requests/650
-v0.93.0
+## v0.93.0
- Fix concurrency limit handler stream interceptor
https://gitlab.com/gitlab-org/gitaly/merge_requests/640
@@ -110,7 +148,7 @@ v0.93.0
- Update gitaly-proto to v0.91.0
https://gitlab.com/gitlab-org/gitaly/merge_requests/643
-v0.92.0
+## v0.92.0
- Server Implementation GetInfoAttributes
https://gitlab.com/gitlab-org/gitaly/merge_requests/641
@@ -125,7 +163,7 @@ v0.92.0
- Vendor gitlab_git at 79aa00321063da
https://gitlab.com/gitlab-org/gitaly/merge_requests/633
-v0.91.0
+## v0.91.0
- Rewrite RepositoryService.HasLocalBranches in Go
https://gitlab.com/gitlab-org/gitaly/merge_requests/629
@@ -138,7 +176,7 @@ v0.91.0
- Sanitize URLs before sending gitaly-ruby exceptions to Sentry
https://gitlab.com/gitlab-org/gitaly/merge_requests/625
-v0.90.0
+## v0.90.0
- Implement SSHService.SSHUploadArchive RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/621
@@ -147,7 +185,7 @@ v0.90.0
- Clean stale worktrees before performing garbage collection
https://gitlab.com/gitlab-org/gitaly/merge_requests/622
-v0.89.0
+## v0.89.0
- Report original exceptions to Sentry instead of wrapped ones by the exception bridge
https://gitlab.com/gitlab-org/gitaly/merge_requests/623
@@ -160,19 +198,19 @@ v0.89.0
- Bump github-linguist to 5.3.3
https://gitlab.com/gitlab-org/gitaly/merge_requests/613
-v0.88.0
+## v0.88.0
- Add support for all field to {Find,Count}Commits RPCs
https://gitlab.com/gitlab-org/gitaly/merge_requests/611
- Vendor gitlab_git at de454de9b10f
https://gitlab.com/gitlab-org/gitaly/merge_requests/611
-v0.87.0
+## v0.87.0
- Implement GetCommitSignatures RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/609
-v0.86.0
+## v0.86.0
- Implement BlobService.GetAllLfsPointers
https://gitlab.com/gitlab-org/gitaly/merge_requests/562
@@ -181,24 +219,24 @@ v0.86.0
- Use gitaly-proto v0.86.0
https://gitlab.com/gitlab-org/gitaly/merge_requests/606
-v0.85.0
+## v0.85.0
- Implement recursive tree entries fetching
https://gitlab.com/gitlab-org/gitaly/merge_requests/600
-v0.84.0
+## v0.84.0
- Send gitaly-ruby exceptions to Sentry
https://gitlab.com/gitlab-org/gitaly/merge_requests/598
- Detect License type for repositories
https://gitlab.com/gitlab-org/gitaly/merge_requests/601
-v0.83.0
+## v0.83.0
- Delete old lock files before performing Garbage Collection
https://gitlab.com/gitlab-org/gitaly/merge_requests/587
-v0.82.0
+## v0.82.0
- Implement RepositoryService.IsSquashInProgress RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/593
@@ -207,19 +245,19 @@ v0.82.0
- Fixed bug in wiki_find_page method
https://gitlab.com/gitlab-org/gitaly/merge_requests/590
-v0.81.0
+## v0.81.0
- Vendor gitlab_git at 7095c2bf4064911
https://gitlab.com/gitlab-org/gitaly/merge_requests/591
- Vendor gitlab_git at 9483cbab26ad239
https://gitlab.com/gitlab-org/gitaly/merge_requests/588
-v0.80.0
+## v0.80.0
- Lock protobuf to 3.5.1
https://gitlab.com/gitlab-org/gitaly/merge_requests/589
-v0.79.0
+## v0.79.0
- Update the activesupport gem
https://gitlab.com/gitlab-org/gitaly/merge_requests/584
@@ -230,7 +268,7 @@ v0.79.0
- Check info split size in catfile parser
https://gitlab.com/gitlab-org/gitaly/merge_requests/583
-v0.78.0
+## v0.78.0
- Vendor gitlab_git at 498d32363aa61d679ff749b
https://gitlab.com/gitlab-org/gitaly/merge_requests/579
@@ -245,12 +283,12 @@ v0.78.0
- Vendor gitlab_git at a03ea19332736c36ecb9
https://gitlab.com/gitlab-org/gitaly/merge_requests/574
-v0.77.0
+## v0.77.0
- Implement RepositoryService.WriteConfig RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/554
-v0.76.0
+## v0.76.0
- Add support for PreReceiveError in UserMergeBranch
https://gitlab.com/gitlab-org/gitaly/merge_requests/573
@@ -265,7 +303,7 @@ v0.76.0
- Vendor gitlab_git at 4376be84ce18cde22febc50
https://gitlab.com/gitlab-org/gitaly/merge_requests/570
-v0.75.0
+## v0.75.0
- Implement WikiGetFormattedData RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/564
@@ -278,7 +316,7 @@ v0.75.0
- ListTagNamesContainingCommit server implementation
https://gitlab.com/gitlab-org/gitaly/merge_requests/537
-v0.74.0
+## v0.74.0
- Implement CreateRepositoryFromBundle RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/557
@@ -289,12 +327,12 @@ v0.74.0
- Add automatic tempdir cleaner
https://gitlab.com/gitlab-org/gitaly/merge_requests/540
-v0.73.0
+## v0.73.0
- Implement CreateBundle RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/546
-v0.72.0
+## v0.72.0
- Implement RemoteService.UpdateRemoteMirror RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/544
@@ -303,7 +341,7 @@ v0.72.0
- Use grpc-go 1.9.1
https://gitlab.com/gitlab-org/gitaly/merge_requests/547
-v0.71.0
+## v0.71.0
- Implement GetLfsPointers RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/543
@@ -312,21 +350,21 @@ v0.71.0
- Fix validation for Repositoryservice::WriteRef
https://gitlab.com/gitlab-org/gitaly/merge_requests/542
-v0.70.0
+## v0.70.0
- Handle non-existent commits in ExtractCommitSignature
https://gitlab.com/gitlab-org/gitaly/merge_requests/535
- Implement RepositoryService::WriteRef
https://gitlab.com/gitlab-org/gitaly/merge_requests/526
-v0.69.0
+## v0.69.0
- Fix handling of paths ending with slashes in TreeEntry
https://gitlab.com/gitlab-org/gitaly/merge_requests/532
- Implement CreateRepositoryFromURL RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/529
-v0.68.0
+## v0.68.0
- Check repo existence before passing to gitaly-ruby
https://gitlab.com/gitlab-org/gitaly/merge_requests/528
@@ -341,7 +379,7 @@ v0.68.0
- Use gitaly-proto 0.70.0
https://gitlab.com/gitlab-org/gitaly/merge_requests/522
-v0.67.0
+## v0.67.0
- Implement UserRebase RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/511
@@ -362,29 +400,29 @@ v0.67.0
- Add support for MergedBranches in FindAllBranches RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/510
-v0.66.0
+## v0.66.0
- Implement RemoteService.FetchInternalRemote RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/508
-v0.65.0
+## v0.65.0
- Add support for MaxCount in CountCommits RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/507
- Implement CreateFork RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/497
-v0.64.0
+## v0.64.0
- Update vendored gitlab_git to b98c69470f52185117fcdb5e28096826b32363ca
https://gitlab.com/gitlab-org/gitaly/merge_requests/506
-v0.63.0
+## v0.63.0
- Handle failed merge when branch gets updated
https://gitlab.com/gitlab-org/gitaly/merge_requests/505
-v0.62.0
+## v0.62.0
- Implement ConflictsService.ResolveConflicts RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/470
@@ -395,14 +433,14 @@ v0.62.0
- Implement RemoteService.AddRemote RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/490
-v0.61.1
+## v0.61.1
- gitaly-ruby shutdown improvements
https://gitlab.com/gitlab-org/gitaly/merge_requests/500
- Use go 1.9
https://gitlab.com/gitlab-org/gitaly/merge_requests/496
-v0.61.0
+## v0.61.0
- Add rdoc to gitaly-ruby's Gemfile
https://gitlab.com/gitlab-org/gitaly/merge_requests/487
@@ -417,19 +455,19 @@ v0.61.0
- Update vendored gitlab_git to 31fa9313991881258b4697cb507cfc8ab205b7dc
https://gitlab.com/gitlab-org/gitaly/merge_requests/486
-v0.60.0
+## v0.60.0
- Implement FindMergeBase RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/477
- Update vendored gitlab_git to 359b65beac43e009b715c2db048e06b6f96b0ee8
https://gitlab.com/gitlab-org/gitaly/merge_requests/481
-v0.59.0
+## v0.59.0
- Restart gitaly-ruby when it uses too much memory
https://gitlab.com/gitlab-org/gitaly/merge_requests/465
-v0.58.0
+## v0.58.0
- Implement RepostoryService::Fsck
https://gitlab.com/gitlab-org/gitaly/merge_requests/475
@@ -438,7 +476,7 @@ v0.58.0
- Update vendored gitlab_git to f3a3bd50eafdcfcaeea21d6cfa0b8bbae7720fec
https://gitlab.com/gitlab-org/gitaly/merge_requests/478
-v0.57.0
+## v0.57.0
- Implement UserRevert RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/471
@@ -451,7 +489,7 @@ v0.57.0
- More logging in housekeeping
https://gitlab.com/gitlab-org/gitaly/merge_requests/435
-v0.56.0
+## v0.56.0
- Implement UserCherryPick RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/457
@@ -464,14 +502,14 @@ v0.56.0
- Implement CommitService::ListCommitsByOid
https://gitlab.com/gitlab-org/gitaly/merge_requests/438
-v0.55.0
+## v0.55.0
- Include pprof debug access in the Prometheus listener
https://gitlab.com/gitlab-org/gitaly/merge_requests/442
- Run gitaly-ruby in the same directory as gitaly
https://gitlab.com/gitlab-org/gitaly/merge_requests/458
-v0.54.0
+## v0.54.0
- Implement RefService.DeleteRefs
https://gitlab.com/gitlab-org/gitaly/merge_requests/453
@@ -481,7 +519,7 @@ v0.54.0
- Implement RepositoryService::FetchSourceBranch
https://gitlab.com/gitlab-org/gitaly/merge_requests/434
-v0.53.0
+## v0.53.0
- Update vendored gitlab_git to f7537ce03a29b
https://gitlab.com/gitlab-org/gitaly/merge_requests/449
@@ -490,17 +528,17 @@ v0.53.0
- Implement WikiGetPageVersions RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/430
-v0.52.1
+## v0.52.1
- Include pprof debug access in the Prometheus listener
https://gitlab.com/gitlab-org/gitaly/merge_requests/442
-v0.52.0
+## v0.52.0
- Implement WikiUpdatePage RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/422
-v0.51.0
+## v0.51.0
- Implement OperationService.UserFFMerge
https://gitlab.com/gitlab-org/gitaly/merge_requests/426
@@ -516,26 +554,26 @@ v0.51.0
- Enable logging in client-streamed and bidi GRPC requests
https://gitlab.com/gitlab-org/gitaly/merge_requests/429
-v0.50.0
+## v0.50.0
- Pass repo git alternate dirs to gitaly-ruby
https://gitlab.com/gitlab-org/gitaly/merge_requests/421
- Remove old temporary files from repositories after GC
https://gitlab.com/gitlab-org/gitaly/merge_requests/411
-v0.49.0
+## v0.49.0
- Use sentry fingerprinting to group exceptions
https://gitlab.com/gitlab-org/gitaly/merge_requests/417
- Use gitlab_git c23c09366db610c1
https://gitlab.com/gitlab-org/gitaly/merge_requests/415
-v0.48.0
+## v0.48.0
- Implement WikiWritePage RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/410
-v0.47.0
+## v0.47.0
- Pass full BranchUpdate result on successful merge
https://gitlab.com/gitlab-org/gitaly/merge_requests/406
@@ -545,7 +583,7 @@ v0.47.0
https://gitlab.com/gitlab-org/gitaly/merge_requests/407
-v0.46.0
+## v0.46.0
- Add a Rails logger to ruby-git
https://gitlab.com/gitlab-org/gitaly/merge_requests/405
@@ -554,7 +592,7 @@ v0.46.0
- Use relative paths for git object dir attributes
https://gitlab.com/gitlab-org/gitaly/merge_requests/393
-v0.45.1
+## v0.45.1
- Implement OperationService::UserMergeBranch
https://gitlab.com/gitlab-org/gitaly/merge_requests/394
@@ -565,11 +603,11 @@ v0.45.1
- Fix Commit Subject parsing in rubyserver
https://gitlab.com/gitlab-org/gitaly/merge_requests/388
-v0.45.0
+## v0.45.0
Skipped. We cut and pushed the wrong tag.
-v0.44.0
+## v0.44.0
- Update gitlab_git to 4a0f720a502ac02423
https://gitlab.com/gitlab-org/gitaly/merge_requests/389
@@ -578,7 +616,7 @@ v0.44.0
- Implement Raw{Diff,Patch} RPCs
https://gitlab.com/gitlab-org/gitaly/merge_requests/381
-v0.43.0
+## v0.43.0
- Pass details of Gitaly-Ruby's Ruby exceptions back to
callers in the request trailers
@@ -596,7 +634,7 @@ v0.43.0
- Add `gitaly-ssh` command
https://gitlab.com/gitlab-org/gitaly/merge_requests/368
-v0.42.0
+## v0.42.0
- Implement UserCreateTag RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/374
@@ -605,7 +643,7 @@ v0.42.0
- Check if we don't overwrite a namespace moved to gitaly
https://gitlab.com/gitlab-org/gitaly/merge_requests/375
-v0.41.0
+## v0.41.0
- Wait for monitor goroutine to return during supervisor shutdown
https://gitlab.com/gitlab-org/gitaly/merge_requests/341
@@ -626,7 +664,7 @@ v0.41.0
- Make gitaly-ruby config mandatory
https://gitlab.com/gitlab-org/gitaly/merge_requests/373
-v0.40.0
+## v0.40.0
- Use context cancellation instead of command.Close
https://gitlab.com/gitlab-org/gitaly/merge_requests/332
- Fix LastCommitForPath handling of tree root
@@ -640,7 +678,7 @@ v0.40.0
- Handle git dates larger than golang's and protobuf's limits
https://gitlab.com/gitlab-org/gitaly/merge_requests/353
-v0.39.0
+## v0.39.0
- Reimplement FindAllTags RPC in Ruby
https://gitlab.com/gitlab-org/gitaly/merge_requests/334
- Re-use gitaly-ruby client connection
@@ -648,7 +686,7 @@ v0.39.0
- Fix encoding-bug in GitalyServer#gitaly_commit_from_rugged
https://gitlab.com/gitlab-org/gitaly/merge_requests/337
-v0.38.0
+## v0.38.0
- Update vendor/gitlab_git to b58c4f436abaf646703bdd80f266fa4c0bab2dd2
https://gitlab.com/gitlab-org/gitaly/merge_requests/324
@@ -657,12 +695,12 @@ v0.38.0
- Populate `flat_path` field of `TreeEntry`s
https://gitlab.com/gitlab-org/gitaly/merge_requests/328
-v0.37.0
+## v0.37.0
- Implement FindBranch RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/315
-v0.36.0
+## v0.36.0
- Terminate commands when their context cancels
https://gitlab.com/gitlab-org/gitaly/merge_requests/318
@@ -671,7 +709,7 @@ v0.36.0
- Use git-linguist to implement CommitLanguages
https://gitlab.com/gitlab-org/gitaly/merge_requests/316
-v0.35.0
+## v0.35.0
- Implement CommitService.CommitStats
https://gitlab.com/gitlab-org/gitaly/merge_requests/312
@@ -680,7 +718,7 @@ v0.35.0
- Restore support for custom environment variables
https://gitlab.com/gitlab-org/gitaly/merge_requests/319
-v0.34.0
+## v0.34.0
- Export environment variables for git debugging
https://gitlab.com/gitlab-org/gitaly/merge_requests/306
@@ -697,19 +735,19 @@ v0.34.0
- Monitor gitaly-ruby RSS via Prometheus
https://gitlab.com/gitlab-org/gitaly/merge_requests/310
-v0.33.0
+## v0.33.0
- Implement DiffService.CommitPatch RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/279
- Use 'bundle config' for gitaly-ruby in source production installations
https://gitlab.com/gitlab-org/gitaly/merge_requests/298
-v0.32.0
+## v0.32.0
- RefService::RefExists endpoint
https://gitlab.com/gitlab-org/gitaly/merge_requests/275
-v0.31.0
+## v0.31.0
- Implement CommitService.FindCommits
https://gitlab.com/gitlab-org/gitaly/merge_requests/266
@@ -720,12 +758,12 @@ v0.31.0
- Implement RepositoryService.FetchRemote RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/276
-v0.30.0
+## v0.30.0
- Add a middleware for handling Git object dir attributes
https://gitlab.com/gitlab-org/gitaly/merge_requests/273
-v0.29.0
+## v0.29.0
- Use BUNDLE_PATH instead of --path for gitaly-ruby
https://gitlab.com/gitlab-org/gitaly/merge_requests/271
@@ -736,7 +774,7 @@ v0.29.0
- Log top level project group for easier analysis
https://gitlab.com/gitlab-org/gitaly/merge_requests/272
-v0.28.0
+## v0.28.0
- Increase gitaly-ruby connection timeout to 20s
https://gitlab.com/gitlab-org/gitaly/merge_requests/265
@@ -745,7 +783,7 @@ v0.28.0
- Implement CommitsByMessage RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/263
-v0.27.0
+## v0.27.0
- Support `git -c` options in SSH upload-pack
https://gitlab.com/gitlab-org/gitaly/merge_requests/242
@@ -760,7 +798,7 @@ v0.27.0
- Install gems into vendor/bundle
https://gitlab.com/gitlab-org/gitaly/merge_requests/264
-v0.26.0
+## v0.26.0
- Implement CommitService.CommitLanguages, add gitaly-ruby
https://gitlab.com/gitlab-org/gitaly/merge_requests/210
@@ -769,24 +807,24 @@ v0.26.0
- Fix a bug in FindAllTags parsing lightweight tags
https://gitlab.com/gitlab-org/gitaly/merge_requests/256
-v0.25.0
+## v0.25.0
- Implement FindAllTags RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/246
-v0.24.1
+## v0.24.1
- Return an empty array on field `ParentIds` of `GitCommit`s if it has none
https://gitlab.com/gitlab-org/gitaly/merge_requests/237
-v0.24.0
+## v0.24.0
- Consume stdout during repack/gc
https://gitlab.com/gitlab-org/gitaly/merge_requests/249
- Implement RefService.FindAllBranches RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/239
-v0.23.0
+## v0.23.0
- Version without Build Time
https://gitlab.com/gitlab-org/gitaly/merge_requests/231
@@ -801,7 +839,7 @@ v0.23.0
- Correctly handle a non-tree path on CommitService.TreeEntries
https://gitlab.com/gitlab-org/gitaly/merge_requests/234
-v0.22.0
+## v0.22.0
- Various build file improvements
https://gitlab.com/gitlab-org/gitaly/merge_requests/229
@@ -810,31 +848,31 @@ v0.22.0
- Send full repository path instead of filename on field `path` of TreeEntry
https://gitlab.com/gitlab-org/gitaly/merge_requests/232
-v0.21.2
+## v0.21.2
- Config: do not start Gitaly without at least one storage
https://gitlab.com/gitlab-org/gitaly/merge_requests/227
- Implement CommitService.GarbageCollect/Repack{Incremental,Full}
https://gitlab.com/gitlab-org/gitaly/merge_requests/218
-v0.21.1
+## v0.21.1
- Make sure stdout.Read has enough bytes buffered to read from
https://gitlab.com/gitlab-org/gitaly/merge_requests/224
-v0.21.0
+## v0.21.0
- Send an empty response for TreeEntry instead of nil
https://gitlab.com/gitlab-org/gitaly/merge_requests/223
-v0.20.0
+## v0.20.0
- Implement commit diff limiting logic
https://gitlab.com/gitlab-org/gitaly/merge_requests/211
- Increase message size to 5 KB for Diff service
https://gitlab.com/gitlab-org/gitaly/merge_requests/221
-v0.19.0
+## v0.19.0
- Send parent ids and raw body on CommitService.CommitsBetween
https://gitlab.com/gitlab-org/gitaly/merge_requests/216
@@ -843,7 +881,7 @@ v0.19.0
- Implement CommitService.GetTreeEntries
https://gitlab.com/gitlab-org/gitaly/merge_requests/208
-v0.18.0
+## v0.18.0
- Add config to specify a git binary path
https://gitlab.com/gitlab-org/gitaly/merge_requests/177
@@ -851,19 +889,19 @@ v0.18.0
message bodies, reject suspicious revisions
https://gitlab.com/gitlab-org/gitaly/merge_requests/204
-v0.17.0
+## v0.17.0
- Rename auth 'unenforced' to 'transitioning'
https://gitlab.com/gitlab-org/gitaly/merge_requests/209
- Also check for "refs" folder for repo existence
https://gitlab.com/gitlab-org/gitaly/merge_requests/207
-v0.16.0
+## v0.16.0
- Implement BlobService.GetBlob
https://gitlab.com/gitlab-org/gitaly/merge_requests/202
-v0.15.0
+## v0.15.0
- Ensure that sub-processes inherit TZ environment variable
https://gitlab.com/gitlab-org/gitaly/merge_requests/201
@@ -872,7 +910,7 @@ v0.15.0
- Implement CountCommits RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/203
-v0.14.0
+## v0.14.0
- Added integration test for SSH, and a client package
https://gitlab.com/gitlab-org/gitaly/merge_requests/178/
@@ -882,21 +920,21 @@ v0.14.0
- Add RepositoryExists Implementation
https://gitlab.com/gitlab-org/gitaly/merge_requests/200
-v0.13.0
+## v0.13.0
- Added usage and version flags to the command line interface
https://gitlab.com/gitlab-org/gitaly/merge_requests/193
- Optional token authentication
https://gitlab.com/gitlab-org/gitaly/merge_requests/191
-v0.12.0
+## v0.12.0
- Stop using deprecated field `path` in Repository messages
https://gitlab.com/gitlab-org/gitaly/merge_requests/179
- Implement TreeEntry RPC
https://gitlab.com/gitlab-org/gitaly/merge_requests/187
-v0.11.2
+## v0.11.2
Skipping 0.11.1 intentionally, we messed up the tag.
@@ -905,7 +943,7 @@ Skipping 0.11.1 intentionally, we messed up the tag.
- Fix incorrect dependency in Makefile
https://gitlab.com/gitlab-org/gitaly/merge_requests/189
-v0.11.0
+## v0.11.0
- FindDefaultBranchName: decorate error
https://gitlab.com/gitlab-org/gitaly/merge_requests/148
@@ -936,7 +974,7 @@ v0.11.0
- Upgrade gRPC and its dependencies
https://gitlab.com/gitlab-org/gitaly/merge_requests/180
-v0.10.0
+## v0.10.0
- CommitDiff: Parse a typechange diff correctly
https://gitlab.com/gitlab-org/gitaly/merge_requests/136
@@ -947,14 +985,14 @@ v0.10.0
- Add SSHUpload/ReceivePack Implementation
https://gitlab.com/gitlab-org/gitaly/merge_requests/132
-v0.9.0
+## v0.9.0
- Add support ignoring whitespace diffs in CommitDiff
https://gitlab.com/gitlab-org/gitaly/merge_requests/126
- Add support for path filtering in CommitDiff
https://gitlab.com/gitlab-org/gitaly/merge_requests/126
-v0.8.0
+## v0.8.0
- Don't error on invalid ref in CommitIsAncestor
https://gitlab.com/gitlab-org/gitaly/merge_requests/129
@@ -963,7 +1001,7 @@ v0.8.0
- Return 'Not Found' gRPC code when repository is not found
https://gitlab.com/gitlab-org/gitaly/merge_requests/120
-v0.7.0
+## v0.7.0
- Use storage configuration data from config.toml, if possible, when
resolving repository paths.
diff --git a/Dangerfile b/Dangerfile
index 3afa7a26d..f1bb16150 100644
--- a/Dangerfile
+++ b/Dangerfile
@@ -1,30 +1,35 @@
-CHANGELOG_FILE = "CHANGELOG.md"
+require 'yaml'
+require 'json'
-def check_changelog
- unless git.modified_files.include?(CHANGELOG_FILE)
- warn("This MR is missing a CHANGELOG entry")
+fail("Please provide a MR description") if gitlab.mr_body.empty?
+
+def check_changelog(path)
+ if git.modified_files.include?("CHANGELOG.md")
+ fail("CHANGELOG.md was edited. Please remove the additions and create an entry with _support/changelog")
return
end
- patch = git.diff_for_file(CHANGELOG_FILE).patch
- unless patch.match?(/^\+- #{Regexp.quote(gitlab.mr_title)}\n/)
- fail('Changelog entry should match the MR title')
- end
+ if !git.added_files.include?(path)
+ warn("No changelog entry was generated, please do so by executing _support/changelog")
+ else
+ yaml = YAML.safe_load(File.read(path))
+
+ unless yaml['merge_request'] == gitlab.mr_json["iid"]
+ fail("Merge request ID was not set to #{gitlab.mr_json['iid']}")
+ end
- unless patch.match?(/^\+\s+#{Regexp.quote(gitlab.mr_json['web_url'])}\n/)
- fail('Changelog entry URL does not match the web url')
+ unless yaml['title'] == gitlab.mr_title
+ fail('Changelog entry should match the MR title')
+ end
end
end
-check_changelog
-
-fail("Please provide a MR description") if gitlab.mr_body.empty?
+check_changelog(File.join('changelogs', 'unreleased', "#{gitlab.branch_for_head}.yml"))
VENDOR_JSON = 'vendor/vendor.json'
fail("Expected #{VENDOR_JSON} to exist") unless File.exist?(VENDOR_JSON)
if git.modified_files.include?(VENDOR_JSON)
- require 'json'
parsed_json = JSON.parse(File.read(VENDOR_JSON))
proto = parsed_json["package"]&.find { |h| h["path"].start_with?("gitlab.com/gitlab-org/gitaly-proto") }
@@ -33,3 +38,5 @@ if git.modified_files.include?(VENDOR_JSON)
fail("gitaly-proto version is incorrect")
end
end
+
+# vim: ft=ruby
diff --git a/Makefile b/Makefile
index 073c3b80b..a47e6a7b7 100644
--- a/Makefile
+++ b/Makefile
@@ -56,7 +56,9 @@ build: .ruby-bundle $(TARGET_SETUP)
cp $(foreach cmd,$(COMMANDS),$(BIN_BUILD_DIR)/$(cmd)) $(BUILD_DIR)/
.ruby-bundle: ruby/Gemfile.lock ruby/Gemfile
+ cd ruby && bundle config # for debugging
cd ruby && bundle install $(BUNDLE_FLAGS)
+ cd ruby && bundle show gitaly-proto # sanity check
touch $@
# TODO: confirm what references this target? Omnibus? Source installs?
diff --git a/VERSION b/VERSION
index a39178a63..89eba2c5b 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.100.1
+0.103.0
diff --git a/_support/changelog b/_support/changelog
new file mode 100755
index 000000000..4abb9da2c
--- /dev/null
+++ b/_support/changelog
@@ -0,0 +1,243 @@
+#!/usr/bin/env ruby
+#
+# Generate a changelog entry file in the correct location.
+#
+# Automatically stages the file and amends the previous commit if the `--amend`
+# argument is used.
+#
+# Lifted from gitlab-org/gitlab-ce
+
+require 'optparse'
+require 'yaml'
+
+Options = Struct.new(
+ :amend,
+ :author,
+ :dry_run,
+ :force,
+ :merge_request,
+ :title,
+ :type
+)
+INVALID_TYPE = -1
+
+class ChangelogOptionParser
+ Type = Struct.new(:name, :description)
+ TYPES = [
+ Type.new('added', 'New feature'),
+ Type.new('fixed', 'Bug fix'),
+ Type.new('changed', 'Feature change'),
+ Type.new('deprecated', 'New deprecation'),
+ Type.new('removed', 'Feature removal'),
+ Type.new('security', 'Security fix'),
+ Type.new('performance', 'Performance improvement'),
+ Type.new('other', 'Other')
+ ].freeze
+ TYPES_OFFSET = 1
+
+ class << self
+ def parse(argv)
+ options = Options.new
+
+ parser = OptionParser.new do |opts|
+ opts.banner = "Usage: #{__FILE__} [options] [title]\n\n"
+
+ # Note: We do not provide a shorthand for this in order to match the `git
+ # commit` interface
+ opts.on('--amend', 'Amend the previous commit') do |value|
+ options.amend = value
+ end
+
+ opts.on('-f', '--force', 'Overwrite an existing entry') do |value|
+ options.force = value
+ end
+
+ opts.on('-m', '--merge-request [integer]', Integer, 'Merge Request ID') do |value|
+ options.merge_request = value
+ end
+
+ opts.on('-n', '--dry-run', "Don't actually write anything, just print") do |value|
+ options.dry_run = value
+ end
+
+ opts.on('-u', '--git-username', 'Use Git user.name configuration as the author') do |value|
+ options.author = git_user_name if value
+ end
+
+ opts.on('-t', '--type [string]', String, "The category of the change, valid options are: #{TYPES.map(&:name).join(', ')}") do |value|
+ options.type = parse_type(value)
+ end
+
+ opts.on('-h', '--help', 'Print help message') do
+ $stdout.puts opts
+ exit
+ end
+ end
+
+ parser.parse!(argv)
+
+ # Title is everything that remains, but let's clean it up a bit
+ options.title = argv.join(' ').strip.squeeze(' ').tr("\r\n", '')
+
+ options
+ end
+
+ def read_type
+ read_type_message
+
+ type = TYPES[$stdin.getc.to_i - TYPES_OFFSET]
+ assert_valid_type!(type)
+
+ type.name
+ end
+
+ private
+
+ def parse_type(name)
+ type_found = TYPES.find do |type|
+ type.name == name
+ end
+ type_found ? type_found.name : INVALID_TYPE
+ end
+
+ def read_type_message
+ $stdout.puts "\n>> Please specify the index for the category of your change:"
+ TYPES.each_with_index do |type, index|
+ $stdout.puts "#{index + TYPES_OFFSET}. #{type.description}"
+ end
+ $stdout.print "\n?> "
+ end
+
+ def assert_valid_type!(type)
+ unless type
+ $stderr.puts "Invalid category index, please select an index between 1 and #{TYPES.length}"
+ exit 1
+ end
+ end
+
+ def git_user_name
+ %x{git config user.name}.strip
+ end
+ end
+end
+
+class ChangelogEntry
+ attr_reader :options
+
+ def initialize(options)
+ @options = options
+
+ assert_feature_branch!
+ assert_title!
+ assert_new_file!
+
+ # Read type from $stdin unless is already set
+ options.type ||= ChangelogOptionParser.read_type
+ assert_valid_type!
+
+ $stdout.puts "\e[32mcreate\e[0m #{file_path}"
+ $stdout.puts contents
+
+ unless options.dry_run
+ write
+ amend_commit if options.amend
+ end
+ end
+
+ private
+
+ def contents
+ yaml_content = YAML.dump(
+ 'title' => title,
+ 'merge_request' => options.merge_request,
+ 'author' => options.author,
+ 'type' => options.type
+ )
+ remove_trailing_whitespace(yaml_content)
+ end
+
+ def write
+ File.write(file_path, contents)
+ end
+
+ def amend_commit
+ %x{git add #{file_path}}
+ exec("git commit --amend")
+ end
+
+ def fail_with(message)
+ $stderr.puts "\e[31merror\e[0m #{message}"
+ exit 1
+ end
+
+ def assert_feature_branch!
+ return unless branch_name == 'master'
+
+ fail_with "Create a branch first!"
+ end
+
+ def assert_new_file!
+ return unless File.exist?(file_path)
+ return if options.force
+
+ fail_with "#{file_path} already exists! Use `--force` to overwrite."
+ end
+
+ def assert_title!
+ return if options.title.length > 0 || options.amend
+
+ fail_with "Provide a title for the changelog entry or use `--amend`" \
+ " to use the title from the previous commit."
+ end
+
+ def assert_valid_type!
+ return unless options.type && options.type == INVALID_TYPE
+
+ fail_with 'Invalid category given!'
+ end
+
+ def title
+ if options.title.empty?
+ last_commit_subject
+ else
+ options.title
+ end
+ end
+
+ def last_commit_subject
+ %x{git log --format="%s" -1}.strip
+ end
+
+ def file_path
+ File.join(
+ unreleased_path,
+ branch_name.gsub(/[^\w-]/, '-') << '.yml'
+ )
+ end
+
+ def unreleased_path
+ path = File.join('changelogs', 'unreleased')
+ path = File.join('ee', path) if ee?
+
+ path
+ end
+
+ def ee?
+ @ee ||= File.exist?(File.expand_path('../CHANGELOG-EE.md', __dir__))
+ end
+
+ def branch_name
+ @branch_name ||= %x{git symbolic-ref --short HEAD}.strip
+ end
+
+ def remove_trailing_whitespace(yaml_content)
+ yaml_content.gsub(/ +$/, '')
+ end
+end
+
+if $0 == __FILE__
+ options = ChangelogOptionParser.parse(ARGV)
+ ChangelogEntry.new(options)
+end
+
+# vim: ft=ruby
diff --git a/_support/generate_changelog b/_support/generate_changelog
new file mode 100755
index 000000000..f34b17d5e
--- /dev/null
+++ b/_support/generate_changelog
@@ -0,0 +1,71 @@
+#!/usr/bin/env ruby
+# Generates the changelog from the yaml entries in changelogs/unreleased
+
+require 'yaml'
+require 'fileutils'
+
+class ChangelogEntry
+ attr_reader :title, :merge_request, :type, :author
+
+ def initialize(file_path)
+ yaml = YAML.safe_load(File.read(file_path))
+
+ @title = yaml['title']
+ @merge_request = yaml['merge_request']
+ @type = yaml['type']
+ @author = yaml['author']
+ end
+
+ def to_s
+ str = ""
+ str << "- #{title}\n"
+ str << " https://gitlab.com/gitlab-org/gitaly/merge_requests/#{merge_request}\n"
+ str << " Contributed by #{author}\n" if author
+
+ str
+ end
+end
+
+ROOT_DIR = File.expand_path('../..', __FILE__)
+UNRELEASED_ENTRIES = File.join(ROOT_DIR, 'changelogs', 'unreleased')
+CHANGELOG_FILE = File.join(ROOT_DIR, 'CHANGELOG.md')
+
+def main(version)
+ entries = []
+ Dir["#{UNRELEASED_ENTRIES}/*.yml"].each do |yml|
+ entries << ChangelogEntry.new(yml)
+ FileUtils.rm(yml)
+ end
+
+ sections = []
+ types = entries.map(&:type).uniq.sort
+ types.each do |type|
+ text = ''
+ text << "#### #{type.capitalize}\n"
+
+ entries.each do |e|
+ next unless e.type == type
+
+ text << e.to_s
+ end
+
+ sections << text
+ end
+
+ new_version_entry = ["## v#{version}\n\n", sections.join("\n"), "\n"].join
+
+ current_changelog = File.read(CHANGELOG_FILE).lines
+ header = current_changelog.shift(2)
+
+ new_changelog = [header, new_version_entry, current_changelog.join]
+
+ File.write(CHANGELOG_FILE, new_changelog.join)
+end
+
+unless ARGV.count == 1
+ warn "Usage: #{$0} VERSION"
+ warn "Specify version as x.y.z"
+ abort
+end
+
+main(ARGV.first)
diff --git a/_support/release b/_support/release
index 81e006135..2ff2061e0 100755
--- a/_support/release
+++ b/_support/release
@@ -35,7 +35,10 @@ def main(version)
tag_name = "v#{version}"
write_version_file(version)
- update_changelog(tag_name)
+
+ run!(%W[_support/generate_changelog #{version}])
+ run!(%w[git add changelogs CHANGELOG.md])
+
version_msg = "Version #{version}"
run!(%W[git commit -m #{version_msg}])
run!(%W[git tag -a -m #{version_msg} #{tag_name}])
@@ -57,19 +60,6 @@ def write_version_file(version)
run!(%W[git add #{version_file}])
end
-def update_changelog(version_string)
- changelog = 'CHANGELOG.md'
- content = IO.read(changelog).lines
- unreleased_line = "UNRELEASED\n"
- version_index = content.find_index { |l| l == unreleased_line }
- if version_index.nil?
- abort "no #{unreleased_line.inspect} line found in #{changelog}"
- end
- content[version_index] = version_string + "\n"
- IO.write(changelog, content.join)
- run!(%W[git add #{changelog}])
-end
-
def error(msg)
warn "#{$0}: #{msg}"
end
diff --git a/changelogs/unreleased/.keep b/changelogs/unreleased/.keep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/changelogs/unreleased/.keep
diff --git a/changelogs/unreleased/1165-rewrite-is-rabase-in-progress.yml b/changelogs/unreleased/1165-rewrite-is-rabase-in-progress.yml
new file mode 100644
index 000000000..08bc113f7
--- /dev/null
+++ b/changelogs/unreleased/1165-rewrite-is-rabase-in-progress.yml
@@ -0,0 +1,5 @@
+---
+title: Rewrite IsRebase/SquashInProgress in Go
+merge_request: 698
+author:
+type: performance
diff --git a/changelogs/unreleased/grpc-1-11.yml b/changelogs/unreleased/grpc-1-11.yml
new file mode 100644
index 000000000..5f0aa7529
--- /dev/null
+++ b/changelogs/unreleased/grpc-1-11.yml
@@ -0,0 +1,5 @@
+---
+title: Use grpc 1.11.0 in gitaly-ruby
+merge_request: 732
+author:
+type: fixed
diff --git a/changelogs/unreleased/pin-faraday-0-12.yml b/changelogs/unreleased/pin-faraday-0-12.yml
new file mode 100644
index 000000000..0158dce5e
--- /dev/null
+++ b/changelogs/unreleased/pin-faraday-0-12.yml
@@ -0,0 +1,5 @@
+---
+title: Use the same faraday gem version as gitlab-ce
+merge_request: 733
+author:
+type: other
diff --git a/config.toml.example b/config.toml.example
index b47ce94eb..76e0ea047 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -56,6 +56,9 @@ dir = "/home/git/gitaly/ruby"
#
# # Time that gitaly-ruby memory must remain high before a restart (seconds)
# restart_delay = "5m"
+#
+# # Number of gitaly-ruby worker processes
+# num_workers = 2
[gitlab-shell]
# The directory where gitlab-shell is installed
diff --git a/doc/MIGRATION_PROCESS.md b/doc/MIGRATION_PROCESS.md
index a9c24eee3..ea0a4041b 100644
--- a/doc/MIGRATION_PROCESS.md
+++ b/doc/MIGRATION_PROCESS.md
@@ -94,13 +94,7 @@ As the maintainer of Gitaly, Jacob to review:
The feature flag will be enabled on dev.gitlab.org, staging and GitLab.com, but the feature flag will be disabled by default. On-premise installations can enable the feature if they wish, but it will be disabled by default.
-For a feature toggle `GITALY_EXAMPLE_FEATURE`, the toggle would be enabled by setting the environment variable:
-
-```shell
-GITALY_EXAMPLE_FEATURE=1 # "One" to enable
-```
-
-Or by running this command in a Rails Console:
+For a feature toggle `gitaly_example_feature`, the toggle would be enabled by running this command in a Rails Console:
```ruby
Feature.enable("gitaly_example_feature")
@@ -118,13 +112,7 @@ This gives on-premise installations a month to test a feature and disable it if
Disabling a feature is done by:
-For a feature toggle `GITALY_EXAMPLE_FEATURE`, the toggle would be enabled by setting the environment variable:
-
-```shell
-GITALY_EXAMPLE_FEATURE=0 # "Zero" to disable
-```
-
-Or by running this command in a Rails Console:
+For a feature toggle `GITALY_EXAMPLE_FEATURE`, the toggle would be enabled by running this command in a Rails Console:
```ruby
Feature.disable("gitaly_example_feature")
@@ -140,5 +128,5 @@ In the next GitLab release following the change to Opt-Out feature status, the f
The change will be made by:
-* Removing the references to the feature flag in Omnibus, Chef repo, etc
-* Remove the feature flag switching code from the client application (GitLab-CE, Workhorse, GitLab-Shell) code
+* Move the old rugged/shell method from gitlab-ce repository into [Gitalys own Gitlab::Git](ruby/lib/gitlab/git).
+* Remove the feature flag switching code from the client application (GitLab-CE, Workhorse, GitLab-Shell) code, and it's underlying rugged/shell method
diff --git a/doc/configuration/README.md b/doc/configuration/README.md
index 88ac51b1e..337e11f87 100644
--- a/doc/configuration/README.md
+++ b/doc/configuration/README.md
@@ -110,7 +110,7 @@ max\_rss limit.
|max_rss|integer|no|Resident set size limit that triggers a gitaly-ruby restart, in bytes. Default 300MB.|
|graceful_restart_timeout|string|no|Grace period to allow a gitaly-ruby process to finish ongoing requests. Default 10 minutes ("10m").|
|restart_delay|string|no|Time memory must be high before a restart is triggered, in seconds. Default 5 minutes ("5m").|
-|num_workers|integer|no|Number of gitaly-ruby worker processes. Default 2, minimum 2.|
+|num_workers|integer|no|Number of gitaly-ruby worker processes. Try increasing this number in case of ResourceExhausted errors. Default 2, minimum 2.|
|linguist_languages_path|string|no|Override for dynamic languages.json discovery. Default: "" (use dynamic discovery).|
### Logging
diff --git a/internal/helper/fieldextractors/fieldextractor.go b/internal/helper/fieldextractors/fieldextractor.go
index 350829bb6..07e51e20d 100644
--- a/internal/helper/fieldextractors/fieldextractor.go
+++ b/internal/helper/fieldextractors/fieldextractor.go
@@ -11,10 +11,14 @@ type repositoryBasedRequest interface {
}
type namespaceBasedRequest interface {
- GetStorageName() string
+ storageBasedRequest
GetName() string
}
+type storageBasedRequest interface {
+ GetStorageName() string
+}
+
func formatRepoRequest(repo *pb.Repository) map[string]interface{} {
if repo == nil {
// Signals that the client did not send a repo through, which
@@ -46,6 +50,12 @@ func getTopLevelGroupFromRepoPath(repoPath string) string {
return parts[0]
}
+func formatStorageRequest(storageReq storageBasedRequest) map[string]interface{} {
+ return map[string]interface{}{
+ "StorageName": storageReq.GetStorageName(),
+ }
+}
+
func formatNamespaceRequest(namespaceReq namespaceBasedRequest) map[string]interface{} {
return map[string]interface{}{
"StorageName": namespaceReq.GetStorageName(),
@@ -74,6 +84,8 @@ func FieldExtractor(fullMethod string, req interface{}) map[string]interface{} {
return formatRepoRequest(req.(repositoryBasedRequest).GetRepository())
case namespaceBasedRequest:
return formatNamespaceRequest(req.(namespaceBasedRequest))
+ case storageBasedRequest:
+ return formatStorageRequest(req.(storageBasedRequest))
}
return nil
diff --git a/internal/rubyserver/balancer/balancer.go b/internal/rubyserver/balancer/balancer.go
index bceb53338..4ba136244 100644
--- a/internal/rubyserver/balancer/balancer.go
+++ b/internal/rubyserver/balancer/balancer.go
@@ -21,6 +21,8 @@ package balancer
//
import (
+ "time"
+
"google.golang.org/grpc/resolver"
)
@@ -32,6 +34,11 @@ func init() {
resolver.Register(lbBuilder)
}
+const (
+ // DefaultRemoveDelay is the minimum time between successive address removals.
+ DefaultRemoveDelay = 1 * time.Minute
+)
+
// AddAddress adds the address of a gitaly-ruby instance to the load
// balancer.
func AddAddress(a string) {
@@ -57,10 +64,38 @@ type addressUpdate struct {
next chan struct{}
}
+type config struct {
+ numAddrs int
+ removeDelay time.Duration
+}
+
type builder struct {
addAddress chan string
removeAddress chan addressRemoval
addressUpdates chan addressUpdate
+ configUpdate chan config
+
+ // for testing only
+ testingRestart chan struct{}
+}
+
+// ConfigureBuilder changes the configuration of the global balancer
+// instance. All calls that interact with the balancer will block until
+// ConfigureBuilder has been called at least once.
+func ConfigureBuilder(numAddrs int, removeDelay time.Duration) {
+ cfg := config{
+ numAddrs: numAddrs,
+ removeDelay: removeDelay,
+ }
+
+ if cfg.removeDelay <= 0 {
+ cfg.removeDelay = DefaultRemoveDelay
+ }
+ if numAddrs <= 0 {
+ panic("numAddrs must be at least 1")
+ }
+
+ lbBuilder.configUpdate <- cfg
}
func newBuilder() *builder {
@@ -68,6 +103,8 @@ func newBuilder() *builder {
addAddress: make(chan string),
removeAddress: make(chan addressRemoval),
addressUpdates: make(chan addressUpdate),
+ configUpdate: make(chan config),
+ testingRestart: make(chan struct{}),
}
go b.monitor()
@@ -83,43 +120,60 @@ func (*builder) Scheme() string { return Scheme }
// care what "address" the caller wants to resolve. We always resolve to
// the current list of address for local gitaly-ruby processes.
func (b *builder) Build(_ resolver.Target, cc resolver.ClientConn, _ resolver.BuildOption) (resolver.Resolver, error) {
- // JV: Normally I would delete this but this is very poorly documented,
- // and I don't want to have to look up the magic words again. In case we
- // ever want to do round-robin.
- // cc.NewServiceConfig(`{"LoadBalancingPolicy":"round_robin"}`)
-
+ cc.NewServiceConfig(`{"LoadBalancingPolicy":"round_robin"}`)
return newGitalyResolver(cc, b.addressUpdates), nil
}
// monitor serves address list requests and handles address updates.
func (b *builder) monitor() {
- addresses := make(map[string]struct{})
+ p := newPool()
notify := make(chan struct{})
+ cfg := <-b.configUpdate
+ lastRemoval := time.Now()
+
+ // This channel is intentionally nil so that our 'select' below won't
+ // send messages to it. We do this to prevent sending out invalid (empty)
+ // messages during boot.
+ var addressUpdates chan addressUpdate
for {
au := addressUpdate{next: notify}
- for a := range addresses {
+ for _, a := range p.activeAddrs() {
au.addrs = append(au.addrs, resolver.Address{Addr: a})
}
+ if len(au.addrs) > 0 && addressUpdates == nil {
+ // Start listening for address update requests
+ addressUpdates = b.addressUpdates
+ }
+
select {
- case b.addressUpdates <- au:
- if len(au.addrs) == 0 {
- panic("builder monitor sent empty address update")
- }
+ case addressUpdates <- au:
+ // We have served an address update request
case addr := <-b.addAddress:
- addresses[addr] = struct{}{}
+ p.add(addr)
+
notify = broadcast(notify)
case removal := <-b.removeAddress:
- _, addressKnown := addresses[removal.addr]
- if !addressKnown || len(addresses) <= 1 {
+ if time.Since(lastRemoval) < cfg.removeDelay || p.activeSize() < cfg.numAddrs-1 {
+ removal.ok <- false
+ break
+ }
+
+ if !p.remove(removal.addr) {
removal.ok <- false
break
}
- delete(addresses, removal.addr)
removal.ok <- true
+ lastRemoval = time.Now()
notify = broadcast(notify)
+ case cfg = <-b.configUpdate:
+ // We have received a config update
+ case <-b.testingRestart:
+ go b.monitor()
+ b.configUpdate <- cfg
+ return
}
}
}
diff --git a/internal/rubyserver/balancer/balancer_test.go b/internal/rubyserver/balancer/balancer_test.go
index a4d13493e..637b1d8f2 100644
--- a/internal/rubyserver/balancer/balancer_test.go
+++ b/internal/rubyserver/balancer/balancer_test.go
@@ -1,54 +1,171 @@
package balancer
import (
+ "encoding/json"
+ "fmt"
+ "strings"
+ "sync"
"testing"
+ "time"
"github.com/stretchr/testify/require"
+ "google.golang.org/grpc/resolver"
)
+func TestServiceConfig(t *testing.T) {
+ configureBuilderTest(3)
+
+ tcc := &testClientConn{}
+ lbBuilder.Build(resolver.Target{}, tcc, resolver.BuildOption{})
+
+ configUpdates := tcc.ConfigUpdates()
+ require.Len(t, configUpdates, 1, "expect exactly one config update")
+
+ svcConfig := struct{ LoadBalancingPolicy string }{}
+ require.NoError(t, json.NewDecoder(strings.NewReader(configUpdates[0])).Decode(&svcConfig))
+ require.Equal(t, "round_robin", svcConfig.LoadBalancingPolicy)
+}
+
+func TestAddressUpdatesSmallestPool(t *testing.T) {
+ // The smallest number of addresses is 2: 1 standby, and 1 active.
+ addrs := configureBuilderTest(2)
+
+ tcc := &testClientConn{}
+ lbBuilder.Build(resolver.Target{}, tcc, resolver.BuildOption{})
+
+ // Simulate some random updates
+ RemoveAddress(addrs[0])
+ RemoveAddress(addrs[0])
+ AddAddress(addrs[0])
+ RemoveAddress(addrs[1])
+ RemoveAddress(addrs[0])
+ AddAddress(addrs[1])
+ AddAddress(addrs[1])
+ RemoveAddress(addrs[1])
+ RemoveAddress(addrs[1])
+ RemoveAddress(addrs[1])
+ RemoveAddress(addrs[0])
+ AddAddress(addrs[0])
+
+ addrUpdates := tcc.AddrUpdates()
+ require.True(t, len(addrUpdates) > 0, "expected at least one address update")
+
+ expectedActive := len(addrs) - 1 // subtract 1 for the standby
+ for _, update := range addrUpdates {
+ require.Equal(t, expectedActive, len(update))
+ }
+}
+
+func TestAddressUpdatesRoundRobinPool(t *testing.T) {
+ // With 3 addresses in the pool, 2 will be active.
+ addrs := configureBuilderTest(3)
+
+ tcc := &testClientConn{}
+ lbBuilder.Build(resolver.Target{}, tcc, resolver.BuildOption{})
+
+ // Simulate some random updates
+ RemoveAddress(addrs[0])
+ RemoveAddress(addrs[0])
+ RemoveAddress(addrs[2])
+ AddAddress(addrs[0])
+ RemoveAddress(addrs[1])
+ RemoveAddress(addrs[0])
+ AddAddress(addrs[2])
+ AddAddress(addrs[1])
+ AddAddress(addrs[1])
+ RemoveAddress(addrs[1])
+ RemoveAddress(addrs[2])
+ RemoveAddress(addrs[1])
+ AddAddress(addrs[1])
+ RemoveAddress(addrs[2])
+ RemoveAddress(addrs[1])
+ RemoveAddress(addrs[0])
+ AddAddress(addrs[0])
+
+ addrUpdates := tcc.AddrUpdates()
+ require.True(t, len(addrUpdates) > 0, "expected at least one address update")
+
+ expectedActive := len(addrs) - 1 // subtract 1 for the standby
+ for _, update := range addrUpdates {
+ require.Equal(t, expectedActive, len(update))
+ }
+}
+
func TestRemovals(t *testing.T) {
okActions := []action{
{add: "foo"},
{add: "bar"},
{add: "qux"},
{remove: "bar"},
+ {add: "baz"},
{remove: "foo"},
}
+ numAddr := 3
+ removeDelay := 1 * time.Millisecond
+ ConfigureBuilder(numAddr, removeDelay)
testCases := []struct {
desc string
actions []action
lastFails bool
+ delay time.Duration
}{
{
desc: "add then remove",
actions: okActions,
+ delay: 2 * removeDelay,
},
{
- desc: "remove last address",
+ desc: "add then remove but too fast",
+ actions: okActions,
+ lastFails: true,
+ delay: 0,
+ },
+ {
+ desc: "remove one address too many",
actions: append(okActions, action{remove: "qux"}),
lastFails: true,
+ delay: 2 * removeDelay,
},
{
desc: "remove unknown address",
actions: []action{
{add: "foo"},
+ {add: "qux"},
+ {add: "baz"},
{remove: "bar"},
},
lastFails: true,
+ delay: 2 * removeDelay,
+ },
+ {
+ // This relies on the implementation detail that the first address added
+ // to the balancer is the standby. The standby cannot be removed.
+ desc: "remove standby address",
+ actions: []action{
+ {add: "foo"},
+ {add: "qux"},
+ {add: "baz"},
+ {remove: "foo"},
+ },
+ lastFails: true,
+ delay: 2 * removeDelay,
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
- // This breaks integration with gRPC and causes a monitor goroutine leak.
- // Not a problem for this test.
- lbBuilder = newBuilder()
+ lbBuilder.testingRestart <- struct{}{}
+ time.Sleep(2 * removeDelay) // wait for lastRemoval in monitor goroutine to be long enough ago
for i, a := range tc.actions {
if a.add != "" {
AddAddress(a.add)
} else {
+ if tc.delay > 0 {
+ time.Sleep(tc.delay)
+ }
+
expected := true
if i+1 == len(tc.actions) && tc.lastFails {
expected = false
@@ -65,3 +182,55 @@ type action struct {
add string
remove string
}
+
+type testClientConn struct {
+ addrUpdates [][]resolver.Address
+ configUpdates []string
+ mu sync.Mutex
+}
+
+func (tcc *testClientConn) NewAddress(addresses []resolver.Address) {
+ tcc.mu.Lock()
+ defer tcc.mu.Unlock()
+
+ tcc.addrUpdates = append(tcc.addrUpdates, addresses)
+}
+
+func (tcc *testClientConn) NewServiceConfig(serviceConfig string) {
+ tcc.mu.Lock()
+ defer tcc.mu.Unlock()
+
+ tcc.configUpdates = append(tcc.configUpdates, serviceConfig)
+}
+
+func (tcc *testClientConn) AddrUpdates() [][]resolver.Address {
+ tcc.mu.Lock()
+ defer tcc.mu.Unlock()
+
+ return tcc.addrUpdates
+}
+
+func (tcc *testClientConn) ConfigUpdates() []string {
+ tcc.mu.Lock()
+ defer tcc.mu.Unlock()
+
+ return tcc.configUpdates
+}
+
+// configureBuilderTest reconfigures the global builder and pre-populates
+// it with addresses. It returns the list of addresses it added.
+func configureBuilderTest(numAddrs int) []string {
+ delay := 1 * time.Millisecond
+ ConfigureBuilder(numAddrs, delay)
+ lbBuilder.testingRestart <- struct{}{}
+ time.Sleep(2 * delay)
+
+ var addrs []string
+ for i := 0; i < numAddrs; i++ {
+ a := fmt.Sprintf("test.%d", i)
+ AddAddress(a)
+ addrs = append(addrs, a)
+ }
+
+ return addrs
+}
diff --git a/internal/rubyserver/balancer/pool.go b/internal/rubyserver/balancer/pool.go
new file mode 100644
index 000000000..f34097990
--- /dev/null
+++ b/internal/rubyserver/balancer/pool.go
@@ -0,0 +1,59 @@
+package balancer
+
+func newPool() *pool {
+ return &pool{active: make(map[string]struct{})}
+}
+
+// pool is a set that keeps one address (element) set aside as a standby.
+// This data structure is not thread safe.
+type pool struct {
+ standby string
+ active map[string]struct{}
+}
+
+// add is idempotent. If there is no standby address yet, addr becomes
+// the standby.
+func (p *pool) add(addr string) {
+ if _, ok := p.active[addr]; ok || p.standby == addr {
+ return
+ }
+
+ if p.standby == "" {
+ p.standby = addr
+ return
+ }
+
+ p.active[addr] = struct{}{}
+}
+
+func (p *pool) activeSize() int {
+ return len(p.active)
+}
+
+// remove tries to remove addr from the active addresses. If addr is not
+// known or not active, remove returns false.
+func (p *pool) remove(addr string) bool {
+ if _, ok := p.active[addr]; !ok || p.standby == "" {
+ return false
+ }
+
+ delete(p.active, addr)
+
+ // Promote the standby to an active address
+ p.active[p.standby] = struct{}{}
+ p.standby = ""
+
+ return true
+}
+
+// activeAddrs returns the currently active addresses as a list. The
+// order is not deterministic.
+func (p *pool) activeAddrs() []string {
+ var addrs []string
+
+ for a := range p.active {
+ addrs = append(addrs, a)
+ }
+
+ return addrs
+}
diff --git a/internal/rubyserver/rubyserver.go b/internal/rubyserver/rubyserver.go
index 8b9f159dc..44cbbd8fc 100644
--- a/internal/rubyserver/rubyserver.go
+++ b/internal/rubyserver/rubyserver.go
@@ -116,8 +116,11 @@ func Start() (*Server, error) {
gitalyRuby := path.Join(cfg.Ruby.Dir, "bin/gitaly-ruby")
+ numWorkers := cfg.Ruby.NumWorkers
+ balancer.ConfigureBuilder(numWorkers, 0)
+
s := &Server{}
- for i := 0; i < cfg.Ruby.NumWorkers; i++ {
+ for i := 0; i < numWorkers; i++ {
name := fmt.Sprintf("gitaly-ruby.%d", i)
socketPath := socketPath(i)
diff --git a/internal/service/register.go b/internal/service/register.go
index 82d792557..35db56c2e 100644
--- a/internal/service/register.go
+++ b/internal/service/register.go
@@ -16,6 +16,7 @@ import (
"gitlab.com/gitlab-org/gitaly/internal/service/server"
"gitlab.com/gitlab-org/gitaly/internal/service/smarthttp"
"gitlab.com/gitlab-org/gitaly/internal/service/ssh"
+ "gitlab.com/gitlab-org/gitaly/internal/service/storage"
"gitlab.com/gitlab-org/gitaly/internal/service/wiki"
"google.golang.org/grpc"
@@ -40,6 +41,7 @@ func RegisterAll(grpcServer *grpc.Server, rubyServer *rubyserver.Server) {
pb.RegisterConflictsServiceServer(grpcServer, conflicts.NewServer(rubyServer))
pb.RegisterRemoteServiceServer(grpcServer, remote.NewServer(rubyServer))
pb.RegisterServerServiceServer(grpcServer, server.NewServer())
+ pb.RegisterStorageServiceServer(grpcServer, storage.NewServer())
healthpb.RegisterHealthServer(grpcServer, health.NewServer())
}
diff --git a/internal/service/repository/create_test.go b/internal/service/repository/create_test.go
index cfb4ce94b..5f2e6f6fb 100644
--- a/internal/service/repository/create_test.go
+++ b/internal/service/repository/create_test.go
@@ -63,6 +63,31 @@ func TestCreateRepositoryFailure(t *testing.T) {
ctx, cancel := testhelper.Context()
defer cancel()
+ storagePath, err := helper.GetStorageByName("default")
+ require.NoError(t, err)
+ fullPath := path.Join(storagePath, "foo.git")
+
+ _, err = os.Create(fullPath)
+ require.NoError(t, err)
+ defer os.RemoveAll(fullPath)
+
+ _, err = client.CreateRepository(ctx, &pb.CreateRepositoryRequest{
+ Repository: &pb.Repository{StorageName: "default", RelativePath: "foo.git"},
+ })
+
+ testhelper.AssertGrpcError(t, err, codes.Unknown, "")
+}
+
+func TestCreateRepositoryFailureInvalidArgs(t *testing.T) {
+ server, serverSocketPath := runRepoServer(t)
+ defer server.Stop()
+
+ client, conn := newRepositoryClient(t, serverSocketPath)
+ defer conn.Close()
+
+ ctx, cancel := testhelper.Context()
+ defer cancel()
+
testCases := []struct {
repo *pb.Repository
code codes.Code
diff --git a/internal/service/repository/rebase_in_progress.go b/internal/service/repository/rebase_in_progress.go
index 2c894e198..dc7d16b6e 100644
--- a/internal/service/repository/rebase_in_progress.go
+++ b/internal/service/repository/rebase_in_progress.go
@@ -2,32 +2,62 @@ package repository
import (
"fmt"
+ "os"
+ "path"
+ "strings"
+ "time"
pb "gitlab.com/gitlab-org/gitaly-proto/go"
-
- "gitlab.com/gitlab-org/gitaly/internal/rubyserver"
+ "gitlab.com/gitlab-org/gitaly/internal/helper"
+ "gitlab.com/gitlab-org/gitaly/internal/helper/housekeeping"
"golang.org/x/net/context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
+const (
+ worktreePrefix = "gitlab-worktree"
+ rebaseWorktreePrefix = "rebase"
+ freshTimeout = 15 * time.Minute
+)
+
func (s *server) IsRebaseInProgress(ctx context.Context, req *pb.IsRebaseInProgressRequest) (*pb.IsRebaseInProgressResponse, error) {
if err := validateIsRebaseInProgressRequest(req); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "IsRebaseInProgress: %v", err)
}
- client, err := s.RepositoryServiceClient(ctx)
+ repoPath, err := helper.GetRepoPath(req.GetRepository())
if err != nil {
return nil, err
}
- clientCtx, err := rubyserver.SetHeaders(ctx, req.GetRepository())
+ inProg, err := freshWorktree(repoPath, rebaseWorktreePrefix, req.GetRebaseId())
if err != nil {
return nil, err
}
+ return &pb.IsRebaseInProgressResponse{InProgress: inProg}, nil
+}
+
+func freshWorktree(repoPath, prefix, id string) (bool, error) {
+ worktreePath := path.Join(repoPath, worktreePrefix, fmt.Sprintf("%s-%s", prefix, id))
+
+ fs, err := os.Stat(worktreePath)
+ if err != nil {
+ return false, nil
+ }
+
+ if time.Since(fs.ModTime()) > freshTimeout {
+ if err = os.RemoveAll(worktreePath); err != nil {
+ if err = housekeeping.FixDirectoryPermissions(worktreePath); err != nil {
+ return false, err
+ }
+ err = os.RemoveAll(worktreePath)
+ }
+ return false, err
+ }
- return client.IsRebaseInProgress(clientCtx, req)
+ return true, nil
}
func validateIsRebaseInProgressRequest(req *pb.IsRebaseInProgressRequest) error {
@@ -39,5 +69,9 @@ func validateIsRebaseInProgressRequest(req *pb.IsRebaseInProgressRequest) error
return fmt.Errorf("empty RebaseId")
}
+ if strings.Contains(req.GetRebaseId(), "/") {
+ return fmt.Errorf("RebaseId contains '/'")
+ }
+
return nil
}
diff --git a/internal/service/repository/rebase_in_progress_test.go b/internal/service/repository/rebase_in_progress_test.go
index 7037028d1..d34165951 100644
--- a/internal/service/repository/rebase_in_progress_test.go
+++ b/internal/service/repository/rebase_in_progress_test.go
@@ -1,8 +1,11 @@
package repository
import (
+ "fmt"
+ "os"
"path"
"testing"
+ "time"
"gitlab.com/gitlab-org/gitaly/internal/testhelper"
@@ -22,7 +25,20 @@ func TestSuccessfulIsRebaseInProgressRequest(t *testing.T) {
testRepo1, testRepo1Path, cleanupFn := testhelper.NewTestRepo(t)
defer cleanupFn()
- testhelper.MustRunCommand(t, nil, "git", "-C", testRepo1Path, "worktree", "add", "--detach", path.Join(testRepo1Path, "gitlab-worktree", "rebase-1"), "master")
+ testhelper.MustRunCommand(t, nil, "git", "-C", testRepo1Path, "worktree", "add", "--detach", path.Join(testRepo1Path, worktreePrefix, fmt.Sprintf("%s-1", rebaseWorktreePrefix)), "master")
+
+ brokenPath := path.Join(testRepo1Path, worktreePrefix, fmt.Sprintf("%s-2", rebaseWorktreePrefix))
+ testhelper.MustRunCommand(t, nil, "git", "-C", testRepo1Path, "worktree", "add", "--detach", brokenPath, "master")
+ os.Chmod(brokenPath, 0)
+ os.Chtimes(brokenPath, time.Now(), time.Now().Add(-16*time.Minute))
+ defer func() {
+ os.Chmod(brokenPath, 0755)
+ os.RemoveAll(brokenPath)
+ }()
+
+ oldPath := path.Join(testRepo1Path, worktreePrefix, fmt.Sprintf("%s-3", rebaseWorktreePrefix))
+ testhelper.MustRunCommand(t, nil, "git", "-C", testRepo1Path, "worktree", "add", "--detach", oldPath, "master")
+ os.Chtimes(oldPath, time.Now(), time.Now().Add(-16*time.Minute))
testRepo2, _, cleanupFn := testhelper.NewTestRepo(t)
defer cleanupFn()
@@ -41,6 +57,22 @@ func TestSuccessfulIsRebaseInProgressRequest(t *testing.T) {
inProgress: true,
},
{
+ desc: "broken rebase in progress",
+ request: &pb.IsRebaseInProgressRequest{
+ Repository: testRepo1,
+ RebaseId: "2",
+ },
+ inProgress: false,
+ },
+ {
+ desc: "expired rebase in progress",
+ request: &pb.IsRebaseInProgressRequest{
+ Repository: testRepo1,
+ RebaseId: "3",
+ },
+ inProgress: false,
+ },
+ {
desc: "no rebase in progress",
request: &pb.IsRebaseInProgressRequest{
Repository: testRepo2,
diff --git a/internal/service/repository/search_files.go b/internal/service/repository/search_files.go
index 479ccff78..56c6d0318 100644
--- a/internal/service/repository/search_files.go
+++ b/internal/service/repository/search_files.go
@@ -50,14 +50,14 @@ func (s *server) SearchFilesByContent(req *pb.SearchFilesByContentRequest, strea
reader := func(objs [][]byte) error {
for _, obj := range objs {
obj = append(obj, '\n')
- if bytes.Compare(obj, contentDelimiter) == 0 {
+ if bytes.Equal(obj, contentDelimiter) {
matches = append(matches, buf)
buf = nil
} else {
buf = append(buf, obj...)
}
}
- if len(matches) > 1 {
+ if len(matches) > 0 {
err = stream.Send(&pb.SearchFilesByContentResponse{Matches: matches})
matches = nil
return err
@@ -69,8 +69,11 @@ func (s *server) SearchFilesByContent(req *pb.SearchFilesByContentRequest, strea
if err != nil {
return helper.DecorateError(codes.Internal, err)
}
- if len(buf) > 1 {
- return stream.Send(&pb.SearchFilesByContentResponse{Matches: [][]byte{buf}})
+ if len(buf) > 0 {
+ matches = append(matches, buf)
+ }
+ if len(matches) > 0 {
+ return stream.Send(&pb.SearchFilesByContentResponse{Matches: matches})
}
return nil
}
diff --git a/internal/service/repository/search_files_test.go b/internal/service/repository/search_files_test.go
index 042b929cb..2679e4715 100644
--- a/internal/service/repository/search_files_test.go
+++ b/internal/service/repository/search_files_test.go
@@ -54,6 +54,22 @@ var (
[]byte(""),
}, []byte{'\n'}),
}
+ contentCoffeeLines = [][]byte{
+ bytes.Join([][]byte{
+ []byte("many_files:CONTRIBUTING.md\x0092\x001. [Ruby style guide](https://github.com/bbatsov/ruby-style-guide)"),
+ []byte("many_files:CONTRIBUTING.md\x0093\x001. [Rails style guide](https://github.com/bbatsov/rails-style-guide)"),
+ []byte("many_files:CONTRIBUTING.md\x0094\x001. [CoffeeScript style guide](https://github.com/polarmobile/coffeescript-style-guide)"),
+ []byte("many_files:CONTRIBUTING.md\x0095\x001. [Shell command guidelines](doc/development/shell_commands.md)"),
+ []byte(""),
+ }, []byte{'\n'}),
+ bytes.Join([][]byte{
+ []byte("many_files:files/js/application.js\x001\x00// This is a manifest file that'll be compiled into including all the files listed below."),
+ []byte("many_files:files/js/application.js\x002\x00// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically"),
+ []byte("many_files:files/js/application.js\x003\x00// be included in the compiled file accessible from http://example.com/assets/application.js"),
+ []byte("many_files:files/js/application.js\x004\x00// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the"),
+ []byte(""),
+ }, []byte{'\n'}),
+ }
)
func TestSearchFilesByContentSuccessful(t *testing.T) {
@@ -82,11 +98,17 @@ func TestSearchFilesByContentSuccessful(t *testing.T) {
output: contentOutputLines,
},
{
- desc: "multi file in many_files",
+ desc: "single files, multiple matches",
query: "backup",
ref: "many_files",
output: contentMultiLines,
},
+ {
+ desc: "multiple files, multiple matches",
+ query: "coffee",
+ ref: "many_files",
+ output: contentCoffeeLines,
+ },
}
for _, tc := range testCases {
diff --git a/internal/service/repository/squash_in_progress.go b/internal/service/repository/squash_in_progress.go
index 3b0217237..2e284faa2 100644
--- a/internal/service/repository/squash_in_progress.go
+++ b/internal/service/repository/squash_in_progress.go
@@ -2,30 +2,35 @@ package repository
import (
"fmt"
+ "strings"
pb "gitlab.com/gitlab-org/gitaly-proto/go"
- "gitlab.com/gitlab-org/gitaly/internal/rubyserver"
+ "gitlab.com/gitlab-org/gitaly/internal/helper"
+
"golang.org/x/net/context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
+const (
+ squashWorktreePrefix = "squash"
+)
+
func (s *server) IsSquashInProgress(ctx context.Context, req *pb.IsSquashInProgressRequest) (*pb.IsSquashInProgressResponse, error) {
if err := validateIsSquashInProgressRequest(req); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "IsSquashInProgress: %v", err)
}
- client, err := s.RepositoryServiceClient(ctx)
+ repoPath, err := helper.GetRepoPath(req.GetRepository())
if err != nil {
return nil, err
}
- clientCtx, err := rubyserver.SetHeaders(ctx, req.GetRepository())
+ inProg, err := freshWorktree(repoPath, squashWorktreePrefix, req.GetSquashId())
if err != nil {
return nil, err
}
-
- return client.IsSquashInProgress(clientCtx, req)
+ return &pb.IsSquashInProgressResponse{InProgress: inProg}, nil
}
func validateIsSquashInProgressRequest(req *pb.IsSquashInProgressRequest) error {
@@ -37,5 +42,9 @@ func validateIsSquashInProgressRequest(req *pb.IsSquashInProgressRequest) error
return fmt.Errorf("empty SquashId")
}
+ if strings.Contains(req.GetSquashId(), "/") {
+ return fmt.Errorf("SquashId contains '/'")
+ }
+
return nil
}
diff --git a/internal/service/repository/squash_in_progress_test.go b/internal/service/repository/squash_in_progress_test.go
index 248887173..5d16545aa 100644
--- a/internal/service/repository/squash_in_progress_test.go
+++ b/internal/service/repository/squash_in_progress_test.go
@@ -22,7 +22,7 @@ func TestSuccessfulIsSquashInProgressRequest(t *testing.T) {
testRepo1, testRepo1Path, cleanupFn := testhelper.NewTestRepo(t)
defer cleanupFn()
- testhelper.MustRunCommand(t, nil, "git", "-C", testRepo1Path, "worktree", "add", "--detach", path.Join(testRepo1Path, "gitlab-worktree", "squash-1"), "master")
+ testhelper.MustRunCommand(t, nil, "git", "-C", testRepo1Path, "worktree", "add", "--detach", path.Join(testRepo1Path, worktreePrefix, "squash-1"), "master")
testRepo2, _, cleanupFn := testhelper.NewTestRepo(t)
defer cleanupFn()
diff --git a/internal/service/storage/.gitignore b/internal/service/storage/.gitignore
new file mode 100644
index 000000000..2743e47ce
--- /dev/null
+++ b/internal/service/storage/.gitignore
@@ -0,0 +1 @@
+/testdata/repositories
diff --git a/internal/service/storage/deleteall.go b/internal/service/storage/deleteall.go
new file mode 100644
index 000000000..74951466f
--- /dev/null
+++ b/internal/service/storage/deleteall.go
@@ -0,0 +1,69 @@
+package storage
+
+import (
+ "io"
+ "os"
+ "path"
+
+ "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
+ log "github.com/sirupsen/logrus"
+ pb "gitlab.com/gitlab-org/gitaly-proto/go"
+ "gitlab.com/gitlab-org/gitaly/internal/helper"
+ "gitlab.com/gitlab-org/gitaly/internal/tempdir"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+func (s *server) DeleteAllRepositories(ctx context.Context, req *pb.DeleteAllRepositoriesRequest) (*pb.DeleteAllRepositoriesResponse, error) {
+ storageDir, err := helper.GetStorageByName(req.StorageName)
+ if err != nil {
+ return nil, status.Errorf(codes.InvalidArgument, "storage lookup failed: %v", err)
+ }
+
+ trashDir, err := tempdir.ForDeleteAllRepositories(req.StorageName)
+ if err != nil {
+ return nil, status.Errorf(codes.Internal, "create trash dir: %v", err)
+ }
+
+ dir, err := os.Open(storageDir)
+ if err != nil {
+ return nil, status.Errorf(codes.Internal, "open storage dir: %v", err)
+ }
+ defer dir.Close()
+
+ grpc_logrus.Extract(ctx).WithFields(log.Fields{
+ "trashDir": trashDir,
+ "storage": req.StorageName,
+ }).Warn("moving all repositories in storage to trash")
+
+ count := 0
+ for done := false; !done; {
+ dirents, err := dir.Readdir(100)
+ if err == io.EOF {
+ done = true
+ } else if err != nil {
+ return nil, status.Errorf(codes.Internal, "read storage dir: %v", err)
+ }
+
+ for _, d := range dirents {
+ if d.Name() == tempdir.GitalyDataPrefix {
+ continue
+ }
+
+ count++
+
+ if err := os.Rename(path.Join(storageDir, d.Name()), path.Join(trashDir, d.Name())); err != nil {
+ return nil, status.Errorf(codes.Internal, "move dir: %v", err)
+ }
+ }
+ }
+
+ grpc_logrus.Extract(ctx).WithFields(log.Fields{
+ "trashDir": trashDir,
+ "storage": req.StorageName,
+ "numDirectories": count,
+ }).Warn("directories moved to trash")
+
+ return &pb.DeleteAllRepositoriesResponse{}, nil
+}
diff --git a/internal/service/storage/deleteall_test.go b/internal/service/storage/deleteall_test.go
new file mode 100644
index 000000000..4d51fbee3
--- /dev/null
+++ b/internal/service/storage/deleteall_test.go
@@ -0,0 +1,133 @@
+package storage
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ pb "gitlab.com/gitlab-org/gitaly-proto/go"
+ "gitlab.com/gitlab-org/gitaly/internal/config"
+ "gitlab.com/gitlab-org/gitaly/internal/tempdir"
+ "gitlab.com/gitlab-org/gitaly/internal/testhelper"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+func TestDeleteAllSuccess(t *testing.T) {
+ require.NoError(t, os.RemoveAll(testStorage.Path))
+
+ gitalyDataFile := path.Join(testStorage.Path, tempdir.GitalyDataPrefix+"/foobar")
+ require.NoError(t, os.MkdirAll(path.Dir(gitalyDataFile), 0755))
+ require.NoError(t, ioutil.WriteFile(gitalyDataFile, nil, 0644))
+
+ repoPaths := []string{
+ "foo/bar1.git",
+ "foo/bar2.git",
+ "baz/foo/qux3.git",
+ "baz/foo/bar1.git",
+ }
+
+ for _, p := range repoPaths {
+ fullPath := path.Join(testStorage.Path, p)
+ require.NoError(t, os.MkdirAll(fullPath, 0755))
+ require.NoError(t, exec.Command("git", "init", "--bare", fullPath).Run())
+ }
+
+ dirents := storageDirents(t, testStorage)
+ expectedNames := []string{"+gitaly", "baz", "foo"}
+ require.Len(t, dirents, len(expectedNames))
+ for i, expected := range expectedNames {
+ require.Equal(t, expected, dirents[i].Name())
+ }
+
+ server, socketPath := runStorageServer(t)
+ defer server.Stop()
+
+ client, conn := newStorageClient(t, socketPath)
+ defer conn.Close()
+
+ ctx, cancel := testhelper.Context()
+ defer cancel()
+ _, err := client.DeleteAllRepositories(ctx, &pb.DeleteAllRepositoriesRequest{StorageName: testStorage.Name})
+ require.NoError(t, err)
+
+ dirents = storageDirents(t, testStorage)
+ require.Len(t, dirents, 1)
+ require.Equal(t, "+gitaly", dirents[0].Name())
+
+ _, err = os.Stat(gitalyDataFile)
+ require.NoError(t, err, "unrelated data file should still exist")
+}
+
+func storageDirents(t *testing.T, st config.Storage) []os.FileInfo {
+ dirents, err := ioutil.ReadDir(st.Path)
+ require.NoError(t, err)
+ return dirents
+}
+
+func TestDeleteAllFail(t *testing.T) {
+ server, socketPath := runStorageServer(t)
+ defer server.Stop()
+
+ client, conn := newStorageClient(t, socketPath)
+ defer conn.Close()
+
+ ctx, cancel := testhelper.Context()
+ defer cancel()
+
+ testCases := []struct {
+ desc string
+ req *pb.DeleteAllRepositoriesRequest
+ setup func(t *testing.T)
+ code codes.Code
+ }{
+ {
+ desc: "empty storage name",
+ req: &pb.DeleteAllRepositoriesRequest{},
+ code: codes.InvalidArgument,
+ },
+ {
+ desc: "unknown storage name",
+ req: &pb.DeleteAllRepositoriesRequest{StorageName: "does not exist"},
+ code: codes.InvalidArgument,
+ },
+ {
+ desc: "cannot create trash dir",
+ req: &pb.DeleteAllRepositoriesRequest{StorageName: testStorage.Name},
+ setup: func(t *testing.T) {
+ dataDir := path.Join(testStorage.Path, tempdir.GitalyDataPrefix)
+ require.NoError(t, os.RemoveAll(dataDir))
+ require.NoError(t, ioutil.WriteFile(dataDir, nil, 0644), "write file where there should be a directory")
+
+ lsOut, err := exec.Command("ls", "-l", testStorage.Path).CombinedOutput()
+ require.NoError(t, err)
+ fmt.Printf("%s\n", lsOut)
+ },
+ code: codes.Internal,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.desc, func(t *testing.T) {
+ require.NoError(t, os.RemoveAll(testStorage.Path))
+ require.NoError(t, os.MkdirAll(testStorage.Path, 0755))
+
+ repoPath := path.Join(testStorage.Path, "foobar.git")
+ require.NoError(t, exec.Command("git", "init", "--bare", repoPath).Run())
+
+ if tc.setup != nil {
+ tc.setup(t)
+ }
+
+ _, err := client.DeleteAllRepositories(ctx, tc.req)
+ require.Equal(t, tc.code, status.Code(err), "expected grpc status code")
+
+ _, err = os.Stat(repoPath)
+ require.NoError(t, err, "repo must still exist")
+ })
+ }
+}
diff --git a/internal/service/storage/server.go b/internal/service/storage/server.go
new file mode 100644
index 000000000..76d051a6a
--- /dev/null
+++ b/internal/service/storage/server.go
@@ -0,0 +1,12 @@
+package storage
+
+import (
+ pb "gitlab.com/gitlab-org/gitaly-proto/go"
+)
+
+type server struct{}
+
+// NewServer creates a new instance of a gRPC storage server
+func NewServer() pb.StorageServiceServer {
+ return &server{}
+}
diff --git a/internal/service/storage/testhelper_test.go b/internal/service/storage/testhelper_test.go
new file mode 100644
index 000000000..3f245e0dd
--- /dev/null
+++ b/internal/service/storage/testhelper_test.go
@@ -0,0 +1,74 @@
+package storage
+
+import (
+ "net"
+ "os"
+ "path/filepath"
+ "testing"
+ "time"
+
+ pb "gitlab.com/gitlab-org/gitaly-proto/go"
+ "gitlab.com/gitlab-org/gitaly/internal/config"
+ "gitlab.com/gitlab-org/gitaly/internal/testhelper"
+
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/reflection"
+)
+
+var testStorage config.Storage
+
+func TestMain(m *testing.M) {
+ configureTestStorage()
+ os.Exit(m.Run())
+}
+
+func configureTestStorage() {
+ storagePath, err := filepath.Abs("testdata/repositories/storage1")
+ if err != nil {
+ panic(err)
+ }
+
+ if err := os.RemoveAll(storagePath); err != nil {
+ panic(err)
+ }
+
+ if err := os.MkdirAll(storagePath, 0755); err != nil {
+ panic(err)
+ }
+
+ testStorage = config.Storage{Name: "storage-will-be-deleted", Path: storagePath}
+
+ config.Config.Storages = []config.Storage{testStorage}
+}
+
+func runStorageServer(t *testing.T) (*grpc.Server, string) {
+ server := testhelper.NewTestGrpcServer(t, nil, nil)
+ serverSocketPath := testhelper.GetTemporaryGitalySocketFileName()
+
+ listener, err := net.Listen("unix", serverSocketPath)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ pb.RegisterStorageServiceServer(server, NewServer())
+ reflection.Register(server)
+
+ go server.Serve(listener)
+
+ return server, serverSocketPath
+}
+
+func newStorageClient(t *testing.T, serverSocketPath string) (pb.StorageServiceClient, *grpc.ClientConn) {
+ connOpts := []grpc.DialOption{
+ grpc.WithInsecure(),
+ grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
+ return net.DialTimeout("unix", addr, timeout)
+ }),
+ }
+ conn, err := grpc.Dial(serverSocketPath, connOpts...)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ return pb.NewStorageServiceClient(conn), conn
+}
diff --git a/internal/tempdir/tempdir.go b/internal/tempdir/tempdir.go
index 649a91f0b..18b4e7bb9 100644
--- a/internal/tempdir/tempdir.go
+++ b/internal/tempdir/tempdir.go
@@ -2,6 +2,7 @@ package tempdir
import (
"context"
+ "fmt"
"io/ioutil"
"os"
"path/filepath"
@@ -17,14 +18,30 @@ import (
)
const (
- // We need to be careful that this path does not clash with any
- // directory name that could be provided by a user. The '+' character is
- // not allowed in GitLab namespaces or repositories.
- tmpRootPrefix = "+gitaly/tmp"
-
- maxAge = 7 * 24 * time.Hour
+ // GitalyDataPrefix is the top-level directory we use to store system
+ // (non-user) data. We need to be careful that this path does not clash
+ // with any directory name that could be provided by a user. The '+'
+ // character is not allowed in GitLab namespaces or repositories.
+ GitalyDataPrefix = "+gitaly"
+
+ // TmpRootPrefix is the directory in which we store temporary
+ // directories.
+ TmpRootPrefix = GitalyDataPrefix + "/tmp"
+
+ // MaxAge is used by ForDeleteAllRepositories. It is also a fallback
+ // for the context-scoped temporary directories, to ensure they get
+ // cleaned up if the cleanup at the end of the context failed to run.
+ MaxAge = 7 * 24 * time.Hour
)
+// ForDeleteAllRepositories returns a temporary directory for the given storage. It is not context-scoped but it will get removed eventuall (after MaxAge).
+func ForDeleteAllRepositories(storageName string) (string, error) {
+ prefix := fmt.Sprintf("%s-repositories.old.%d.", storageName, time.Now().Unix())
+ _, path, err := newAsRepository(context.Background(), storageName, prefix)
+
+ return path, err
+}
+
// New returns the path of a new temporary directory for use with the
// repository. The directory is removed with os.RemoveAll when ctx
// expires.
@@ -40,7 +57,11 @@ func New(ctx context.Context, repo *pb.Repository) (string, error) {
// NewAsRepository is the same as New, but it returns a *pb.Repository for the
// created directory as well as the bare path as a string
func NewAsRepository(ctx context.Context, repo *pb.Repository) (*pb.Repository, string, error) {
- storageDir, err := helper.GetStorageByName(repo.StorageName)
+ return newAsRepository(ctx, repo.StorageName, "repo")
+}
+
+func newAsRepository(ctx context.Context, storageName string, prefix string) (*pb.Repository, string, error) {
+ storageDir, err := helper.GetStorageByName(storageName)
if err != nil {
return nil, "", err
}
@@ -50,7 +71,7 @@ func NewAsRepository(ctx context.Context, repo *pb.Repository) (*pb.Repository,
return nil, "", err
}
- tempDir, err := ioutil.TempDir(root, "repo")
+ tempDir, err := ioutil.TempDir(root, prefix)
if err != nil {
return nil, "", err
}
@@ -60,13 +81,13 @@ func NewAsRepository(ctx context.Context, repo *pb.Repository) (*pb.Repository,
os.RemoveAll(tempDir)
}()
- newAsRepo := &pb.Repository{StorageName: repo.StorageName}
+ newAsRepo := &pb.Repository{StorageName: storageName}
newAsRepo.RelativePath, err = filepath.Rel(storageDir, tempDir)
return newAsRepo, tempDir, err
}
func tmpRoot(storageRoot string) string {
- return filepath.Join(storageRoot, tmpRootPrefix)
+ return filepath.Join(storageRoot, TmpRootPrefix)
}
// StartCleaning starts tempdir cleanup goroutines.
@@ -95,7 +116,7 @@ type invalidCleanRoot string
func clean(dir string) error {
// If we start "cleaning up" the wrong directory we may delete user data
// which is Really Bad.
- if !strings.HasSuffix(dir, tmpRootPrefix) {
+ if !strings.HasSuffix(dir, TmpRootPrefix) {
log.Print(dir)
panic(invalidCleanRoot("invalid tempdir clean root: panicking to prevent data loss"))
}
@@ -109,7 +130,7 @@ func clean(dir string) error {
}
for _, info := range entries {
- if time.Since(info.ModTime()) < maxAge {
+ if time.Since(info.ModTime()) < MaxAge {
continue
}
diff --git a/internal/tempdir/tempdir_test.go b/internal/tempdir/tempdir_test.go
index 112659473..4f1311151 100644
--- a/internal/tempdir/tempdir_test.go
+++ b/internal/tempdir/tempdir_test.go
@@ -53,7 +53,7 @@ func TestNewAsRepositoryFailStorageUnknown(t *testing.T) {
require.Error(t, err)
}
-var cleanRoot = path.Join("testdata/clean", tmpRootPrefix)
+var cleanRoot = path.Join("testdata/clean", TmpRootPrefix)
func TestCleanerSafety(t *testing.T) {
defer func() {
@@ -135,7 +135,7 @@ func makeDir(t *testing.T, dirPath string, mtime time.Time) {
func TestCleanNoTmpExists(t *testing.T) {
// This directory is valid because it ends in the special prefix
- dir := path.Join("testdata", "does-not-exist", tmpRootPrefix)
+ dir := path.Join("testdata", "does-not-exist", TmpRootPrefix)
require.NoError(t, clean(dir))
}
diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go
index 10dd4507e..892c11b78 100644
--- a/internal/testhelper/testhelper.go
+++ b/internal/testhelper/testhelper.go
@@ -259,12 +259,6 @@ func ConfigureRuby() {
if err := config.ConfigureRuby(); err != nil {
log.Fatal("validate ruby config: %v", err)
}
-
- // This speeds up test boot-up. The reason we use more than 1 worker in
- // production is to handle memory leaks, but the tests don't run for long
- // enough to hit those memory leaks anyway. Most tests also run faster
- // than the minimum delay before a ruby worker failover can even happen.
- config.Config.Ruby.NumWorkers = 1
}
// NewTestGrpcServer creates a GRPC Server for testing purposes
diff --git a/ruby/Gemfile b/ruby/Gemfile
index a5d7da71d..4d89e2f0d 100644
--- a/ruby/Gemfile
+++ b/ruby/Gemfile
@@ -10,6 +10,7 @@ gem 'gitlab-gollum-lib', '~> 4.2', require: false
gem 'gitlab-gollum-rugged_adapter', '~> 0.4.4', require: false
gem 'grpc', '~> 1.11.0'
gem 'sentry-raven', '~> 2.7.2', require: false
+gem 'faraday', '~> 0.12'
# Detects the open source license the repository includes
# This version needs to be in sync with GitLab CE/EE
diff --git a/ruby/Gemfile.lock b/ruby/Gemfile.lock
index bbb14e902..c6d9562c2 100644
--- a/ruby/Gemfile.lock
+++ b/ruby/Gemfile.lock
@@ -13,7 +13,7 @@ GEM
concurrent-ruby (1.0.5)
diff-lcs (1.3)
escape_utils (1.1.1)
- faraday (0.14.0)
+ faraday (0.12.2)
multipart-post (>= 1.2, < 3)
gemojione (3.3.0)
json
@@ -141,6 +141,7 @@ PLATFORMS
DEPENDENCIES
activesupport (~> 5.0.2)
+ faraday (~> 0.12)
gitaly-proto (~> 0.99.0)
github-linguist (~> 5.3.3)
gitlab-gollum-lib (~> 4.2)
diff --git a/ruby/bin/gitaly-ruby b/ruby/bin/gitaly-ruby
index 87acda775..7c16d2f0e 100755
--- a/ruby/bin/gitaly-ruby
+++ b/ruby/bin/gitaly-ruby
@@ -35,6 +35,7 @@ def main
s.add_http2_port(port, :this_port_is_insecure)
GRPC.logger.info("... running insecurely on #{port}")
+ GRPC.logger.warn("Using gitaly-proto #{Gitaly::VERSION}")
GitalyServer.register_handlers(s)
signal_thread = Thread.new do
diff --git a/ruby/bin/ruby-cd b/ruby/bin/ruby-cd
index 9dfb91e84..9c60fcd42 100755
--- a/ruby/bin/ruby-cd
+++ b/ruby/bin/ruby-cd
@@ -2,5 +2,7 @@
# This script lets you run `bundle exec` in one directory, and then changes into another.
+warn "PID #{Process.pid} BUNDLE_GEMFILE=#{ENV['BUNDLE_GEMFILE']}"
+
Dir.chdir(ARGV.shift)
exec(*ARGV)
diff --git a/ruby/lib/gitaly_server/repository_service.rb b/ruby/lib/gitaly_server/repository_service.rb
index 934870bb9..48ee81a1a 100644
--- a/ruby/lib/gitaly_server/repository_service.rb
+++ b/ruby/lib/gitaly_server/repository_service.rb
@@ -8,7 +8,7 @@ module GitalyServer
bridge_exceptions do
repo_path = GitalyServer.repo_path(call)
- Gitlab::Git::Repository.create(repo_path, bare: true, symlink_hooks_to: Gitlab.config.gitlab_shell.hooks_path)
+ Gitlab::Git::Repository.create(repo_path)
Gitaly::CreateRepositoryResponse.new
end
diff --git a/ruby/lib/gitlab/git/repository.rb b/ruby/lib/gitlab/git/repository.rb
index f82bed70e..b61c03b97 100644
--- a/ruby/lib/gitlab/git/repository.rb
+++ b/ruby/lib/gitlab/git/repository.rb
@@ -2,14 +2,53 @@ module Gitlab
module Git
# These are monkey patches on top of the vendored version of Repository.
class Repository
- def self.from_gitaly(gitaly_repository, call)
- new(
- gitaly_repository,
- GitalyServer.repo_path(call),
- GitalyServer.gl_repository(call),
- Gitlab::Git::GitlabProjects.from_gitaly(gitaly_repository, call),
- GitalyServer.repo_alt_dirs(call)
- )
+ class << self
+ def from_gitaly(gitaly_repository, call)
+ new(
+ gitaly_repository,
+ GitalyServer.repo_path(call),
+ GitalyServer.gl_repository(call),
+ Gitlab::Git::GitlabProjects.from_gitaly(gitaly_repository, call),
+ GitalyServer.repo_alt_dirs(call)
+ )
+ end
+
+ def create(repo_path)
+ FileUtils.mkdir_p(repo_path, mode: 0770)
+
+ # Equivalent to `git --git-path=#{repo_path} init [--bare]`
+ repo = Rugged::Repository.init_at(repo_path, true)
+ repo.close
+
+ symlink_hooks_to = Gitlab.config.gitlab_shell.hooks_path
+ create_hooks(repo_path, symlink_hooks_to) if symlink_hooks_to.present?
+ end
+
+ def create_hooks(repo_path, global_hooks_path)
+ local_hooks_path = File.join(repo_path, 'hooks')
+ real_local_hooks_path = :not_found
+
+ begin
+ real_local_hooks_path = File.realpath(local_hooks_path)
+ rescue Errno::ENOENT
+ # real_local_hooks_path == :not_found
+ end
+
+ # Do nothing if hooks already exist
+ unless real_local_hooks_path == File.realpath(global_hooks_path)
+ if File.exist?(local_hooks_path)
+ # Move the existing hooks somewhere safe
+ FileUtils.mv(
+ local_hooks_path,
+ "#{local_hooks_path}.old.#{Time.now.to_i}")
+ end
+
+ # Create the hooks symlink
+ FileUtils.ln_sf(global_hooks_path, local_hooks_path)
+ end
+
+ true
+ end
end
attr_reader :path
@@ -28,6 +67,16 @@ module Gitlab
@gitlab_projects = gitlab_projects
end
+ def add_branch(branch_name, user:, target:)
+ target_object = Ref.dereference_object(lookup(target))
+ raise InvalidRef.new("target not found: #{target}") unless target_object
+
+ OperationService.new(user, self).add_branch(branch_name, target_object.oid)
+ find_branch(branch_name)
+ rescue Rugged::ReferenceError => ex
+ raise InvalidRef, ex
+ end
+
def circuit_breaker
FakeCircuitBreaker
end
diff --git a/vendor/gitlab.com/gitlab-org/gitaly-proto/go/VERSION b/vendor/gitlab.com/gitlab-org/gitaly-proto/go/VERSION
index 01781720c..897e21587 100644
--- a/vendor/gitlab.com/gitlab-org/gitaly-proto/go/VERSION
+++ b/vendor/gitlab.com/gitlab-org/gitaly-proto/go/VERSION
@@ -1 +1 @@
-0.99.0
+0.100.0
diff --git a/vendor/gitlab.com/gitlab-org/gitaly-proto/go/blob.pb.go b/vendor/gitlab.com/gitlab-org/gitaly-proto/go/blob.pb.go
index d3e3209ca..999e12a08 100644
--- a/vendor/gitlab.com/gitlab-org/gitaly-proto/go/blob.pb.go
+++ b/vendor/gitlab.com/gitlab-org/gitaly-proto/go/blob.pb.go
@@ -20,6 +20,7 @@ It is generated from these files:
shared.proto
smarthttp.proto
ssh.proto
+ storage.proto
wiki.proto
It has these top-level messages:
@@ -250,6 +251,8 @@ It has these top-level messages:
SSHReceivePackResponse
SSHUploadArchiveRequest
SSHUploadArchiveResponse
+ DeleteAllRepositoriesRequest
+ DeleteAllRepositoriesResponse
WikiCommitDetails
WikiPageVersion
WikiPage
diff --git a/vendor/gitlab.com/gitlab-org/gitaly-proto/go/storage.pb.go b/vendor/gitlab.com/gitlab-org/gitaly-proto/go/storage.pb.go
new file mode 100644
index 000000000..e106695e2
--- /dev/null
+++ b/vendor/gitlab.com/gitlab-org/gitaly-proto/go/storage.pb.go
@@ -0,0 +1,135 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: storage.proto
+
+package gitaly
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+import (
+ context "golang.org/x/net/context"
+ grpc "google.golang.org/grpc"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+type DeleteAllRepositoriesRequest struct {
+ StorageName string `protobuf:"bytes,1,opt,name=storage_name,json=storageName" json:"storage_name,omitempty"`
+}
+
+func (m *DeleteAllRepositoriesRequest) Reset() { *m = DeleteAllRepositoriesRequest{} }
+func (m *DeleteAllRepositoriesRequest) String() string { return proto.CompactTextString(m) }
+func (*DeleteAllRepositoriesRequest) ProtoMessage() {}
+func (*DeleteAllRepositoriesRequest) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{0} }
+
+func (m *DeleteAllRepositoriesRequest) GetStorageName() string {
+ if m != nil {
+ return m.StorageName
+ }
+ return ""
+}
+
+type DeleteAllRepositoriesResponse struct {
+}
+
+func (m *DeleteAllRepositoriesResponse) Reset() { *m = DeleteAllRepositoriesResponse{} }
+func (m *DeleteAllRepositoriesResponse) String() string { return proto.CompactTextString(m) }
+func (*DeleteAllRepositoriesResponse) ProtoMessage() {}
+func (*DeleteAllRepositoriesResponse) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{1} }
+
+func init() {
+ proto.RegisterType((*DeleteAllRepositoriesRequest)(nil), "gitaly.DeleteAllRepositoriesRequest")
+ proto.RegisterType((*DeleteAllRepositoriesResponse)(nil), "gitaly.DeleteAllRepositoriesResponse")
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// Client API for StorageService service
+
+type StorageServiceClient interface {
+ DeleteAllRepositories(ctx context.Context, in *DeleteAllRepositoriesRequest, opts ...grpc.CallOption) (*DeleteAllRepositoriesResponse, error)
+}
+
+type storageServiceClient struct {
+ cc *grpc.ClientConn
+}
+
+func NewStorageServiceClient(cc *grpc.ClientConn) StorageServiceClient {
+ return &storageServiceClient{cc}
+}
+
+func (c *storageServiceClient) DeleteAllRepositories(ctx context.Context, in *DeleteAllRepositoriesRequest, opts ...grpc.CallOption) (*DeleteAllRepositoriesResponse, error) {
+ out := new(DeleteAllRepositoriesResponse)
+ err := grpc.Invoke(ctx, "/gitaly.StorageService/DeleteAllRepositories", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// Server API for StorageService service
+
+type StorageServiceServer interface {
+ DeleteAllRepositories(context.Context, *DeleteAllRepositoriesRequest) (*DeleteAllRepositoriesResponse, error)
+}
+
+func RegisterStorageServiceServer(s *grpc.Server, srv StorageServiceServer) {
+ s.RegisterService(&_StorageService_serviceDesc, srv)
+}
+
+func _StorageService_DeleteAllRepositories_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(DeleteAllRepositoriesRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(StorageServiceServer).DeleteAllRepositories(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/gitaly.StorageService/DeleteAllRepositories",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(StorageServiceServer).DeleteAllRepositories(ctx, req.(*DeleteAllRepositoriesRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+var _StorageService_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "gitaly.StorageService",
+ HandlerType: (*StorageServiceServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "DeleteAllRepositories",
+ Handler: _StorageService_DeleteAllRepositories_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "storage.proto",
+}
+
+func init() { proto.RegisterFile("storage.proto", fileDescriptor15) }
+
+var fileDescriptor15 = []byte{
+ // 159 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2d, 0x2e, 0xc9, 0x2f,
+ 0x4a, 0x4c, 0x4f, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x4b, 0xcf, 0x2c, 0x49, 0xcc,
+ 0xa9, 0x54, 0x72, 0xe4, 0x92, 0x71, 0x49, 0xcd, 0x49, 0x2d, 0x49, 0x75, 0xcc, 0xc9, 0x09, 0x4a,
+ 0x2d, 0xc8, 0x2f, 0xce, 0x2c, 0xc9, 0x2f, 0xca, 0x4c, 0x2d, 0x0e, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d,
+ 0x2e, 0x11, 0x52, 0xe4, 0xe2, 0x81, 0x6a, 0x8c, 0xcf, 0x4b, 0xcc, 0x4d, 0x95, 0x60, 0x54, 0x60,
+ 0xd4, 0xe0, 0x0c, 0xe2, 0x86, 0x8a, 0xf9, 0x25, 0xe6, 0xa6, 0x2a, 0xc9, 0x73, 0xc9, 0xe2, 0x30,
+ 0xa2, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0xd5, 0xa8, 0x82, 0x8b, 0x2f, 0x18, 0xa2, 0x3e, 0x38, 0xb5,
+ 0xa8, 0x2c, 0x33, 0x39, 0x55, 0x28, 0x8d, 0x4b, 0x14, 0xab, 0x16, 0x21, 0x15, 0x3d, 0x88, 0xbb,
+ 0xf4, 0xf0, 0x39, 0x4a, 0x4a, 0x95, 0x80, 0x2a, 0x88, 0xbd, 0x4a, 0x0c, 0x49, 0x6c, 0x60, 0xcf,
+ 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x3d, 0x21, 0xd8, 0x88, 0xfd, 0x00, 0x00, 0x00,
+}
diff --git a/vendor/gitlab.com/gitlab-org/gitaly-proto/go/wiki.pb.go b/vendor/gitlab.com/gitlab-org/gitaly-proto/go/wiki.pb.go
index 4401f204d..3cebea71a 100644
--- a/vendor/gitlab.com/gitlab-org/gitaly-proto/go/wiki.pb.go
+++ b/vendor/gitlab.com/gitlab-org/gitaly-proto/go/wiki.pb.go
@@ -28,7 +28,7 @@ type WikiCommitDetails struct {
func (m *WikiCommitDetails) Reset() { *m = WikiCommitDetails{} }
func (m *WikiCommitDetails) String() string { return proto.CompactTextString(m) }
func (*WikiCommitDetails) ProtoMessage() {}
-func (*WikiCommitDetails) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{0} }
+func (*WikiCommitDetails) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{0} }
func (m *WikiCommitDetails) GetName() []byte {
if m != nil {
@@ -73,7 +73,7 @@ type WikiPageVersion struct {
func (m *WikiPageVersion) Reset() { *m = WikiPageVersion{} }
func (m *WikiPageVersion) String() string { return proto.CompactTextString(m) }
func (*WikiPageVersion) ProtoMessage() {}
-func (*WikiPageVersion) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{1} }
+func (*WikiPageVersion) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{1} }
func (m *WikiPageVersion) GetCommit() *GitCommit {
if m != nil {
@@ -105,7 +105,7 @@ type WikiPage struct {
func (m *WikiPage) Reset() { *m = WikiPage{} }
func (m *WikiPage) String() string { return proto.CompactTextString(m) }
func (*WikiPage) ProtoMessage() {}
-func (*WikiPage) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{2} }
+func (*WikiPage) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{2} }
func (m *WikiPage) GetVersion() *WikiPageVersion {
if m != nil {
@@ -173,7 +173,7 @@ type WikiGetPageVersionsRequest struct {
func (m *WikiGetPageVersionsRequest) Reset() { *m = WikiGetPageVersionsRequest{} }
func (m *WikiGetPageVersionsRequest) String() string { return proto.CompactTextString(m) }
func (*WikiGetPageVersionsRequest) ProtoMessage() {}
-func (*WikiGetPageVersionsRequest) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{3} }
+func (*WikiGetPageVersionsRequest) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{3} }
func (m *WikiGetPageVersionsRequest) GetRepository() *Repository {
if m != nil {
@@ -210,7 +210,7 @@ type WikiGetPageVersionsResponse struct {
func (m *WikiGetPageVersionsResponse) Reset() { *m = WikiGetPageVersionsResponse{} }
func (m *WikiGetPageVersionsResponse) String() string { return proto.CompactTextString(m) }
func (*WikiGetPageVersionsResponse) ProtoMessage() {}
-func (*WikiGetPageVersionsResponse) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{4} }
+func (*WikiGetPageVersionsResponse) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{4} }
func (m *WikiGetPageVersionsResponse) GetVersions() []*WikiPageVersion {
if m != nil {
@@ -233,7 +233,7 @@ type WikiWritePageRequest struct {
func (m *WikiWritePageRequest) Reset() { *m = WikiWritePageRequest{} }
func (m *WikiWritePageRequest) String() string { return proto.CompactTextString(m) }
func (*WikiWritePageRequest) ProtoMessage() {}
-func (*WikiWritePageRequest) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{5} }
+func (*WikiWritePageRequest) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{5} }
func (m *WikiWritePageRequest) GetRepository() *Repository {
if m != nil {
@@ -277,7 +277,7 @@ type WikiWritePageResponse struct {
func (m *WikiWritePageResponse) Reset() { *m = WikiWritePageResponse{} }
func (m *WikiWritePageResponse) String() string { return proto.CompactTextString(m) }
func (*WikiWritePageResponse) ProtoMessage() {}
-func (*WikiWritePageResponse) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{6} }
+func (*WikiWritePageResponse) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{6} }
func (m *WikiWritePageResponse) GetDuplicateError() []byte {
if m != nil {
@@ -300,7 +300,7 @@ type WikiUpdatePageRequest struct {
func (m *WikiUpdatePageRequest) Reset() { *m = WikiUpdatePageRequest{} }
func (m *WikiUpdatePageRequest) String() string { return proto.CompactTextString(m) }
func (*WikiUpdatePageRequest) ProtoMessage() {}
-func (*WikiUpdatePageRequest) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{7} }
+func (*WikiUpdatePageRequest) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{7} }
func (m *WikiUpdatePageRequest) GetRepository() *Repository {
if m != nil {
@@ -351,7 +351,7 @@ type WikiUpdatePageResponse struct {
func (m *WikiUpdatePageResponse) Reset() { *m = WikiUpdatePageResponse{} }
func (m *WikiUpdatePageResponse) String() string { return proto.CompactTextString(m) }
func (*WikiUpdatePageResponse) ProtoMessage() {}
-func (*WikiUpdatePageResponse) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{8} }
+func (*WikiUpdatePageResponse) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{8} }
func (m *WikiUpdatePageResponse) GetError() []byte {
if m != nil {
@@ -369,7 +369,7 @@ type WikiDeletePageRequest struct {
func (m *WikiDeletePageRequest) Reset() { *m = WikiDeletePageRequest{} }
func (m *WikiDeletePageRequest) String() string { return proto.CompactTextString(m) }
func (*WikiDeletePageRequest) ProtoMessage() {}
-func (*WikiDeletePageRequest) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{9} }
+func (*WikiDeletePageRequest) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{9} }
func (m *WikiDeletePageRequest) GetRepository() *Repository {
if m != nil {
@@ -398,7 +398,7 @@ type WikiDeletePageResponse struct {
func (m *WikiDeletePageResponse) Reset() { *m = WikiDeletePageResponse{} }
func (m *WikiDeletePageResponse) String() string { return proto.CompactTextString(m) }
func (*WikiDeletePageResponse) ProtoMessage() {}
-func (*WikiDeletePageResponse) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{10} }
+func (*WikiDeletePageResponse) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{10} }
type WikiFindPageRequest struct {
Repository *Repository `protobuf:"bytes,1,opt,name=repository" json:"repository,omitempty"`
@@ -410,7 +410,7 @@ type WikiFindPageRequest struct {
func (m *WikiFindPageRequest) Reset() { *m = WikiFindPageRequest{} }
func (m *WikiFindPageRequest) String() string { return proto.CompactTextString(m) }
func (*WikiFindPageRequest) ProtoMessage() {}
-func (*WikiFindPageRequest) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{11} }
+func (*WikiFindPageRequest) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{11} }
func (m *WikiFindPageRequest) GetRepository() *Repository {
if m != nil {
@@ -449,7 +449,7 @@ type WikiFindPageResponse struct {
func (m *WikiFindPageResponse) Reset() { *m = WikiFindPageResponse{} }
func (m *WikiFindPageResponse) String() string { return proto.CompactTextString(m) }
func (*WikiFindPageResponse) ProtoMessage() {}
-func (*WikiFindPageResponse) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{12} }
+func (*WikiFindPageResponse) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{12} }
func (m *WikiFindPageResponse) GetPage() *WikiPage {
if m != nil {
@@ -468,7 +468,7 @@ type WikiFindFileRequest struct {
func (m *WikiFindFileRequest) Reset() { *m = WikiFindFileRequest{} }
func (m *WikiFindFileRequest) String() string { return proto.CompactTextString(m) }
func (*WikiFindFileRequest) ProtoMessage() {}
-func (*WikiFindFileRequest) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{13} }
+func (*WikiFindFileRequest) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{13} }
func (m *WikiFindFileRequest) GetRepository() *Repository {
if m != nil {
@@ -502,7 +502,7 @@ type WikiFindFileResponse struct {
func (m *WikiFindFileResponse) Reset() { *m = WikiFindFileResponse{} }
func (m *WikiFindFileResponse) String() string { return proto.CompactTextString(m) }
func (*WikiFindFileResponse) ProtoMessage() {}
-func (*WikiFindFileResponse) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{14} }
+func (*WikiFindFileResponse) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{14} }
func (m *WikiFindFileResponse) GetName() []byte {
if m != nil {
@@ -539,7 +539,7 @@ type WikiGetAllPagesRequest struct {
func (m *WikiGetAllPagesRequest) Reset() { *m = WikiGetAllPagesRequest{} }
func (m *WikiGetAllPagesRequest) String() string { return proto.CompactTextString(m) }
func (*WikiGetAllPagesRequest) ProtoMessage() {}
-func (*WikiGetAllPagesRequest) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{15} }
+func (*WikiGetAllPagesRequest) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{15} }
func (m *WikiGetAllPagesRequest) GetRepository() *Repository {
if m != nil {
@@ -558,7 +558,7 @@ type WikiGetAllPagesResponse struct {
func (m *WikiGetAllPagesResponse) Reset() { *m = WikiGetAllPagesResponse{} }
func (m *WikiGetAllPagesResponse) String() string { return proto.CompactTextString(m) }
func (*WikiGetAllPagesResponse) ProtoMessage() {}
-func (*WikiGetAllPagesResponse) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{16} }
+func (*WikiGetAllPagesResponse) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{16} }
func (m *WikiGetAllPagesResponse) GetPage() *WikiPage {
if m != nil {
@@ -584,7 +584,7 @@ type WikiGetFormattedDataRequest struct {
func (m *WikiGetFormattedDataRequest) Reset() { *m = WikiGetFormattedDataRequest{} }
func (m *WikiGetFormattedDataRequest) String() string { return proto.CompactTextString(m) }
func (*WikiGetFormattedDataRequest) ProtoMessage() {}
-func (*WikiGetFormattedDataRequest) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{17} }
+func (*WikiGetFormattedDataRequest) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{17} }
func (m *WikiGetFormattedDataRequest) GetRepository() *Repository {
if m != nil {
@@ -621,7 +621,7 @@ type WikiGetFormattedDataResponse struct {
func (m *WikiGetFormattedDataResponse) Reset() { *m = WikiGetFormattedDataResponse{} }
func (m *WikiGetFormattedDataResponse) String() string { return proto.CompactTextString(m) }
func (*WikiGetFormattedDataResponse) ProtoMessage() {}
-func (*WikiGetFormattedDataResponse) Descriptor() ([]byte, []int) { return fileDescriptor15, []int{18} }
+func (*WikiGetFormattedDataResponse) Descriptor() ([]byte, []int) { return fileDescriptor16, []int{18} }
func (m *WikiGetFormattedDataResponse) GetData() []byte {
if m != nil {
@@ -1161,9 +1161,9 @@ var _WikiService_serviceDesc = grpc.ServiceDesc{
Metadata: "wiki.proto",
}
-func init() { proto.RegisterFile("wiki.proto", fileDescriptor15) }
+func init() { proto.RegisterFile("wiki.proto", fileDescriptor16) }
-var fileDescriptor15 = []byte{
+var fileDescriptor16 = []byte{
// 928 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0xdd, 0x6e, 0xdc, 0x44,
0x14, 0xae, 0xb3, 0x7f, 0xde, 0x93, 0x34, 0xa5, 0x43, 0x69, 0x5c, 0x27, 0x84, 0x68, 0xa8, 0x44,
diff --git a/vendor/vendor.json b/vendor/vendor.json
index f35e07303..6ee7cacdb 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -297,12 +297,12 @@
"revisionTime": "2015-12-15T15:34:51Z"
},
{
- "checksumSHA1": "2MLcT+TD1llBP8wYuTzN5yUUlys=",
+ "checksumSHA1": "yweNy6QdSvamPWCaHDB4JUu6Plo=",
"path": "gitlab.com/gitlab-org/gitaly-proto/go",
- "revision": "7e89ea626eab9efab35f0346d41bb7585e8a11c5",
- "revisionTime": "2018-05-02T12:27:22Z",
- "version": "v0.99.0",
- "versionExact": "v0.99.0"
+ "revision": "d2a0710dea59eb1617fbea21bec27a987b18c498",
+ "revisionTime": "2018-05-22T09:12:59Z",
+ "version": "v0.100.0",
+ "versionExact": "v0.100.0"
},
{
"checksumSHA1": "TT1rac6kpQp2vz24m5yDGUNQ/QQ=",