From 0a6fab564f7533d87f02272c3febf622b27dd366 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Tue, 27 Apr 2021 17:04:15 +0100 Subject: [PATCH] PERF: Add timeout to theme import git commands (#12856) This ensures that large git repositories cannot cause performance issues on the server. In normal use, this 20s timeout should never be hit. --- lib/theme_store/git_importer.rb | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/lib/theme_store/git_importer.rb b/lib/theme_store/git_importer.rb index c3f28f5795..1525f16185 100644 --- a/lib/theme_store/git_importer.rb +++ b/lib/theme_store/git_importer.rb @@ -3,6 +3,7 @@ module ThemeStore; end class ThemeStore::GitImporter + COMMAND_TIMEOUT_SECONDS = 20 attr_reader :url @@ -24,15 +25,16 @@ class ThemeStore::GitImporter import_public! end if version = Discourse.find_compatible_git_resource(@temp_folder) - Discourse::Utils.execute_command(chdir: @temp_folder) do |runner| - begin - runner.exec "git", "cat-file", "-e", version - rescue RuntimeError => e - tracking_ref = runner.exec "git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{upstream}" - remote_name = tracking_ref.split("/", 2)[0] - runner.exec "git", "fetch", "--depth", "1", remote_name, "#{version}:#{version}" - end - runner.exec "git", "reset", "--hard", version + begin + execute "git", "cat-file", "-e", version + rescue RuntimeError => e + tracking_ref = execute "git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{upstream}" + remote_name = tracking_ref.split("/", 2)[0] + execute "git", "fetch", remote_name, "#{version}:#{version}" + end + + begin + execute "git", "reset", "--hard", version rescue RuntimeError raise RemoteTheme::ImportError.new(I18n.t("themes.import_error.git_ref_not_found", ref: version)) end @@ -42,16 +44,14 @@ class ThemeStore::GitImporter def commits_since(hash) commit_hash, commits_behind = nil - Discourse::Utils.execute_command(chdir: @temp_folder) do |runner| - commit_hash = runner.exec("git", "rev-parse", "HEAD").strip - commits_behind = runner.exec("git", "rev-list", "#{hash}..HEAD", "--count").strip rescue -1 - end + commit_hash = execute("git", "rev-parse", "HEAD").strip + commits_behind = execute("git", "rev-list", "#{hash}..HEAD", "--count").strip rescue -1 [commit_hash, commits_behind] end def version - Discourse::Utils.execute_command("git", "rev-parse", "HEAD", chdir: @temp_folder).strip + execute "git", "rev-parse", "HEAD" end def cleanup! @@ -117,4 +117,7 @@ class ThemeStore::GitImporter FileUtils.rm_rf ssh_folder end + def execute(*args) + Discourse::Utils.execute_command(*args, chdir: @temp_folder, timeout: COMMAND_TIMEOUT_SECONDS) + end end