Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit f04f859

Browse files
authored
gitserver: Remove revspec updates (#61861)
Revspec updates never worked reliably. When there was _any_ operation in flight, we would just not fetch this revspec and return "all good". This is only used by packages, an experimental feature. Gitserver should not modify the authoritative data source for what versions exist. Instead, callers should add the version to the list of desired versions, and they'll eventually be part of the package when the next fetch occurred. Anyhow, experimental, didn't work reliably, will be removed for now. Test plan: Existing test suites.
1 parent 73e84a4 commit f04f859

File tree

10 files changed

+41
-156
lines changed

10 files changed

+41
-156
lines changed

cmd/gitserver/internal/ensurerevision.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func (s *Server) EnsureRevision(ctx context.Context, repo api.RepoName, rev stri
3232
}
3333

3434
// Revision not found, update before returning.
35-
err := s.doRepoUpdate(ctx, repo, rev)
35+
_, _, err := s.RepoUpdate(ctx, repo)
3636
if err != nil {
3737
if ctx.Err() == nil {
3838
ensureRevisionCounter.WithLabelValues("update_failed").Inc()

cmd/gitserver/internal/server.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ func (s *Server) repoUpdateOrClone(ctx context.Context, repoName api.RepoName) e
371371
repoClonedCounter.Inc()
372372
logger.Info("cloned repo", log.String("repo", string(repoName)))
373373
} else {
374-
if err := s.doRepoUpdate(ctx, repoName, ""); err != nil {
374+
if err := s.doRepoUpdate(ctx, repoName); err != nil {
375375
// The repo update might have failed due to the repo being corrupt
376376
s.LogIfCorrupt(ctx, repoName, err)
377377

@@ -691,7 +691,7 @@ var (
691691

692692
var doBackgroundRepoUpdateMock func(api.RepoName) error
693693

694-
func (s *Server) doRepoUpdate(ctx context.Context, repo api.RepoName, revspec string) (err error) {
694+
func (s *Server) doRepoUpdate(ctx context.Context, repo api.RepoName) (err error) {
695695
logger := s.logger.Scoped("repoUpdate").With(log.String("repo", string(repo)))
696696

697697
if doBackgroundRepoUpdateMock != nil {
@@ -722,7 +722,7 @@ func (s *Server) doRepoUpdate(ctx context.Context, repo api.RepoName, revspec st
722722
// ensure the background update doesn't hang forever
723723
fetchCtx, cancelTimeout := context.WithTimeout(ctx, fetchTimeout)
724724
defer cancelTimeout()
725-
output, err := syncer.Fetch(fetchCtx, repo, dir, revspec)
725+
output, err := syncer.Fetch(fetchCtx, repo, dir)
726726
// best-effort update the output of the fetch
727727
if err := s.db.GitserverRepos().SetLastOutput(ctx, repo, string(output)); err != nil {
728728
s.logger.Warn("Setting last output in DB", log.Error(err))

cmd/gitserver/internal/server_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@ type mockVCSSyncer struct {
11411141
mockTypeFunc func() string
11421142
mockIsCloneable func(ctx context.Context, repoName api.RepoName) error
11431143
mockClone func(ctx context.Context, repo api.RepoName, targetDir common.GitDir, tmpPath string, progressWriter io.Writer) error
1144-
mockFetch func(ctx context.Context, repoName api.RepoName, dir common.GitDir, revspec string) ([]byte, error)
1144+
mockFetch func(ctx context.Context, repoName api.RepoName, dir common.GitDir) ([]byte, error)
11451145
}
11461146

11471147
func (m *mockVCSSyncer) Type() string {
@@ -1168,9 +1168,9 @@ func (m *mockVCSSyncer) Clone(ctx context.Context, repo api.RepoName, targetDir
11681168
return errors.New("no mock for Clone() is set")
11691169
}
11701170

1171-
func (m *mockVCSSyncer) Fetch(ctx context.Context, repoName api.RepoName, dir common.GitDir, revspec string) ([]byte, error) {
1171+
func (m *mockVCSSyncer) Fetch(ctx context.Context, repoName api.RepoName, dir common.GitDir) ([]byte, error) {
11721172
if m.mockFetch != nil {
1173-
return m.mockFetch(ctx, repoName, dir, revspec)
1173+
return m.mockFetch(ctx, repoName, dir)
11741174
}
11751175

11761176
return nil, errors.New("no mock for Fetch() is set")

cmd/gitserver/internal/vcssyncer/git.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ func (s *gitRepoSyncer) Clone(ctx context.Context, repo api.RepoName, _ common.G
162162
}
163163

164164
// Fetch tries to fetch updates of a Git repository.
165-
func (s *gitRepoSyncer) Fetch(ctx context.Context, repoName api.RepoName, dir common.GitDir, _ string) ([]byte, error) {
165+
func (s *gitRepoSyncer) Fetch(ctx context.Context, repoName api.RepoName, dir common.GitDir) ([]byte, error) {
166166
source, err := s.getRemoteURLSource(ctx, repoName)
167167
if err != nil {
168168
return nil, errors.Wrapf(err, "failed to get remote URL source for %s", repoName)

cmd/gitserver/internal/vcssyncer/instrumented_syncer.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ package vcssyncer
22

33
import (
44
"context"
5-
"github.com/prometheus/client_golang/prometheus"
6-
"github.com/prometheus/client_golang/prometheus/promauto"
7-
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
8-
"github.com/sourcegraph/sourcegraph/internal/api"
95
"io"
106
"strconv"
117
"strings"
128
"time"
9+
10+
"github.com/prometheus/client_golang/prometheus"
11+
"github.com/prometheus/client_golang/prometheus/promauto"
12+
13+
"github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common"
14+
"github.com/sourcegraph/sourcegraph/internal/api"
1315
)
1416

1517
// fetchBuckets are the buckets used for the fetch and clone duration histograms.
@@ -94,9 +96,9 @@ func (i *instrumentedSyncer) Clone(ctx context.Context, repo api.RepoName, targe
9496
return i.base.Clone(ctx, repo, targetDir, tmpPath, progressWriter)
9597
}
9698

97-
func (i *instrumentedSyncer) Fetch(ctx context.Context, repoName api.RepoName, dir common.GitDir, revspec string) (output []byte, err error) {
99+
func (i *instrumentedSyncer) Fetch(ctx context.Context, repoName api.RepoName, dir common.GitDir) (output []byte, err error) {
98100
if !i.shouldObserve() {
99-
return i.base.Fetch(ctx, repoName, dir, revspec)
101+
return i.base.Fetch(ctx, repoName, dir)
100102
}
101103

102104
start := time.Now()
@@ -107,7 +109,7 @@ func (i *instrumentedSyncer) Fetch(ctx context.Context, repoName api.RepoName, d
107109
metricFetchDuration.WithLabelValues(i.formattedTypeLabel, strconv.FormatBool(succeeded)).Observe(duration)
108110
}()
109111

110-
return i.base.Fetch(ctx, repoName, dir, revspec)
112+
return i.base.Fetch(ctx, repoName, dir)
111113
}
112114

113115
func (i *instrumentedSyncer) shouldObserve() bool {

cmd/gitserver/internal/vcssyncer/mock.go

Lines changed: 13 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/gitserver/internal/vcssyncer/packages_syncer.go

Lines changed: 2 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"path"
99
"sort"
1010
"strings"
11-
"time"
1211

1312
"github.com/sourcegraph/log"
1413

@@ -98,14 +97,14 @@ func (s *vcsPackagesSyncer) Clone(ctx context.Context, repo api.RepoName, _ comm
9897
// The Fetch method is responsible for cleaning up temporary directories.
9998
// TODO: We should have more fine-grained progress reporting here.
10099
tryWrite(s.logger, progressWriter, "Fetching package revisions\n")
101-
if _, err := s.Fetch(ctx, repo, common.GitDir(tmpPath), ""); err != nil {
100+
if _, err := s.Fetch(ctx, repo, common.GitDir(tmpPath)); err != nil {
102101
return errors.Wrapf(err, "failed to fetch repo for %s", repo)
103102
}
104103

105104
return nil
106105
}
107106

108-
func (s *vcsPackagesSyncer) Fetch(ctx context.Context, repo api.RepoName, dir common.GitDir, revspec string) ([]byte, error) {
107+
func (s *vcsPackagesSyncer) Fetch(ctx context.Context, repo api.RepoName, dir common.GitDir) ([]byte, error) {
109108
source, err := s.getRemoteURLSource(ctx, repo)
110109
if err != nil {
111110
return nil, errors.Wrap(err, "getting remote URL source")
@@ -128,76 +127,9 @@ func (s *vcsPackagesSyncer) Fetch(ctx context.Context, repo api.RepoName, dir co
128127
return nil, err
129128
}
130129

131-
if revspec != "" {
132-
return nil, s.fetchRevspec(ctx, name, dir, versions, revspec)
133-
}
134-
135130
return nil, s.fetchVersions(ctx, name, dir, versions)
136131
}
137132

138-
// fetchRevspec fetches the given revspec if it's not contained in
139-
// existingVersions. If download and upserting the new version into database
140-
// succeeds, it calls s.fetchVersions with the newly-added version and the old
141-
// ones, to possibly update the "latest" tag.
142-
func (s *vcsPackagesSyncer) fetchRevspec(ctx context.Context, name reposource.PackageName, dir common.GitDir, existingVersions []string, revspec string) error {
143-
// Optionally try to resolve the version of the user-provided revspec (formatted as `"v${VERSION}^0"`).
144-
// This logic lives inside `vcsPackagesSyncer` meaning this repo must be a package repo where all
145-
// the git tags are created by our npm/crates/pypi/maven integrations (no human commits/branches/tags).
146-
// Package repos only create git tags using the format `"v${VERSION}"`.
147-
//
148-
// Unlike other versions, we silently ignore all errors from resolving requestedVersion because it could
149-
// be any random user-provided string, with no guarantee that it's a valid version string that resolves
150-
// to an existing dependency version.
151-
//
152-
// We assume the revspec is formatted as `"v${VERSION}^0"` but it could be any random string or
153-
// a git commit SHA. It should be harmless if the string is invalid, worst case the resolution fails
154-
// and we silently ignore the error.
155-
requestedVersion := strings.TrimSuffix(strings.TrimPrefix(revspec, "v"), "^0")
156-
157-
for _, existingVersion := range existingVersions {
158-
if existingVersion == requestedVersion {
159-
return nil
160-
}
161-
}
162-
163-
dep, err := s.source.ParseVersionedPackageFromNameAndVersion(name, requestedVersion)
164-
if err != nil {
165-
// Invalid version. Silently ignore error, see comment above why.
166-
return nil
167-
}
168-
169-
// if the next check passes, we know that any filters added/updated before this timestamp did not block it
170-
instant := time.Now()
171-
172-
if allowed, err := s.svc.IsPackageRepoVersionAllowed(ctx, s.scheme, dep.PackageSyntax(), dep.PackageVersion()); !allowed || err != nil {
173-
// if err == nil && !allowed, this will return nil
174-
return errors.Wrap(err, "error checking if package repo version is allowed")
175-
}
176-
177-
err = s.gitPushDependencyTag(ctx, string(dir), dep)
178-
if err != nil {
179-
// Package could not be downloaded. Silently ignore error, see comment above why.
180-
return nil
181-
}
182-
183-
if _, _, err = s.svc.InsertPackageRepoRefs(ctx, []dependencies.MinimalPackageRepoRef{
184-
{
185-
Scheme: dep.Scheme(),
186-
Name: dep.PackageSyntax(),
187-
Versions: []dependencies.MinimalPackageRepoRefVersion{{Version: dep.PackageVersion(), LastCheckedAt: &instant}},
188-
LastCheckedAt: &instant,
189-
},
190-
}); err != nil {
191-
// We don't want to ignore when writing to the database failed, since
192-
// we've already downloaded the package successfully.
193-
return err
194-
}
195-
196-
existingVersions = append(existingVersions, requestedVersion)
197-
198-
return s.fetchVersions(ctx, name, dir, existingVersions)
199-
}
200-
201133
// fetchVersions checks whether the given versions are all valid version
202134
// specifiers, then checks whether they've already been downloaded and, if not,
203135
// downloads them.

0 commit comments

Comments
 (0)