Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support system proxy #15234

Closed
wants to merge 6 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Let git support proxy when necessary
lunny committed Apr 17, 2021
commit 1679c76d9184a75b1fcc3c43635bca7622f1c5ca
2 changes: 1 addition & 1 deletion contrib/pr/checkout.go
Original file line number Diff line number Diff line change
@@ -80,7 +80,7 @@ func runPR() {
setting.RunUser = curUser.Username

log.Printf("[PR] Loading fixtures data ...\n")
setting.CheckLFSVersion()
git.CheckLFSVersion()
//models.LoadConfigs()
/*
setting.Database.Type = "sqlite3"
6 changes: 3 additions & 3 deletions integrations/git_test.go
Original file line number Diff line number Diff line change
@@ -143,7 +143,7 @@ func standardCommitAndPushTest(t *testing.T, dstPath string) (little, big string
func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS string) {
t.Run("LFS", func(t *testing.T) {
defer PrintCurrentTest(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
@@ -213,7 +213,7 @@ func rawTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS s
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
assert.Equal(t, littleSize, resp.Length)

setting.CheckLFSVersion()
git.CheckLFSVersion()
if setting.LFS.StartServer {
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS))
resp := session.MakeRequest(t, req, http.StatusOK)
@@ -255,7 +255,7 @@ func mediaTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
assert.Equal(t, littleSize, resp.Length)

setting.CheckLFSVersion()
git.CheckLFSVersion()
if setting.LFS.StartServer {
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS))
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
3 changes: 2 additions & 1 deletion integrations/integration_test.go
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@ import (

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/queue"
@@ -163,7 +164,7 @@ func initIntegrationTest() {
setting.SetCustomPathAndConf("", "", "")
setting.NewContext()
util.RemoveAll(models.LocalCopyPath())
setting.CheckLFSVersion()
git.CheckLFSVersion()
setting.InitDBConfig()
if err := storage.Init(); err != nil {
fmt.Printf("Init storage failed: %v", err)
13 changes: 7 additions & 6 deletions integrations/lfs_getobject_test.go
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ import (
"testing"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers/routes"
@@ -90,7 +91,7 @@ func checkResponseTestContentEncoding(t *testing.T, content *[]byte, resp *httpt

func TestGetLFSSmall(t *testing.T) {
defer prepareTestEnv(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
@@ -103,7 +104,7 @@ func TestGetLFSSmall(t *testing.T) {

func TestGetLFSLarge(t *testing.T) {
defer prepareTestEnv(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
@@ -119,7 +120,7 @@ func TestGetLFSLarge(t *testing.T) {

func TestGetLFSGzip(t *testing.T) {
defer prepareTestEnv(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
@@ -140,7 +141,7 @@ func TestGetLFSGzip(t *testing.T) {

func TestGetLFSZip(t *testing.T) {
defer prepareTestEnv(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
@@ -163,7 +164,7 @@ func TestGetLFSZip(t *testing.T) {

func TestGetLFSRangeNo(t *testing.T) {
defer prepareTestEnv(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
@@ -176,7 +177,7 @@ func TestGetLFSRangeNo(t *testing.T) {

func TestGetLFSRange(t *testing.T) {
defer prepareTestEnv(t)()
setting.CheckLFSVersion()
git.CheckLFSVersion()
if !setting.LFS.StartServer {
t.Skip()
return
3 changes: 2 additions & 1 deletion integrations/migration-test/migration_test.go
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ import (
"code.gitea.io/gitea/models/migrations"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/charset"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"

@@ -61,7 +62,7 @@ func initMigrationTest(t *testing.T) func() {
assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
assert.NoError(t, util.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))

setting.CheckLFSVersion()
git.CheckLFSVersion()
setting.InitDBConfig()
setting.NewLogServices(true)
return deferFn
3 changes: 2 additions & 1 deletion models/migrations/migrations_test.go
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ import (

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
@@ -55,7 +56,7 @@ func TestMain(m *testing.M) {

setting.SetCustomPathAndConf("", "", "")
setting.NewContext()
setting.CheckLFSVersion()
git.CheckLFSVersion()
setting.InitDBConfig()
setting.NewLogServices(true)

51 changes: 37 additions & 14 deletions modules/git/command.go
Original file line number Diff line number Diff line change
@@ -109,48 +109,71 @@ func (c *Command) RunInDirTimeoutEnvFullPipeline(env []string, timeout time.Dura
// RunInDirTimeoutEnvFullPipelineFunc executes the command in given directory with given timeout,
// it pipes stdout and stderr to given io.Writer and passes in an io.Reader as stdin. Between cmd.Start and cmd.Wait the passed in function is run.
func (c *Command) RunInDirTimeoutEnvFullPipelineFunc(env []string, timeout time.Duration, dir string, stdout, stderr io.Writer, stdin io.Reader, fn func(context.Context, context.CancelFunc) error) error {
if timeout == -1 {
timeout = DefaultCommandExecutionTimeout
return c.RunWithContext(&RunContext{
Env: env,
Timeout: timeout,
Dir: dir,
Stdout: stdout,
Stderr: stderr,
Stdin: stdin,
CancelFunc: fn,
})
}

// RunContext represents parameters to run the command
type RunContext struct {
Env []string
Timeout time.Duration
Dir string
Stdout, Stderr io.Writer
Stdin io.Reader
CancelFunc func(context.Context, context.CancelFunc) error
}

// RunWithContext run the command with context
func (c *Command) RunWithContext(rc *RunContext) error {
if rc.Timeout == -1 {
rc.Timeout = DefaultCommandExecutionTimeout
}

if len(dir) == 0 {
if len(rc.Dir) == 0 {
log(c.String())
} else {
log("%s: %v", dir, c)
log("%s: %v", rc.Dir, c)
}

ctx, cancel := context.WithTimeout(c.parentContext, timeout)
ctx, cancel := context.WithTimeout(c.parentContext, rc.Timeout)
defer cancel()

cmd := exec.CommandContext(ctx, c.name, c.args...)
if env == nil {
if rc.Env == nil {
cmd.Env = append(os.Environ(), fmt.Sprintf("LC_ALL=%s", DefaultLocale))
} else {
cmd.Env = env
cmd.Env = rc.Env
cmd.Env = append(cmd.Env, fmt.Sprintf("LC_ALL=%s", DefaultLocale))
}

// TODO: verify if this is still needed in golang 1.15
if goVersionLessThan115 {
cmd.Env = append(cmd.Env, "GODEBUG=asyncpreemptoff=1")
}
cmd.Dir = dir
cmd.Stdout = stdout
cmd.Stderr = stderr
cmd.Stdin = stdin
cmd.Dir = rc.Dir
cmd.Stdout = rc.Stdout
cmd.Stderr = rc.Stderr
cmd.Stdin = rc.Stdin
if err := cmd.Start(); err != nil {
return err
}

desc := c.desc
if desc == "" {
desc = fmt.Sprintf("%s %s %s [repo_path: %s]", GitExecutable, c.name, strings.Join(c.args, " "), dir)
desc = fmt.Sprintf("%s %s %s [repo_path: %s]", GitExecutable, c.name, strings.Join(c.args, " "), rc.Dir)
}
pid := process.GetManager().Add(desc, cancel)
defer process.GetManager().Remove(pid)

if fn != nil {
err := fn(ctx, cancel)
if rc.CancelFunc != nil {
err := rc.CancelFunc(ctx, cancel)
if err != nil {
cancel()
_ = cmd.Wait()
36 changes: 36 additions & 0 deletions modules/git/git.go
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ import (
"time"

"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting"

"github.com/hashicorp/go-version"
)
@@ -122,10 +123,45 @@ func SetExecutablePath(path string) error {
return nil
}

// VersionInfo returns git version information
func VersionInfo() string {
var format = "Git Version: %s"
var args = []interface{}{gitVersion.Original()}
// Since git wire protocol has been released from git v2.18
if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil {
format += ", Wire Protocol %s Enabled"
args = append(args, "Version 2") // for focus color
}

return fmt.Sprintf(format, args...)
}

// Init initializes git module
func Init(ctx context.Context) error {
DefaultContext = ctx

DefaultCommandExecutionTimeout = time.Duration(setting.Git.Timeout.Default) * time.Second

if err := SetExecutablePath(setting.Git.Path); err != nil {
return err
}

// force cleanup args
GlobalCommandArgs = []string{}

if CheckGitVersionAtLeast("2.9") == nil {
// Explicitly disable credential helper, otherwise Git credentials might leak
GlobalCommandArgs = append(GlobalCommandArgs, "-c", "credential.helper=")
}

// Since git wire protocol has been released from git v2.18
if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil {
GlobalCommandArgs = append(GlobalCommandArgs, "-c", "protocol.version=2")
}

CommitsRangeSize = setting.Git.CommitsRangeSize
BranchesRangeSize = setting.Git.BranchesRangeSize

// Save current git version on init to gitVersion otherwise it would require an RWMutex
if err := LoadGitVersion(); err != nil {
return err
37 changes: 37 additions & 0 deletions modules/git/lfs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package git

import (
"sync"

logger "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)

var once sync.Once

// CheckLFSVersion will check lfs version, if not satisfied, then disable it.
func CheckLFSVersion() {
if setting.LFS.StartServer {
//Disable LFS client hooks if installed for the current OS user
//Needs at least git v2.1.2

err := LoadGitVersion()
if err != nil {
logger.Fatal("Error retrieving git version: %v", err)
}

if CheckGitVersionAtLeast("2.1.2") != nil {
setting.LFS.StartServer = false
logger.Error("LFS server support needs at least Git v2.1.2")
} else {
once.Do(func() {
GlobalCommandArgs = append(GlobalCommandArgs, "-c", "filter.lfs.required=",
"-c", "filter.lfs.smudge=", "-c", "filter.lfs.clean=")
})
}
}
}
21 changes: 19 additions & 2 deletions modules/git/repo.go
Original file line number Diff line number Diff line change
@@ -10,11 +10,14 @@ import (
"container/list"
"context"
"fmt"
"net/url"
"os"
"path"
"strconv"
"strings"
"time"

"code.gitea.io/gitea/modules/proxy"
)

// GPGSettings represents the default GPG settings for this repository
@@ -147,8 +150,22 @@ func CloneWithArgs(ctx context.Context, from, to string, args []string, opts Clo
opts.Timeout = -1
}

_, err = cmd.RunTimeout(opts.Timeout)
return err
var envs []string
u, err := url.Parse(from)
if err == nil && (strings.EqualFold(u.Scheme, "http") || strings.EqualFold(u.Scheme, "https")) {
if proxy.Match(u.Host) {
envs = []string{fmt.Sprintf("https_proxy=%s", proxy.GetProxy())}
}
}

var stderr = new(bytes.Buffer)
err = cmd.RunWithContext(&RunContext{
Timeout: opts.Timeout,
Env: envs,
Stdout: new(bytes.Buffer),
Stderr: stderr,
})
return ConcatenateError(err, stderr.String())
}

// PullRemoteOptions options when pull from remote
Loading