From 2063a7687462b706192b24c6b81ac390251b4c66 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Mon, 19 Jun 2017 15:51:03 -0400 Subject: [PATCH 1/2] follow symlinks recursively when add entry to zip https://bugzilla.redhat.com/show_bug.cgi?id=1450134 --- lib/vmdb/util.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/vmdb/util.rb b/lib/vmdb/util.rb index 92baf676369..48458bcfa7a 100644 --- a/lib/vmdb/util.rb +++ b/lib/vmdb/util.rb @@ -113,8 +113,11 @@ def self.zip_logs(zip_filename, dirs, userid = "system") dirs.each do |dir| dir = Rails.root.join(dir) unless Pathname.new(dir).absolute? Dir.glob(dir).each do |file| - entry, mtime = add_zip_entry(zip, file, zfile) - _log.info "Adding file: [#{entry}], size: [#{File.size(file)}], mtime: [#{mtime}]" + begin + entry, _mtime = add_zip_entry(zip, file, zfile) + rescue => e + _log.error "Failed to add file: [#{entry}]. Error information: #{e.message}" + end end end zip.close @@ -131,9 +134,13 @@ def self.add_zip_entry(zip, file_path, zfile) ztime = Zip::DOSTime.at(mtime.to_i) if File.directory?(file_path) zip.mkdir(entry) + elsif File.symlink?(file_path) + zip_entry = Zip::Entry.new(zfile, entry, nil, nil, nil, nil, nil, nil, ztime) + zip.add(zip_entry, File.realpath(file_path)) else zip_entry = Zip::Entry.new(zfile, entry, nil, nil, nil, nil, nil, nil, ztime) zip.add(zip_entry, file_path) + _log.info "Adding file: [#{entry}], size: [#{File.size(file_path)}], mtime: [#{mtime}]" end return entry, mtime end From 43f9e8391334ffc200db87320bebe79b00c90125 Mon Sep 17 00:00:00 2001 From: Bo Yao Date: Wed, 21 Jun 2017 16:55:01 -0400 Subject: [PATCH 2/2] add new test in spec --- spec/lib/vmdb/util_spec.rb | 67 ++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/spec/lib/vmdb/util_spec.rb b/spec/lib/vmdb/util_spec.rb index d0082ecd9e9..81ef4a6255f 100644 --- a/spec/lib/vmdb/util_spec.rb +++ b/spec/lib/vmdb/util_spec.rb @@ -116,21 +116,49 @@ def self.assert_zip_entry_from_path(expected_entry, path) assert_zip_entry_from_path("GUID", "/var/www/miq/vmdb/GUID") end - it ".add_zip_entry(private)" do + context ".add_zip_entry(private)" do require 'zip/filesystem' - file = "/var/log/messages.log" - entry = "ROOT/var/log/messages.log" - mtime = Time.parse("2013-09-24 09:00:45 -0400") - expect(File).to receive(:mtime).with(file).and_return(mtime) - expect(described_class).to receive(:zip_entry_from_path).with(file).and_return(entry) - - zip = double - ztime = Zip::DOSTime.at(mtime.to_i) - zip_entry = Zip::Entry.new(zip, entry, nil, nil, nil, nil, nil, nil, ztime) - expect(zip).to receive(:add).with(zip_entry, file) - zip_file = double - - expect(described_class.send(:add_zip_entry, zip, file, zip_file)).to eq([entry, mtime]) + let(:origin_file) { Tempfile.new 'origin' } + let(:symlink_level_1) { create_temp_symlink 'symlink_level_1', origin_file.path } + let(:symlink_level_2) { create_temp_symlink 'symlink_level_2', symlink_level_1 } + let(:mtime) { origin_file.mtime } + let(:ztime) { Zip::DOSTime.at(mtime.to_i) } + let(:zip) { double } + let(:zip_file) { double } + + it "entry is a normal file" do + file = "/var/log/messages.log" + entry = "ROOT/var/log/messages.log" + log_mtime = Time.zone.parse("2013-09-24 09:00:45 -0400") + expect(File).to receive(:mtime).with(file).and_return(log_mtime) + expect(described_class).to receive(:zip_entry_from_path).with(file).and_return(entry) + + log_ztime = Zip::DOSTime.at(log_mtime.to_i) + zip_entry = Zip::Entry.new(zip, entry, nil, nil, nil, nil, nil, nil, log_ztime) + expect(zip).to receive(:add).with(zip_entry, file) + + expect(File).to receive(:size).and_return(1) # a stub size for _log.info + expect(described_class.send(:add_zip_entry, zip, file, zip_file)).to eq([entry, log_mtime]) + end + + it "entry is a symlink to origin file, origin file is added with symlink's name" do + entry = 'ROOT' + symlink_level_1 + zip_entry = Zip::Entry.new(zip, entry, nil, nil, nil, nil, nil, nil, ztime) + expect(zip).to receive(:add).with(zip_entry, origin_file.path) + expect(described_class.send(:add_zip_entry, zip, symlink_level_1, zip_file)).to eq([entry, mtime]) + end + + it "entry is a symlink to symlink to origin file, origin file is added with symlink's name" do + entry = 'ROOT' + symlink_level_2 + zip_entry = Zip::Entry.new(zip, entry, nil, nil, nil, nil, nil, nil, ztime) + expect(zip).to receive(:add).with(zip_entry, origin_file.path) + expect(described_class.send(:add_zip_entry, zip, symlink_level_2, zip_file)).to eq([entry, mtime]) + end + + after do + origin_file.close + origin_file.unlink + end end it ".get_evm_log_for_date" do @@ -139,4 +167,15 @@ def self.assert_zip_entry_from_path(expected_entry, path) expect(described_class.get_evm_log_for_date("log/*.log")).to eq("log/evm.log") end + + private + + def create_temp_symlink(name, origin) + symlink_file = Tempfile.new name + symlink_file.close + symlink_name = symlink_file.path + symlink_file.unlink + FileUtils.ln_s origin, symlink_name + symlink_name + end end