Skip to content

Commit fea4018

Browse files
authored
Load code host config from external services database (sourcegraph#1160)
1 parent 9fc5b10 commit fea4018

37 files changed

Lines changed: 586 additions & 119 deletions

‎cmd/frontend/backend/repos.go‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,11 @@ func (s *repos) Add(ctx context.Context, name api.RepoName) (err error) {
9898
// Avoid hitting the repoupdater (and incurring a hit against our GitHub/etc. API rate
9999
// limit) for repositories that don't exist or private repositories that people attempt to
100100
// access.
101-
if gitserverRepo := quickGitserverRepo(name); gitserverRepo != nil {
101+
gitserverRepo, err := quickGitserverRepo(ctx, name)
102+
if err != nil {
103+
return err
104+
}
105+
if gitserverRepo != nil {
102106
if err := gitserver.DefaultClient.IsRepoCloneable(ctx, *gitserverRepo); err != nil {
103107
return err
104108
}
@@ -200,7 +204,12 @@ func (s *repos) GetInventoryUncached(ctx context.Context, repo *types.Repo, comm
200204
ctx, done := trace(ctx, "Repos", "GetInventoryUncached", map[string]interface{}{"repo": repo.Name, "commitID": commitID}, &err)
201205
defer done()
202206

203-
files, err := git.ReadDir(ctx, CachedGitRepo(repo), commitID, "", true)
207+
cachedRepo, err := CachedGitRepo(ctx, repo)
208+
if err != nil {
209+
return nil, err
210+
}
211+
212+
files, err := git.ReadDir(ctx, *cachedRepo, commitID, "", true)
204213
if err != nil {
205214
return nil, err
206215
}

‎cmd/frontend/backend/repos_vcs.go‎

Lines changed: 78 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ package backend
22

33
import (
44
"context"
5+
"net/url"
56
"strings"
67

7-
"github.com/sourcegraph/sourcegraph/cmd/frontend/envvar"
88
log15 "gopkg.in/inconshreveable/log15.v2"
99

1010
"github.com/pkg/errors"
11-
11+
"github.com/sourcegraph/sourcegraph/cmd/frontend/db"
12+
"github.com/sourcegraph/sourcegraph/cmd/frontend/envvar"
1213
"github.com/sourcegraph/sourcegraph/cmd/frontend/types"
1314
"github.com/sourcegraph/sourcegraph/pkg/api"
14-
"github.com/sourcegraph/sourcegraph/pkg/conf"
1515
"github.com/sourcegraph/sourcegraph/pkg/gitserver"
1616
"github.com/sourcegraph/sourcegraph/pkg/repoupdater"
1717
"github.com/sourcegraph/sourcegraph/pkg/repoupdater/protocol"
@@ -22,17 +22,25 @@ import (
2222
// knowing the remote URL is necessary to perform any operations (from method calls on the return
2323
// value), those operations will fail. This occurs when the repository isn't cloned on gitserver or
2424
// when an update is needed (eg in ResolveRevision).
25-
func CachedGitRepo(repo *types.Repo) gitserver.Repo {
26-
if r := quickGitserverRepo(repo.Name); r != nil {
27-
return *r
25+
func CachedGitRepo(ctx context.Context, repo *types.Repo) (*gitserver.Repo, error) {
26+
r, err := quickGitserverRepo(ctx, repo.Name)
27+
if err != nil {
28+
return nil, err
29+
}
30+
if r != nil {
31+
return r, nil
2832
}
29-
return gitserver.Repo{Name: repo.Name}
33+
return &gitserver.Repo{Name: repo.Name}, nil
3034
}
3135

3236
// GitRepo returns a handle to the Git repository with the up-to-date (as of the time of this call)
3337
// remote URL. See CachedGitRepo for when this is necessary vs. unnecessary.
3438
func GitRepo(ctx context.Context, repo *types.Repo) (gitserver.Repo, error) {
35-
if gitserverRepo := quickGitserverRepo(repo.Name); gitserverRepo != nil {
39+
gitserverRepo, err := quickGitserverRepo(ctx, repo.Name)
40+
if err != nil {
41+
return gitserver.Repo{Name: repo.Name}, err
42+
}
43+
if gitserverRepo != nil {
3644
return *gitserverRepo, nil
3745
}
3846

@@ -49,27 +57,79 @@ func GitRepo(ctx context.Context, repo *types.Repo) (gitserver.Repo, error) {
4957
return gitserver.Repo{Name: result.Repo.Name, URL: result.Repo.VCS.URL}, nil
5058
}
5159

52-
func quickGitserverRepo(repo api.RepoName) *gitserver.Repo {
60+
func quickGitserverRepo(ctx context.Context, repo api.RepoName) (*gitserver.Repo, error) {
5361
// If it is possible to 100% correctly determine it statically, use a fast path. This is
5462
// used to avoid a RepoLookup call for public GitHub.com and GitLab.com repositories
5563
// (especially on Sourcegraph.com), which reduces rate limit pressure significantly.
5664
//
5765
// This fails for private repositories, which require authentication in the URL userinfo.
5866

67+
lowerRepo := strings.ToLower(string(repo))
68+
var hasToken func(context.Context) (bool, error)
5969
switch {
60-
case strings.HasPrefix(strings.ToLower(string(repo)), "github.com/"):
61-
if envvar.SourcegraphDotComMode() || !conf.HasGitHubDotComToken() {
62-
return &gitserver.Repo{Name: repo, URL: "https://" + string(repo) + ".git"}
63-
}
70+
case strings.HasPrefix(lowerRepo, "github.com/"):
71+
hasToken = hasGitHubDotComToken
72+
case strings.HasPrefix(lowerRepo, "gitlab.com/"):
73+
hasToken = hasGitLabDotComToken
74+
default:
75+
return nil, nil
76+
}
6477

65-
case strings.HasPrefix(strings.ToLower(string(repo)), "gitlab.com/"):
66-
if envvar.SourcegraphDotComMode() || !conf.HasGitLabDotComToken() {
67-
return &gitserver.Repo{Name: repo, URL: "https://" + string(repo) + ".git"}
68-
}
78+
r := &gitserver.Repo{Name: repo, URL: "https://" + string(repo) + ".git"}
79+
if envvar.SourcegraphDotComMode() {
80+
return r, nil
81+
}
82+
83+
ok, err := hasToken(ctx)
84+
if err != nil {
85+
return nil, err
86+
}
87+
if !ok {
88+
return r, nil
6989
}
7090

7191
// Fall back to performing full RepoLookup, which will hit the code host.
72-
return nil
92+
return nil, nil
93+
}
94+
95+
// hasGitHubDotComToken reports whether there are any personal access tokens configured for
96+
// github.com.
97+
func hasGitHubDotComToken(ctx context.Context) (bool, error) {
98+
conns, err := db.ExternalServices.ListGitHubConnections(ctx)
99+
if err != nil {
100+
return false, err
101+
}
102+
for _, c := range conns {
103+
u, err := url.Parse(c.Url)
104+
if err != nil {
105+
continue
106+
}
107+
hostname := strings.ToLower(u.Hostname())
108+
if (hostname == "github.com" || hostname == "api.github.com") && c.Token != "" {
109+
return true, nil
110+
}
111+
}
112+
return false, nil
113+
}
114+
115+
// hasGitLabDotComToken reports whether there are any personal access tokens configured for
116+
// github.com.
117+
func hasGitLabDotComToken(ctx context.Context) (bool, error) {
118+
conns, err := db.ExternalServices.ListGitLabConnections(ctx)
119+
if err != nil {
120+
return false, err
121+
}
122+
for _, c := range conns {
123+
u, err := url.Parse(c.Url)
124+
if err != nil {
125+
continue
126+
}
127+
hostname := strings.ToLower(u.Hostname())
128+
if hostname == "gitlab.com" && c.Token != "" {
129+
return true, nil
130+
}
131+
}
132+
return false, nil
73133
}
74134

75135
// ResolveRev will return the absolute commit for a commit-ish spec in a repo.

0 commit comments

Comments
 (0)