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