mirror of
https://github.com/discourse/discourse.git
synced 2024-11-30 08:34:39 +08:00
972db687fe
Why this change? We currently support `GlobalSetting.refresh_maxmind_db_during_precompile_days` which should cache the maxmind databases on disk for the configured number of days before it downloads the databases from maxmind again via the API. This was previously added to help us avoid hitting the API rate limit from maxmind. However, there was a bug in the `copy_maxmind` when we copied the latest downloaded database to the cache directory. In particular, `FileUtils.cp` was called with `preserve: true` which would preserve the modified time of the file being copied. This is problematic because download the database from maxmind on 2 April 2024 can give us a file with an mtime of 29 March 2024. If `GlobalSetting.refresh_maxmind_db_during_precompile_days` is set to `2` for example, the cache will never be used since we will think that the file has been downloaded for more than 2 days in our checks. What is the fix here? While we want to preserve the owner and group of the file, we do not want to preserve the modified time and hence we will call `FileUtils.touch` when copying the file.
89 lines
2.3 KiB
Ruby
89 lines
2.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
GEOLITE_DBS ||= %w[GeoLite2-City GeoLite2-ASN]
|
|
|
|
desc "downloads MaxMind's GeoLite2-City databases"
|
|
task "maxminddb:get" => "environment" do
|
|
GEOLITE_DBS.each do |name|
|
|
puts "Downloading MaxMindDb's #{name}..."
|
|
DiscourseIpInfo.mmdb_download(name)
|
|
end
|
|
end
|
|
|
|
def get_mmdb_time(root_path)
|
|
mmdb_time = nil
|
|
|
|
GEOLITE_DBS.each do |name|
|
|
path = File.join(root_path, "#{name}.mmdb")
|
|
|
|
if File.exist?(path)
|
|
mmdb_time = File.mtime(path)
|
|
else
|
|
mmdb_time = nil
|
|
break
|
|
end
|
|
end
|
|
|
|
mmdb_time
|
|
end
|
|
|
|
def copy_maxmind(from_path, to_path)
|
|
puts "Copying MaxMindDB from #{from_path} to #{to_path}"
|
|
|
|
GEOLITE_DBS.each do |name|
|
|
from = File.join(from_path, "#{name}.mmdb")
|
|
to = File.join(to_path, "#{name}.mmdb")
|
|
FileUtils.cp(from, to, preserve: true)
|
|
FileUtils.touch(to)
|
|
end
|
|
end
|
|
|
|
maxmind_thread = nil
|
|
|
|
task "maxminddb:refresh": "environment" do
|
|
refresh_days = GlobalSetting.refresh_maxmind_db_during_precompile_days
|
|
next if refresh_days.to_i <= 0
|
|
|
|
mmdb_time = get_mmdb_time(DiscourseIpInfo.path)
|
|
|
|
if GlobalSetting.maxmind_backup_path.present?
|
|
backup_mmdb_time = get_mmdb_time(GlobalSetting.maxmind_backup_path)
|
|
puts "Detected MaxMindDB backup (downloaded: #{backup_mmdb_time}) at #{GlobalSetting.maxmind_backup_path}"
|
|
mmdb_time ||= backup_mmdb_time
|
|
end
|
|
|
|
if backup_mmdb_time && backup_mmdb_time >= mmdb_time
|
|
copy_maxmind(GlobalSetting.maxmind_backup_path, DiscourseIpInfo.path)
|
|
mmdb_time = backup_mmdb_time
|
|
end
|
|
|
|
if mmdb_time && mmdb_time >= refresh_days.days.ago
|
|
puts "Skip downloading MaxMindDB as it was last downloaded at #{mmdb_time}"
|
|
next
|
|
end
|
|
|
|
puts "Downloading MaxMindDB..."
|
|
|
|
maxmind_thread =
|
|
Thread.new do
|
|
name = "unknown"
|
|
begin
|
|
GEOLITE_DBS.each do |db|
|
|
name = db
|
|
DiscourseIpInfo.mmdb_download(db)
|
|
end
|
|
|
|
if GlobalSetting.maxmind_backup_path.present?
|
|
copy_maxmind(DiscourseIpInfo.path, GlobalSetting.maxmind_backup_path)
|
|
end
|
|
rescue OpenURI::HTTPError => e
|
|
STDERR.puts("*" * 100)
|
|
STDERR.puts("MaxMindDB (#{name}) could not be downloaded: #{e}")
|
|
STDERR.puts("*" * 100)
|
|
Rails.logger.warn("MaxMindDB (#{name}) could not be downloaded: #{e}")
|
|
end
|
|
end
|
|
|
|
at_exit { maxmind_thread.join }
|
|
end
|