summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Frysinger <vapier@google.com>2021-05-05 19:44:35 -0400
committerMike Frysinger <vapier@google.com>2021-05-10 21:10:29 +0000
commit19e409c81863878d5d313fdc40b3975b98602454 (patch)
tree491d08dbc32c2e5e8acb33fcecff09a5a51613f9
parent4a58100251624ddd37c3046611c110fb3077668d (diff)
downloadgit-repo-19e409c81863878d5d313fdc40b3975b98602454.tar.gz
ssh: move proxy usage to the sync subcommand
The only time we really need ssh proxies is when we want to run many connections and reuse them. That only happens when running sync. Every other command makes at most two connections, and even then it's only one or none. So the effort of setting up & tearing down ssh proxies isn't worth it most of the time. The big reason we want to move this logic to sync is that it's now using multiprocessing for parallel work. The current ssh proxy code is all based on threads, which means none of the logic is working correctly. The current ssh design makes it hard to fix when all of the state lives in the global/module scope. So the first step to fixing this is top move the setup & teardown to the one place that really needs it: sync. No other commands will use proxies anymore, just direct connections. Bug: https://crbug.com/gerrit/12389 Change-Id: Ibd351acdec39a87562b3013637c5df4ea34e03c6 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/305485 Reviewed-by: Chris Mcdonald <cjmcdonald@google.com> Tested-by: Mike Frysinger <vapier@google.com>
-rw-r--r--git_config.py8
-rwxr-xr-xmain.py25
-rw-r--r--project.py11
-rw-r--r--subcmds/sync.py10
4 files changed, 32 insertions, 22 deletions
diff --git a/git_config.py b/git_config.py
index 1d8d1363..d7fef8ca 100644
--- a/git_config.py
+++ b/git_config.py
@@ -520,6 +520,14 @@ class Remote(object):
520 return self.url.replace(longest, longestUrl, 1) 520 return self.url.replace(longest, longestUrl, 1)
521 521
522 def PreConnectFetch(self): 522 def PreConnectFetch(self):
523 """Run any setup for this remote before we connect to it.
524
525 In practice, if the remote is using SSH, we'll attempt to create a new
526 SSH master session to it for reuse across projects.
527
528 Returns:
529 Whether the preconnect phase for this remote was successful.
530 """
523 connectionUrl = self._InsteadOf() 531 connectionUrl = self._InsteadOf()
524 return ssh.preconnect(connectionUrl) 532 return ssh.preconnect(connectionUrl)
525 533
diff --git a/main.py b/main.py
index 96744335..e399ddce 100755
--- a/main.py
+++ b/main.py
@@ -56,7 +56,6 @@ from error import RepoChangedException
56import gitc_utils 56import gitc_utils
57from manifest_xml import GitcClient, RepoClient 57from manifest_xml import GitcClient, RepoClient
58from pager import RunPager, TerminatePager 58from pager import RunPager, TerminatePager
59import ssh
60from wrapper import WrapperPath, Wrapper 59from wrapper import WrapperPath, Wrapper
61 60
62from subcmds import all_commands 61from subcmds import all_commands
@@ -592,20 +591,16 @@ def _Main(argv):
592 591
593 repo = _Repo(opt.repodir) 592 repo = _Repo(opt.repodir)
594 try: 593 try:
595 try: 594 init_http()
596 ssh.init() 595 name, gopts, argv = repo._ParseArgs(argv)
597 init_http() 596 run = lambda: repo._Run(name, gopts, argv) or 0
598 name, gopts, argv = repo._ParseArgs(argv) 597 if gopts.trace_python:
599 run = lambda: repo._Run(name, gopts, argv) or 0 598 import trace
600 if gopts.trace_python: 599 tracer = trace.Trace(count=False, trace=True, timing=True,
601 import trace 600 ignoredirs=set(sys.path[1:]))
602 tracer = trace.Trace(count=False, trace=True, timing=True, 601 result = tracer.runfunc(run)
603 ignoredirs=set(sys.path[1:])) 602 else:
604 result = tracer.runfunc(run) 603 result = run()
605 else:
606 result = run()
607 finally:
608 ssh.close()
609 except KeyboardInterrupt: 604 except KeyboardInterrupt:
610 print('aborted by user', file=sys.stderr) 605 print('aborted by user', file=sys.stderr)
611 result = 1 606 result = 1
diff --git a/project.py b/project.py
index 7b5b56d4..37558061 100644
--- a/project.py
+++ b/project.py
@@ -1050,6 +1050,7 @@ class Project(object):
1050 retry_fetches=0, 1050 retry_fetches=0,
1051 prune=False, 1051 prune=False,
1052 submodules=False, 1052 submodules=False,
1053 ssh_proxy=None,
1053 clone_filter=None, 1054 clone_filter=None,
1054 partial_clone_exclude=set()): 1055 partial_clone_exclude=set()):
1055 """Perform only the network IO portion of the sync process. 1056 """Perform only the network IO portion of the sync process.
@@ -1143,6 +1144,7 @@ class Project(object):
1143 alt_dir=alt_dir, current_branch_only=current_branch_only, 1144 alt_dir=alt_dir, current_branch_only=current_branch_only,
1144 tags=tags, prune=prune, depth=depth, 1145 tags=tags, prune=prune, depth=depth,
1145 submodules=submodules, force_sync=force_sync, 1146 submodules=submodules, force_sync=force_sync,
1147 ssh_proxy=ssh_proxy,
1146 clone_filter=clone_filter, retry_fetches=retry_fetches): 1148 clone_filter=clone_filter, retry_fetches=retry_fetches):
1147 return False 1149 return False
1148 1150
@@ -1994,6 +1996,7 @@ class Project(object):
1994 prune=False, 1996 prune=False,
1995 depth=None, 1997 depth=None,
1996 submodules=False, 1998 submodules=False,
1999 ssh_proxy=None,
1997 force_sync=False, 2000 force_sync=False,
1998 clone_filter=None, 2001 clone_filter=None,
1999 retry_fetches=2, 2002 retry_fetches=2,
@@ -2041,16 +2044,14 @@ class Project(object):
2041 if not name: 2044 if not name:
2042 name = self.remote.name 2045 name = self.remote.name
2043 2046
2044 ssh_proxy = False
2045 remote = self.GetRemote(name) 2047 remote = self.GetRemote(name)
2046 if remote.PreConnectFetch(): 2048 if not remote.PreConnectFetch():
2047 ssh_proxy = True 2049 ssh_proxy = False
2048 2050
2049 if initial: 2051 if initial:
2050 if alt_dir and 'objects' == os.path.basename(alt_dir): 2052 if alt_dir and 'objects' == os.path.basename(alt_dir):
2051 ref_dir = os.path.dirname(alt_dir) 2053 ref_dir = os.path.dirname(alt_dir)
2052 packed_refs = os.path.join(self.gitdir, 'packed-refs') 2054 packed_refs = os.path.join(self.gitdir, 'packed-refs')
2053 remote = self.GetRemote(name)
2054 2055
2055 all_refs = self.bare_ref.all 2056 all_refs = self.bare_ref.all
2056 ids = set(all_refs.values()) 2057 ids = set(all_refs.values())
@@ -2238,7 +2239,7 @@ class Project(object):
2238 name=name, quiet=quiet, verbose=verbose, output_redir=output_redir, 2239 name=name, quiet=quiet, verbose=verbose, output_redir=output_redir,
2239 current_branch_only=current_branch_only and depth, 2240 current_branch_only=current_branch_only and depth,
2240 initial=False, alt_dir=alt_dir, 2241 initial=False, alt_dir=alt_dir,
2241 depth=None, clone_filter=clone_filter) 2242 depth=None, ssh_proxy=ssh_proxy, clone_filter=clone_filter)
2242 2243
2243 return ok 2244 return ok
2244 2245
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 6f5b5644..28568062 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -57,6 +57,7 @@ from error import RepoChangedException, GitError, ManifestParseError
57import platform_utils 57import platform_utils
58from project import SyncBuffer 58from project import SyncBuffer
59from progress import Progress 59from progress import Progress
60import ssh
60from wrapper import Wrapper 61from wrapper import Wrapper
61from manifest_xml import GitcManifest 62from manifest_xml import GitcManifest
62 63
@@ -357,6 +358,7 @@ later is required to fix a server side protocol bug.
357 optimized_fetch=opt.optimized_fetch, 358 optimized_fetch=opt.optimized_fetch,
358 retry_fetches=opt.retry_fetches, 359 retry_fetches=opt.retry_fetches,
359 prune=opt.prune, 360 prune=opt.prune,
361 ssh_proxy=True,
360 clone_filter=self.manifest.CloneFilter, 362 clone_filter=self.manifest.CloneFilter,
361 partial_clone_exclude=self.manifest.PartialCloneExclude) 363 partial_clone_exclude=self.manifest.PartialCloneExclude)
362 364
@@ -983,8 +985,12 @@ later is required to fix a server side protocol bug.
983 985
984 self._fetch_times = _FetchTimes(self.manifest) 986 self._fetch_times = _FetchTimes(self.manifest)
985 if not opt.local_only: 987 if not opt.local_only:
986 self._FetchMain(opt, args, all_projects, err_event, manifest_name, 988 try:
987 load_local_manifests) 989 ssh.init()
990 self._FetchMain(opt, args, all_projects, err_event, manifest_name,
991 load_local_manifests)
992 finally:
993 ssh.close()
988 994
989 # If we saw an error, exit with code 1 so that other scripts can check. 995 # If we saw an error, exit with code 1 so that other scripts can check.
990 if err_event.is_set(): 996 if err_event.is_set():