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--changelogs/unreleased/sh-export-gl-project-git-archive.yml5
-rw-r--r--internal/command/command.go5
-rw-r--r--internal/git/command.go6
-rw-r--r--internal/git/safecmd.go10
-rw-r--r--internal/git/safecmd_test.go32
-rw-r--r--internal/gitaly/service/repository/archive.go8
-rw-r--r--internal/gitaly/service/repository/archive_test.go45
-rw-r--r--internal/testhelper/testhelper.go8
8 files changed, 111 insertions, 8 deletions
diff --git a/changelogs/unreleased/sh-export-gl-project-git-archive.yml b/changelogs/unreleased/sh-export-gl-project-git-archive.yml
new file mode 100644
index 000000000..1b0999a7a
--- /dev/null
+++ b/changelogs/unreleased/sh-export-gl-project-git-archive.yml
@@ -0,0 +1,5 @@
+---
+title: Export GL_REPOSITORY and GL_PROJECT_PATH in git archive call
+merge_request: 2557
+author:
+type: changed
diff --git a/internal/command/command.go b/internal/command/command.go
index 40f8844a9..5ea8ab752 100644
--- a/internal/command/command.go
+++ b/internal/command/command.go
@@ -458,3 +458,8 @@ func checkNullArgv(cmd *exec.Cmd) error {
func (c *Command) Args() []string {
return c.cmd.Args
}
+
+// Env is an accessor for the environment variables
+func (c *Command) Env() []string {
+ return c.cmd.Env
+}
diff --git a/internal/git/command.go b/internal/git/command.go
index 866269424..6fb682913 100644
--- a/internal/git/command.go
+++ b/internal/git/command.go
@@ -9,13 +9,15 @@ import (
"gitlab.com/gitlab-org/gitaly/internal/git/repository"
)
-// unsafeCmd creates a git.unsafeCmd with the given args and Repository
-func unsafeCmd(ctx context.Context, repo repository.GitRepo, args ...string) (*command.Command, error) {
+// unsafeCmdWithEnv creates a git.unsafeCmd with the given args, environment, and Repository
+func unsafeCmdWithEnv(ctx context.Context, extraEnv []string, repo repository.GitRepo, args ...string) (*command.Command, error) {
args, env, err := argsAndEnv(repo, args...)
if err != nil {
return nil, err
}
+ env = append(env, extraEnv...)
+
return unsafeBareCmd(ctx, CmdStream{}, env, args...)
}
diff --git a/internal/git/safecmd.go b/internal/git/safecmd.go
index a0a240123..c45aa3a8f 100644
--- a/internal/git/safecmd.go
+++ b/internal/git/safecmd.go
@@ -213,15 +213,21 @@ func ConvertGlobalOptions(options *gitalypb.GlobalOptions) []Option {
return globals
}
-// SafeCmd creates a git.Command with the given args and Repository. It
+// SafeCmd creates a command.Command with the given args and Repository. It
// validates the arguments in the command before executing.
func SafeCmd(ctx context.Context, repo repository.GitRepo, globals []Option, sc Cmd) (*command.Command, error) {
+ return SafeCmdWithEnv(ctx, nil, repo, globals, sc)
+}
+
+// SafeCmdWithEnv creates a command.Command with the given args, environment, and Repository. It
+// validates the arguments in the command before executing.
+func SafeCmdWithEnv(ctx context.Context, env []string, repo repository.GitRepo, globals []Option, sc Cmd) (*command.Command, error) {
args, err := combineArgs(globals, sc)
if err != nil {
return nil, err
}
- return unsafeCmd(ctx, repo, args...)
+ return unsafeCmdWithEnv(ctx, env, repo, args...)
}
// SafeBareCmd creates a git.Command with the given args, stream, and env. It
diff --git a/internal/git/safecmd_test.go b/internal/git/safecmd_test.go
index 0829d9a58..6ab199390 100644
--- a/internal/git/safecmd_test.go
+++ b/internal/git/safecmd_test.go
@@ -200,6 +200,11 @@ func TestSafeCmdValid(t *testing.T) {
// ignore first 3 indeterministic args (executable path and repo args)
require.Equal(t, tt.expectArgs, cmd.Args()[3:])
+ cmd, err = git.SafeCmdWithEnv(ctx, nil, testRepo, tt.globals, tt.subCmd)
+ require.NoError(t, err)
+ // ignore first 3 indeterministic args (executable path and repo args)
+ require.Equal(t, tt.expectArgs, cmd.Args()[3:])
+
cmd, err = git.SafeStdinCmd(ctx, testRepo, tt.globals, tt.subCmd)
require.NoError(t, err)
require.Equal(t, tt.expectArgs, cmd.Args()[3:])
@@ -215,6 +220,33 @@ func TestSafeCmdValid(t *testing.T) {
}
}
+func TestSafeCmdWithEnv(t *testing.T) {
+ testRepo, _, cleanup := testhelper.NewTestRepo(t)
+ defer cleanup()
+
+ ctx, cancel := testhelper.Context()
+ defer cancel()
+
+ reenableGitCmd := disableGitCmd()
+ defer reenableGitCmd()
+
+ globals := []git.Option{
+ git.Flag{Name: "--aaaa-bbbb"},
+ }
+
+ subCmd := git.SubCmd{Name: "cccc"}
+ endOfOptions := "--end-of-options"
+ expectArgs := []string{"--aaaa-bbbb", "cccc", endOfOptions}
+
+ env := []string{"TEST_VAR1=1", "TEST_VAR2=2"}
+
+ cmd, err := git.SafeCmdWithEnv(ctx, env, testRepo, globals, subCmd)
+ require.NoError(t, err)
+ // ignore first 3 indeterministic args (executable path and repo args)
+ require.Equal(t, expectArgs, cmd.Args()[3:])
+ require.Subset(t, cmd.Env(), env)
+}
+
func disableGitCmd() testhelper.Cleanup {
oldBinPath := config.Config.Git.BinPath
config.Config.Git.BinPath = "/bin/echo"
diff --git a/internal/gitaly/service/repository/archive.go b/internal/gitaly/service/repository/archive.go
index e60950678..807f97ebd 100644
--- a/internal/gitaly/service/repository/archive.go
+++ b/internal/gitaly/service/repository/archive.go
@@ -2,6 +2,7 @@ package repository
import (
"context"
+ "fmt"
"io"
"os"
"os/exec"
@@ -150,7 +151,12 @@ func handleArchive(ctx context.Context, writer io.Writer, in *gitalypb.GetArchiv
pathspecs = append(pathspecs, ":(exclude)"+exclude)
}
- archiveCommand, err := git.SafeCmd(ctx, in.GetRepository(), nil, git.SubCmd{
+ env := []string{
+ fmt.Sprintf("GL_REPOSITORY=%s", in.GetRepository().GetGlRepository()),
+ fmt.Sprintf("GL_PROJECT_PATH=%s", in.GetRepository().GetGlProjectPath()),
+ }
+
+ archiveCommand, err := git.SafeCmdWithEnv(ctx, env, in.GetRepository(), nil, git.SubCmd{
Name: "archive",
Flags: []git.Option{git.ValueFlag{"--format", format}, git.ValueFlag{"--prefix", in.GetPrefix() + "/"}},
Args: args,
diff --git a/internal/gitaly/service/repository/archive_test.go b/internal/gitaly/service/repository/archive_test.go
index ffbc8540c..4f600d836 100644
--- a/internal/gitaly/service/repository/archive_test.go
+++ b/internal/gitaly/service/repository/archive_test.go
@@ -9,6 +9,7 @@ import (
"testing"
"github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/internal/gitaly/config"
"gitlab.com/gitlab-org/gitaly/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/proto/go/gitalypb"
"gitlab.com/gitlab-org/gitaly/streamio"
@@ -369,6 +370,50 @@ func TestGetArchivePathInjection(t *testing.T) {
require.Zero(t, authorizedKeysFileStat.Size())
}
+func TestGetArchiveEnv(t *testing.T) {
+ serverSocketPath, stop := runRepoServer(t)
+ defer stop()
+
+ client, conn := newRepositoryClient(t, serverSocketPath)
+ defer conn.Close()
+
+ testRepo, _, cleanupFn := testhelper.NewTestRepo(t)
+ defer cleanupFn()
+
+ commitID := "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863"
+
+ ctx, cancel := testhelper.Context()
+ defer cancel()
+
+ req := &gitalypb.GetArchiveRequest{
+ Repository: testRepo,
+ CommitId: commitID,
+ }
+
+ tmpFile, err := ioutil.TempFile("", "archive.sh")
+ require.NoError(t, err)
+ defer os.Remove(tmpFile.Name())
+
+ err = tmpFile.Chmod(0755)
+ require.NoError(t, err)
+
+ tmpFile.Write([]byte(`#!/bin/sh
+env | grep ^GL_`))
+ tmpFile.Close()
+
+ oldBinPath := config.Config.Git.BinPath
+ config.Config.Git.BinPath = tmpFile.Name()
+ defer func() { config.Config.Git.BinPath = oldBinPath }()
+
+ stream, err := client.GetArchive(ctx, req)
+ require.NoError(t, err)
+
+ data, err := consumeArchive(stream)
+ require.NoError(t, err)
+ require.Contains(t, string(data), "GL_REPOSITORY="+testhelper.GlRepository)
+ require.Contains(t, string(data), "GL_PROJECT_PATH="+testhelper.GlProjectPath)
+}
+
func compressedFileContents(t *testing.T, format gitalypb.GetArchiveRequest_Format, name string) []byte {
switch format {
case gitalypb.GetArchiveRequest_TAR:
diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go
index 5c8be0bcb..134367ead 100644
--- a/internal/testhelper/testhelper.go
+++ b/internal/testhelper/testhelper.go
@@ -56,6 +56,7 @@ const (
testGitEnv = "testdata/git-env"
GlRepository = "project-1"
GlID = "user-123"
+ GlProjectPath = "gitlab-org/gitlab-test"
)
var configureOnce sync.Once
@@ -500,9 +501,10 @@ func Context(opts ...ContextOpt) (context.Context, func()) {
func CreateRepo(t testing.TB, storagePath, relativePath string) *gitalypb.Repository {
require.NoError(t, os.MkdirAll(filepath.Dir(storagePath), 0755), "making repo parent dir")
return &gitalypb.Repository{
- StorageName: "default",
- RelativePath: relativePath,
- GlRepository: GlRepository,
+ StorageName: "default",
+ RelativePath: relativePath,
+ GlRepository: GlRepository,
+ GlProjectPath: GlProjectPath,
}
}