1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
# gitaly-ssh
Gitaly-ssh is a helper executable that enables Git data traffic
(`git fetch`) between Gitaly servers within a single GitLab
installation. It acts as a plugin to `git fetch` using the
`GIT_SSH_COMMAND` environment variable.
We created gitaly-ssh because we needed a way to pull Git data from one
Gitaly server to another, without going through one of the "front
doors" of GitLab: gitlab-shell (Git SSH) or gitlab-workhorse (Git
HTTP). To avoid building a special RPC for this, we re-used the
SSHUploadPack RPC that Gitaly already had. By connecting directly to
the Gitaly server we avoided the need to create some kind of service
account in GitLab itself: to go through the front door we would need a
service account.
The implementation shares code with how gitlab-shell handles Git SSH traffic
from real users, but it cuts out SSH itself.
> Note for Git experts: in retrospect, we should have used
[git-remote-ext](https://git-scm.com/docs/git-remote-ext) for this,
but we didn't know that mechanism existed at the time.
## How gitlab-shell does it
A normal `git fetch` over SSH goes through these steps. Note that here
`git fetch` runs on the computer of a GitLab user.
```mermaid
sequenceDiagram
participant User as User
participant UserGit as git fetch
participant SSHClient as User's SSH Client
participant SSHD as GitLab SSHD
participant GitLabShell as gitlab-shell
participant GitalyServer as Gitaly
participant GitalyGit as git upload-pack
User ->> UserGit: Runs git fetch
UserGit ->> SSHClient: Spawns SSH client
Note over User,SSHClient: On user's local machine
SSHClient ->> SSHD: SSH session
Note over SSHClient,SSHD: Session over Internet
SSHD ->> GitLabShell: spawns gitlab-shell
GitLabShell ->> GitalyServer: gRPC SSHUploadPack
GitalyServer ->> GitalyGit: spawns git upload-pack
Note over GitalyServer,GitalyGit: On Gitaly server
Note over SSHD,GitalyGit: On GitLab server
```
## How gitaly-ssh does it
In contrast, with `gitaly-ssh`, `git fetch` is run by one Gitaly server
('gitaly 1') that wants to fetch data from another ('gitaly 2'). Note
that there is no SSH client or server in this chain.
```mermaid
sequenceDiagram
participant Gitaly1 as Gitaly 1
participant Gitaly1Git as git fetch
participant GitalySSH as gitaly-ssh
participant Gitaly2 as Gitaly 2
participant Gitaly2Git as git upload-pack
Gitaly1 ->> Gitaly1Git: Spawns git-fetch
Gitaly1Git ->> GitalySSH: Spawns gitaly-ssh
Note over Gitaly1,GitalySSH: On Gitaly server 1
GitalySSH ->> Gitaly2: grpc SSHUploadPack
Note over GitalySSH,Gitaly2: Internal network (TCP/Unix)
Gitaly2 ->> Gitaly2Git: Spawns git upload-pack
Note over Gitaly2,Gitaly2Git: On Gitaly server 2
```
|