summaryrefslogtreecommitdiff
path: root/workhorse/internal/git/snapshot.go
diff options
context:
space:
mode:
Diffstat (limited to 'workhorse/internal/git/snapshot.go')
-rw-r--r--workhorse/internal/git/snapshot.go64
1 files changed, 64 insertions, 0 deletions
diff --git a/workhorse/internal/git/snapshot.go b/workhorse/internal/git/snapshot.go
new file mode 100644
index 00000000000..eb38becbd06
--- /dev/null
+++ b/workhorse/internal/git/snapshot.go
@@ -0,0 +1,64 @@
+package git
+
+import (
+ "fmt"
+ "io"
+ "net/http"
+
+ "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb"
+
+ "gitlab.com/gitlab-org/gitlab-workhorse/internal/gitaly"
+ "gitlab.com/gitlab-org/gitlab-workhorse/internal/helper"
+ "gitlab.com/gitlab-org/gitlab-workhorse/internal/senddata"
+)
+
+type snapshot struct {
+ senddata.Prefix
+}
+
+type snapshotParams struct {
+ GitalyServer gitaly.Server
+ GetSnapshotRequest string
+}
+
+var (
+ SendSnapshot = &snapshot{"git-snapshot:"}
+)
+
+func (s *snapshot) Inject(w http.ResponseWriter, r *http.Request, sendData string) {
+ var params snapshotParams
+
+ if err := s.Unpack(&params, sendData); err != nil {
+ helper.Fail500(w, r, fmt.Errorf("SendSnapshot: unpack sendData: %v", err))
+ return
+ }
+
+ request := &gitalypb.GetSnapshotRequest{}
+ if err := gitaly.UnmarshalJSON(params.GetSnapshotRequest, request); err != nil {
+ helper.Fail500(w, r, fmt.Errorf("SendSnapshot: unmarshal GetSnapshotRequest: %v", err))
+ return
+ }
+
+ ctx, c, err := gitaly.NewRepositoryClient(r.Context(), params.GitalyServer)
+ if err != nil {
+ helper.Fail500(w, r, fmt.Errorf("SendSnapshot: gitaly.NewRepositoryClient: %v", err))
+ return
+ }
+
+ reader, err := c.SnapshotReader(ctx, request)
+ if err != nil {
+ helper.Fail500(w, r, fmt.Errorf("SendSnapshot: client.SnapshotReader: %v", err))
+ return
+ }
+
+ w.Header().Del("Content-Length")
+ w.Header().Set("Content-Disposition", `attachment; filename="snapshot.tar"`)
+ w.Header().Set("Content-Type", "application/x-tar")
+ w.Header().Set("Content-Transfer-Encoding", "binary")
+ w.Header().Set("Cache-Control", "private")
+ w.WriteHeader(http.StatusOK) // Errors aren't detectable beyond this point
+
+ if _, err := io.Copy(w, reader); err != nil {
+ helper.LogError(r, fmt.Errorf("SendSnapshot: copy gitaly output: %v", err))
+ }
+}