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.
This commit is contained in:
David Taylor 2021-04-27 17:04:15 +01:00 committed by GitHub
parent 2c4fd7f7c7
commit 0a6fab564f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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