summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Cuneo2022-06-04 16:05:33 +1000
committerMatt Cuneo2022-06-04 16:05:33 +1000
commit0ae591ed2c63b05d97b484801230a1c763dbb140 (patch)
tree1802016159e8060ed66818faf4803213507e4326
downloadaur-0ae591ed2c63b05d97b484801230a1c763dbb140.tar.gz
adjusted patch files and PKGBUILD from community package to pull from 15-0-stable git branch
-rw-r--r--.SRCINFO29
-rw-r--r--PKGBUILD62
-rw-r--r--configs.patch82
-rw-r--r--gitlab-gitaly.service14
-rw-r--r--ruby27.patch270
5 files changed, 457 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..c4086d0ad917
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,29 @@
+pkgbase = gitlab-gitaly-git
+ pkgdesc = Speed up Git access using caching
+ pkgver = 15.0.1
+ pkgrel = 1
+ url = https://gitlab.com/gitlab-org/gitaly
+ arch = x86_64
+ license = MIT
+ makedepends = go
+ makedepends = cmake
+ makedepends = git
+ depends = glibc
+ depends = ruby2.7
+ depends = libxml2
+ depends = libxslt
+ depends = libssh2
+ provides = gitlab-gitaly
+ conflicts = gitlab-gitaly
+ options = !buildflags
+ backup = etc/gitlab-gitaly/config.toml
+ source = git+https://gitlab.com/gitlab-org/gitaly#branch=15-0-stable
+ source = configs.patch
+ source = gitlab-gitaly.service
+ source = ruby27.patch
+ sha512sums = SKIP
+ sha512sums = ee8e6c43f9da4107b49886ef3bbeacaaf8a85fbdc82c464625bbccd75f53253834ce81ac9462643f4097f7d5d049160763fcd9d8450af93580167b00f7e5c150
+ sha512sums = 7f5cd528c873a5e43e18aa6a88bd7298422c047e0e61cf3208be7d9fcfdfdc8a844b5c439ab6afc2098c5c4c60ed9c3d167c2f87517f1e93b34f39be3d3dad09
+ sha512sums = 1b07ee10f47f152ebf2fa2ce684c4694ebe4475bc67fe2b61bcf7f34b9b87bdb0fe99aa07d21a60aeaa62d21a193ad24b2ea4bd2a4ef78852da538777b902521
+
+pkgname = gitlab-gitaly-git
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..294b046a8764
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,62 @@
+# Maintainer: Matt Cuneo <m@cuneo.au>
+
+_pkgname=gitlab-gitaly
+pkgname="${_pkgname}-git"
+pkgver=15.0.1
+pkgrel=1
+pkgdesc="Speed up Git access using caching"
+arch=('x86_64')
+conflicts=("$_pkgname")
+provides=("$_pkgname")
+url="https://gitlab.com/gitlab-org/gitaly"
+license=('MIT')
+depends=(glibc ruby2.7 libxml2 libxslt libssh2)
+options=(!buildflags)
+makedepends=(go cmake git)
+backup=("etc/gitlab-gitaly/config.toml")
+_tag=v${pkgver}
+source=("git+https://gitlab.com/gitlab-org/gitaly#branch=15-0-stable"
+ "configs.patch"
+ "gitlab-gitaly.service"
+ "ruby27.patch")
+sha512sums=('SKIP'
+ 'ee8e6c43f9da4107b49886ef3bbeacaaf8a85fbdc82c464625bbccd75f53253834ce81ac9462643f4097f7d5d049160763fcd9d8450af93580167b00f7e5c150'
+ '7f5cd528c873a5e43e18aa6a88bd7298422c047e0e61cf3208be7d9fcfdfdc8a844b5c439ab6afc2098c5c4c60ed9c3d167c2f87517f1e93b34f39be3d3dad09'
+ '1b07ee10f47f152ebf2fa2ce684c4694ebe4475bc67fe2b61bcf7f34b9b87bdb0fe99aa07d21a60aeaa62d21a193ad24b2ea4bd2a4ef78852da538777b902521')
+
+pkgver() {
+ cd gitaly
+ cat VERSION | xargs
+}
+
+prepare() {
+ cd gitaly
+
+ patch -p1 < ../ruby27.patch
+
+ patch -p1 < ../configs.patch
+ # At this point the config file should not contain any references to '/home/git'
+
+ # https://github.com/bundler/bundler/issues/6882
+ sed -e '/BUNDLED WITH/,+1d' -i ruby/Gemfile.lock
+}
+
+build() {
+ cd gitaly
+
+ bundle-2.7 config force_ruby_platform true # build from sources as some prebuilt gems are not available for newer ruby
+ make BUILD_TAGS="tracer_static tracer_static_jaeger"
+}
+
+package() {
+ cd gitaly
+
+ make PREFIX=/usr DESTDIR="${pkgdir}" install
+ mkdir -p "${pkgdir}"/etc/gitlab-gitaly
+ mkdir -p "${pkgdir}"/usr/share/webapps/gitlab-gitaly
+ cp -r ruby "${pkgdir}"/usr/share/webapps/gitlab-gitaly/ruby
+
+ install -Dm644 config.toml.example "${pkgdir}"/etc/${_pkgname}/config.toml
+ install -Dm644 "LICENSE" "${pkgdir}"/usr/share/licenses/${_pkgname}/LICENSE
+ install -Dm644 "${srcdir}"/gitlab-gitaly.service "${pkgdir}"/usr/lib/systemd/system/gitlab-gitaly.service
+}
diff --git a/configs.patch b/configs.patch
new file mode 100644
index 000000000000..9b902e5b76c1
--- /dev/null
+++ b/configs.patch
@@ -0,0 +1,82 @@
+diff '--color=auto' -Naur a/config.toml.example b/config.toml.example
+--- a/config.toml.example 2022-06-04 09:04:55.882280459 +1000
++++ b/config.toml.example 2022-06-04 09:08:35.230703194 +1000
+@@ -2,10 +2,10 @@
+ # Documentation lives at https://docs.gitlab.com/ee/administration/gitaly/ and
+ # https://docs.gitlab.com/ee//administration/gitaly/reference
+
+-socket_path = "/home/git/gitlab/tmp/sockets/private/gitaly.socket"
++socket_path = "/run/gitlab/gitlab-gitaly.socket"
+
+ # The directory where Gitaly's executables are stored
+-bin_dir = "/home/git/gitaly/_build/bin"
++bin_dir = "/usr/bin"
+
+ # # Optional: The directory where Gitaly can create all files required to
+ # # properly operate at runtime. If not set, Gitaly will create a directory in
+@@ -22,7 +22,7 @@
+ # # Optional: configure where the Gitaly creates the sockets for internal connections. If unset, Gitaly will create a randomly
+ # # named temp directory each time it boots.
+ # # Non Gitaly clients should never connect to these sockets.
+-# internal_socket_dir = "/home/git/gitlab/tmp/sockets/private/internal"
++# internal_socket_dir = "run/gitlab/private"
+
+ # # Optional: authenticate Gitaly requests using a shared secret
+ # [auth]
+@@ -30,8 +30,8 @@
+ # transitioning = false # Set `transitioning` to true to temporarily allow unauthenticated while rolling out authentication.
+
+ # [tls]
+-# certificate_path = '/home/git/cert.cert'
+-# key_path = '/home/git/key.pem'
++# certificate_path = '/var/lib/gitlab/cert.cert'
++# key_path = '/var/lib/gitlab/key.pem'
+
+ # # Git settings
+ # [git]
+@@ -43,7 +43,7 @@
+
+ [[storage]]
+ name = "default"
+-path = "/home/git/repositories"
++path = "/var/lib/gitlab/repositories"
+
+ # # You can optionally configure more storages for this Gitaly instance to serve up
+ #
+@@ -55,7 +55,7 @@
+ # # You can optionally configure Gitaly to output JSON-formatted log messages to stdout
+ # [logging]
+ # # The directory where Gitaly stores extra log files
+-dir = "/home/git/gitlab/log"
++dir = "/var/log/gitlab"
+ # format = "json"
+ # # Optional: Set log level to only log entries with that severity or above
+ # # One of, in order: debug, info, warn, errror, fatal, panic
+@@ -73,7 +73,7 @@
+
+ [gitaly-ruby]
+ # The directory where gitaly-ruby is installed
+-dir = "/home/git/gitaly/ruby"
++dir = "/usr/share/webapps/gitlab-gitaly/ruby"
+
+ # # Gitaly-ruby resident set size (RSS) that triggers a memory restart (bytes)
+ # max_rss = 200000000
+@@ -93,14 +93,14 @@
+
+ [gitlab-shell]
+ # The directory where gitlab-shell is installed
+-dir = "/home/git/gitlab-shell"
++dir = "/usr/share/webapps/gitlab-shell"
+
+ [hooks]
+-custom_hooks_dir = "/home/git/custom_hooks"
++custom_hooks_dir = "/var/lib/gitlab/custom_hooks"
+
+ [gitlab]
+-secret_file = "/home/git/gitlab-shell/.gitlab_shell_secret"
+-url = "http+unix://%2Fhome%2Fgit%2Fgitlab%2Ftmp%2Fsockets%2Fgitlab-workhorse.socket"
++secret_file = "/etc/webapps/gitlab-shell/secret"
++url = "http+unix://%2Frun%2Fgitlab%2Fgitlab.socket"
+ # Only needed if a UNIX socket is used in `url` and GitLab is configured to
+ # use a relative path (e.g. /gitlab).
+ # relative_url_root = '/'
diff --git a/gitlab-gitaly.service b/gitlab-gitaly.service
new file mode 100644
index 000000000000..8dd6cad5498f
--- /dev/null
+++ b/gitlab-gitaly.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Gitaly is a Git RPC service for handling all the git calls made by GitLab.
+
+[Service]
+Type=simple
+User=gitlab
+Group=gitlab
+WorkingDirectory=/usr/share/webapps/gitlab
+SyslogIdentifier=gitlab-gitaly
+PIDFile=/run/gitlab/gitaly.pid
+ExecStart=/usr/bin/gitaly /etc/gitlab-gitaly/config.toml
+
+[Install]
+WantedBy=multi-user.target
diff --git a/ruby27.patch b/ruby27.patch
new file mode 100644
index 000000000000..bcc5859d7ff8
--- /dev/null
+++ b/ruby27.patch
@@ -0,0 +1,270 @@
+diff '--color=auto' -Naur a/cmd/gitaly-backup/restore_test.go b/cmd/gitaly-backup/restore_test.go
+--- a/cmd/gitaly-backup/restore_test.go 2022-06-04 09:15:30.119502802 +1000
++++ b/cmd/gitaly-backup/restore_test.go 2022-06-04 09:16:46.423649855 +1000
+@@ -34,7 +34,7 @@
+
+ path := testhelper.TempDir(t)
+ existingRepoBundlePath := filepath.Join(path, existingRepo.RelativePath+".bundle")
+- gittest.Exec(t, cfg, "-C", existRepoPath, "bundle", "create", existingRepoBundlePath, "--all")
++ gittest.Exec(t, cfg, "-C", existRepoPath, "bundle-2.7", "create", existingRepoBundlePath, "--all")
+
+ repos := []*gitalypb.Repository{existingRepo}
+ for i := 0; i < 2; i++ {
+@@ -77,7 +77,7 @@
+ repoPath := filepath.Join(cfg.Storages[0].Path, gittest.GetReplicaPath(ctx, t, cfg, repo))
+ bundlePath := filepath.Join(path, repo.RelativePath+".bundle")
+
+- output := gittest.Exec(t, cfg, "-C", repoPath, "bundle", "verify", bundlePath)
++ output := gittest.Exec(t, cfg, "-C", repoPath, "bundle-2.7", "verify", bundlePath)
+ require.Contains(t, string(output), "The bundle records a complete history")
+ }
+ }
+diff '--color=auto' -Naur a/.gitlab-ci.yml b/.gitlab-ci.yml
+--- a/.gitlab-ci.yml 2022-06-04 09:15:30.111502783 +1000
++++ b/.gitlab-ci.yml 2022-06-04 09:16:46.423649855 +1000
+@@ -240,7 +240,7 @@
+ <<: *test_definition
+ script:
+ - make -j$(nproc)
+- - ruby -rerb -e 'ERB.new(ARGF.read).run' _support/config.praefect.toml.ci-sql-test.erb > config.praefect.toml
++ - ruby-2.7 -rerb -e 'ERB.new(ARGF.read).run' _support/config.praefect.toml.ci-sql-test.erb > config.praefect.toml
+ - ./_build/bin/praefect -config config.praefect.toml sql-ping
+ - ./_build/bin/praefect -config config.praefect.toml sql-migrate
+
+diff '--color=auto' -Naur a/internal/backup/backup_test.go b/internal/backup/backup_test.go
+--- a/internal/backup/backup_test.go 2022-06-04 09:15:30.119502802 +1000
++++ b/internal/backup/backup_test.go 2022-06-04 09:16:46.423649855 +1000
+@@ -125,7 +125,7 @@
+ require.NoError(t, err)
+ require.Equal(t, os.FileMode(0o600), bundleInfo.Mode().Perm(), "expecting restricted file permissions")
+
+- output := gittest.Exec(t, cfg, "-C", repoPath, "bundle", "verify", bundlePath)
++ output := gittest.Exec(t, cfg, "-C", repoPath, "bundle-2.7", "verify", bundlePath)
+ require.Contains(t, string(output), "The bundle records a complete history")
+
+ expectedRefs := gittest.Exec(t, cfg, "-C", repoPath, "show-ref", "--head")
+@@ -185,7 +185,7 @@
+ refsPath := filepath.Join(backupPath, "001.refs")
+
+ require.NoError(t, os.MkdirAll(backupPath, os.ModePerm))
+- gittest.Exec(t, cfg, "-C", repoPath, "bundle", "create", bundlePath, "--all")
++ gittest.Exec(t, cfg, "-C", repoPath, "bundle-2.7", "create", bundlePath, "--all")
+
+ refs := gittest.Exec(t, cfg, "-C", repoPath, "show-ref", "--head")
+ require.NoError(t, os.WriteFile(refsPath, refs, os.ModePerm))
+@@ -211,7 +211,7 @@
+ refsPath := filepath.Join(backupPath, "001.refs")
+
+ require.NoError(t, os.MkdirAll(backupPath, os.ModePerm))
+- gittest.Exec(t, cfg, "-C", repoPath, "bundle", "create", bundlePath, "--all")
++ gittest.Exec(t, cfg, "-C", repoPath, "bundle-2.7", "create", bundlePath, "--all")
+
+ refs := gittest.Exec(t, cfg, "-C", repoPath, "show-ref", "--head")
+ require.NoError(t, os.WriteFile(refsPath, refs, os.ModePerm))
+@@ -434,7 +434,7 @@
+ )
+ gittest.Exec(t, cfg, "-C", expectedRepoPath, "symbolic-ref", "HEAD", "refs/heads/master")
+ bundlePath1 := filepath.Join(backupPath, "001.bundle")
+- gittest.Exec(t, cfg, "-C", expectedRepoPath, "bundle", "create", bundlePath1,
++ gittest.Exec(t, cfg, "-C", expectedRepoPath, "bundle-2.7", "create", bundlePath1,
+ "HEAD",
+ "refs/heads/master",
+ "refs/heads/other",
+@@ -445,7 +445,7 @@
+ gittest.WithParents(master1),
+ )
+ bundlePath2 := filepath.Join(backupPath, "002.bundle")
+- gittest.Exec(t, cfg, "-C", expectedRepoPath, "bundle", "create", bundlePath2,
++ gittest.Exec(t, cfg, "-C", expectedRepoPath, "bundle-2.7", "create", bundlePath2,
+ "HEAD",
+ "^"+master1.String(),
+ "^"+other.String(),
+diff '--color=auto' -Naur a/internal/git/gittest/repo.go b/internal/git/gittest/repo.go
+--- a/internal/git/gittest/repo.go 2022-06-04 09:15:30.123502809 +1000
++++ b/internal/git/gittest/repo.go 2022-06-04 09:16:46.423649855 +1000
+@@ -338,7 +338,7 @@
+ if len(patterns) == 0 {
+ patterns = []string{"--all"}
+ }
+- Exec(t, cfg, append([]string{"-C", repoPath, "bundle", "create", bundlePath}, patterns...)...)
++ Exec(t, cfg, append([]string{"-C", repoPath, "bundle-2.7", "create", bundlePath}, patterns...)...)
+ }
+
+ // ChecksumRepo calculates the checksum of a repository.
+diff '--color=auto' -Naur a/internal/gitaly/linguist/linguist.go b/internal/gitaly/linguist/linguist.go
+--- a/internal/gitaly/linguist/linguist.go 2022-06-04 09:15:30.131502824 +1000
++++ b/internal/gitaly/linguist/linguist.go 2022-06-04 13:51:09.940415664 +1000
+@@ -88,7 +88,7 @@
+ }
+
+ func (inst *Instance) startGitLinguist(ctx context.Context, repoPath string, commitID string, linguistCommand string) (*command.Command, error) {
+- bundle, err := exec.LookPath("bundle")
++ bundle, err := exec.LookPath("bundle-2.7")
+ if err != nil {
+ return nil, fmt.Errorf("finding bundle executable: %w", err)
+ }
+@@ -155,7 +155,7 @@
+ // We use a symlink because we cannot trust Bundler to not print garbage
+ // on its stdout.
+ rubyScript := `FileUtils.ln_sf(Bundler.rubygems.find_name('github-linguist').first.full_gem_path, ARGV.first)`
+- cmd := exec.Command("bundle", "exec", "ruby", "-rfileutils", "-e", rubyScript, linguistPathSymlink.Name())
++ cmd := exec.Command("bundle-2.7", "exec", "ruby-2.7", "-rfileutils", "-e", rubyScript, linguistPathSymlink.Name())
+ cmd.Dir = cfg.Ruby.Dir
+
+ // We have learned that in practice the command we are about to run is a
+diff '--color=auto' -Naur a/internal/gitaly/rubyserver/rubyserver.go b/internal/gitaly/rubyserver/rubyserver.go
+--- a/internal/gitaly/rubyserver/rubyserver.go 2022-06-04 09:15:30.131502824 +1000
++++ b/internal/gitaly/rubyserver/rubyserver.go 2022-06-04 09:16:46.427649862 +1000
+@@ -200,7 +200,7 @@
+ // Use 'ruby-cd' to make sure gitaly-ruby has the same working directory
+ // as the current process. This is a hack to sort-of support relative
+ // Unix socket paths.
+- args := []string{"bundle", "exec", "bin/ruby-cd", wd, gitalyRuby, strconv.Itoa(os.Getpid()), socketPath}
++ args := []string{"bundle-2.7", "exec", "bin/ruby-cd", wd, gitalyRuby, strconv.Itoa(os.Getpid()), socketPath}
+
+ events := make(chan supervisor.Event)
+ check := func() error { return ping(socketPath) }
+diff '--color=auto' -Naur a/internal/gitaly/service/repository/create_bundle_from_ref_list_test.go b/internal/gitaly/service/repository/create_bundle_from_ref_list_test.go
+--- a/internal/gitaly/service/repository/create_bundle_from_ref_list_test.go 2022-06-04 09:15:30.147502854 +1000
++++ b/internal/gitaly/service/repository/create_bundle_from_ref_list_test.go 2022-06-04 09:16:46.427649862 +1000
+@@ -62,7 +62,7 @@
+
+ require.NoError(t, bundle.Close())
+
+- output := gittest.Exec(t, cfg, "-C", repoPath, "bundle", "verify", bundle.Name())
++ output := gittest.Exec(t, cfg, "-C", repoPath, "bundle-2.7", "verify", bundle.Name())
+
+ require.Contains(t, string(output), fmt.Sprintf("The bundle contains this ref:\n%s refs/heads/master", masterOID))
+ }
+@@ -100,7 +100,7 @@
+
+ require.NoError(t, bundle.Close())
+
+- output := gittest.Exec(t, cfg, "-C", repoPath, "bundle", "verify", bundle.Name())
++ output := gittest.Exec(t, cfg, "-C", repoPath, "bundle-2.7", "verify", bundle.Name())
+
+ require.Contains(t, string(output), fmt.Sprintf("The bundle contains this ref:\n%s refs/heads/master", masterOID))
+ }
+diff '--color=auto' -Naur a/internal/gitaly/service/repository/create_bundle_test.go b/internal/gitaly/service/repository/create_bundle_test.go
+--- a/internal/gitaly/service/repository/create_bundle_test.go 2022-06-04 09:15:30.147502854 +1000
++++ b/internal/gitaly/service/repository/create_bundle_test.go 2022-06-04 09:16:46.427649862 +1000
+@@ -55,7 +55,7 @@
+ _, err = io.Copy(dstFile, reader)
+ require.NoError(t, err)
+
+- output := gittest.Exec(t, cfg, "-C", repoPath, "bundle", "verify", dstFile.Name())
++ output := gittest.Exec(t, cfg, "-C", repoPath, "bundle-2.7", "verify", dstFile.Name())
+ // Extra sanity; running verify should fail on bad bundles
+ require.Contains(t, string(output), "The bundle records a complete history")
+ }
+diff '--color=auto' -Naur a/internal/gitaly/service/repository/create_repository_from_bundle_test.go b/internal/gitaly/service/repository/create_repository_from_bundle_test.go
+--- a/internal/gitaly/service/repository/create_repository_from_bundle_test.go 2022-06-04 09:15:30.147502854 +1000
++++ b/internal/gitaly/service/repository/create_repository_from_bundle_test.go 2022-06-04 09:16:46.427649862 +1000
+@@ -44,7 +44,7 @@
+ const wantDefaultBranch = "refs/heads/markdown"
+ gittest.Exec(t, cfg, "-C", repoPath, "symbolic-ref", "HEAD", wantDefaultBranch)
+
+- gittest.Exec(t, cfg, "-C", repoPath, "bundle", "create", bundlePath, "--all")
++ gittest.Exec(t, cfg, "-C", repoPath, "bundle-2.7", "create", bundlePath, "--all")
+ defer func() { require.NoError(t, os.RemoveAll(bundlePath)) }()
+
+ stream, err := client.CreateRepositoryFromBundle(ctx)
+@@ -131,7 +131,7 @@
+ },
+ }))
+
+- bundle := gittest.Exec(t, cfg, "-C", repoPath, "bundle", "create", "-",
++ bundle := gittest.Exec(t, cfg, "-C", repoPath, "bundle-2.7", "create", "-",
+ "refs/heads/master", "refs/heads/feature", "refs/keep-around/1", "refs/keep-around/2")
+ require.Greater(t, len(bundle), 100*1024)
+
+diff '--color=auto' -Naur a/internal/gitaly/service/repository/fetch_bundle_test.go b/internal/gitaly/service/repository/fetch_bundle_test.go
+--- a/internal/gitaly/service/repository/fetch_bundle_test.go 2022-06-04 09:15:30.147502854 +1000
++++ b/internal/gitaly/service/repository/fetch_bundle_test.go 2022-06-04 09:16:46.427649862 +1000
+@@ -34,7 +34,7 @@
+ bundlePath := filepath.Join(tmp, "test.bundle")
+
+ gittest.Exec(t, cfg, "-C", repoPath, "symbolic-ref", "HEAD", "refs/heads/feature")
+- gittest.Exec(t, cfg, "-C", repoPath, "bundle", "create", bundlePath, "--all")
++ gittest.Exec(t, cfg, "-C", repoPath, "bundle-2.7", "create", bundlePath, "--all")
+ expectedRefs := gittest.Exec(t, cfg, "-C", repoPath, "show-ref", "--head")
+
+ targetRepo, targetRepoPath := gittest.CreateRepository(ctx, t, cfg)
+diff '--color=auto' -Naur a/Makefile b/Makefile
+--- a/Makefile 2022-06-04 09:15:30.119502802 +1000
++++ b/Makefile 2022-06-04 09:16:46.427649862 +1000
+@@ -370,7 +370,7 @@
+ .PHONY: rspec
+ ## Run Ruby tests.
+ rspec: prepare-tests
+- ${Q}cd ${GITALY_RUBY_DIR} && PATH='${SOURCE_DIR}/internal/testhelper/testdata/home/bin:${PATH}' bundle exec rspec
++ ${Q}cd ${GITALY_RUBY_DIR} && PATH='${SOURCE_DIR}/internal/testhelper/testdata/home/bin:${PATH}' bundle-2.7 exec rspec
+
+ # This is a workaround for our unprivileged CI builds. We manually execute the
+ # build target as privileged user, but then run the rspec target unprivileged.
+@@ -421,7 +421,7 @@
+ .PHONY: rubocop
+ ## Run Rubocop.
+ rubocop: ${SOURCE_DIR}/.ruby-bundle
+- ${Q}cd ${GITALY_RUBY_DIR} && bundle exec rubocop --parallel --config ${GITALY_RUBY_DIR}/.rubocop.yml ${GITALY_RUBY_DIR} ${SOURCE_DIR}/_support/test-boot
++ ${Q}cd ${GITALY_RUBY_DIR} && bundle-2.7 exec rubocop --parallel --config ${GITALY_RUBY_DIR}/.rubocop.yml ${GITALY_RUBY_DIR} ${SOURCE_DIR}/_support/test-boot
+
+ .PHONY: cover
+ ## Generate coverage report via Go tests.
+@@ -493,7 +493,7 @@
+ # step. Both Omnibus and CNG assume it is in the Gitaly root, not in
+ # _build. Hence the '../' in front.
+ ${SOURCE_DIR}/.ruby-bundle: ${GITALY_RUBY_DIR}/Gemfile.lock ${GITALY_RUBY_DIR}/Gemfile
+- ${Q}cd ${GITALY_RUBY_DIR} && bundle install
++ ${Q}cd ${GITALY_RUBY_DIR} && bundle-2.7 install
+ ${Q}touch $@
+
+ ${SOURCE_DIR}/NOTICE: ${BUILD_DIR}/NOTICE
+diff '--color=auto' -Naur a/ruby/bin/gitaly-ruby b/ruby/bin/gitaly-ruby
+--- a/ruby/bin/gitaly-ruby 2022-06-04 09:15:30.171502899 +1000
++++ b/ruby/bin/gitaly-ruby 2022-06-04 09:16:46.427649862 +1000
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env ruby
++#!/usr/bin/env ruby-2.7
+
+ # Gitaly always spawns this executable with LANG=en_US.UTF-8. In case the
+ # system doesn't have this local, Ruby will fall back to the C locale and as a
+diff '--color=auto' -Naur a/ruby/bin/ruby-cd b/ruby/bin/ruby-cd
+--- a/ruby/bin/ruby-cd 2022-06-04 09:15:00.563445840 +1000
++++ b/ruby/bin/ruby-cd 2022-06-04 09:16:46.427649862 +1000
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env ruby
++#!/usr/bin/env ruby-2.7
+
+ # This script lets you run `bundle exec` in one directory, and then changes into another.
+
+diff '--color=auto' -Naur a/ruby/spec/lib/gitlab/git/popen_spec.rb b/ruby/spec/lib/gitlab/git/popen_spec.rb
+--- a/ruby/spec/lib/gitlab/git/popen_spec.rb 2022-06-04 09:15:00.563445840 +1000
++++ b/ruby/spec/lib/gitlab/git/popen_spec.rb 2022-06-04 09:16:46.427649862 +1000
+@@ -40,7 +40,7 @@
+ end
+
+ context 'when stderr is included' do
+- let(:result) { klass.new.popen(['ruby', '-e', 'warn "hello world"'], path, include_stderr: true) }
++ let(:result) { klass.new.popen(['ruby-2.7', '-e', 'warn "hello world"'], path, include_stderr: true) }
+ let(:output) { result.first }
+ let(:status) { result.last }
+
+diff '--color=auto' -Naur a/_support/generate-proto-ruby b/_support/generate-proto-ruby
+--- a/_support/generate-proto-ruby 2022-06-04 09:15:00.495445708 +1000
++++ b/_support/generate-proto-ruby 2022-06-04 09:16:46.427649862 +1000
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env ruby
++#!/usr/bin/env ruby-2.7
+
+ require 'erb'
+ require 'fileutils'
+@@ -20,7 +20,7 @@
+ # locations. `protoc` requires this.
+ proto_include_abs = File.absolute_path(File.join('..', PROTO_INCLUDE))
+
+- run!(%W[bundle exec grpc_tools_ruby_protoc -I #{proto_include_abs} --ruby_out=../#{ruby_lib_gitaly} --grpc_out=../#{ruby_lib_gitaly}] + PROTO_FILES)
++ run!(%W[bundle-2.7 exec grpc_tools_ruby_protoc -I #{proto_include_abs} --ruby_out=../#{ruby_lib_gitaly} --grpc_out=../#{ruby_lib_gitaly}] + PROTO_FILES)
+ end
+
+ write_ruby_requires