Skip to content

Commit 2850b26

Browse files
authored
Add warning for directory permission to in_tail.rb (#4865)
**Which issue(s) this PR fixes**: ~~Fixes #~~ **What this PR does / why we need it**: This PR provides a warning for typical configuration mistakes that prevent log transfer from starting. When using the tail type as a source, it is common for directories with inappropriate partitions to be mistakenly included in the source path. In my opinion, it would be preferable to issue a warning in such cases to help users avoid these mistakes. Steps to Reproduce: ```shell $ sudo mkdir /var/log/noaccess $ sudo mkdir /var/log/noaccess/noaccess2 $ sudo touch /var/log/noaccess/noaccess2/fluentd.log $ sudo chmod 0000 /var/log/noaccess $ sed -Ei 's|^([[:space:]]*)path .*|\1path /var/log/noaccess/noaccess2/fluentd.log|' example/in_tail.conf $ bundle exec fluentd -c example/in_tail.conf {no warning...} ``` **Docs Changes**: No documentation changes required. **Release Note**: in_tail: add warning for directory permission. Signed-off-by: Tomoaki Kobayashi <[email protected]>
1 parent 921b93f commit 2850b26

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

lib/fluent/plugin/in_tail.rb

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ def configure(conf)
165165
@path_formatters = @paths.map{|path| [path, Fluent::Timezone.formatter(@path_timezone, path)]}.to_h
166166
@exclude_path_formatters = @exclude_path.map{|path| [path, Fluent::Timezone.formatter(@path_timezone, path)]}.to_h
167167
end
168+
check_dir_permission unless Fluent.windows?
168169

169170
# TODO: Use plugin_root_dir and storage plugin to store positions if available
170171
if @pos_file
@@ -212,6 +213,20 @@ def configure(conf)
212213
@metrics = MetricsInfo.new(opened_file_metrics, closed_file_metrics, rotated_file_metrics, throttling_metrics)
213214
end
214215

216+
def check_dir_permission
217+
expand_paths_raw.select { |path|
218+
not File.exist?(path)
219+
}.each { |path|
220+
inaccessible_dir = Pathname.new(File.expand_path(path))
221+
.ascend
222+
.reverse_each
223+
.find { |p| p.directory? && !p.executable? }
224+
if inaccessible_dir
225+
log.warn "Skip #{path} because '#{inaccessible_dir}' lacks execute permission."
226+
end
227+
}
228+
end
229+
215230
def configure_tag
216231
if @tag.index('*')
217232
@tag_prefix, @tag_suffix = @tag.split('*')
@@ -321,7 +336,7 @@ def use_glob?(path)
321336
end
322337
end
323338

324-
def expand_paths
339+
def expand_paths_raw
325340
date = Fluent::EventTime.now
326341
paths = []
327342
@paths.each { |path|
@@ -367,10 +382,14 @@ def expand_paths
367382
end
368383
use_glob?(path) ? Dir.glob(path) : path
369384
}.flatten.uniq
385+
paths - excluded
386+
end
387+
388+
def expand_paths
370389
# filter out non existing files, so in case pattern is without '*' we don't do unnecessary work
371390
hash = {}
372-
(paths - excluded).select { |path|
373-
FileTest.exist?(path)
391+
expand_paths_raw.select { |path|
392+
File.exist?(path)
374393
}.each { |path|
375394
# Even we just checked for existence, there is a race condition here as
376395
# of which stat() might fail with ENOENT. See #3224.

test/plugin/test_in_tail.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2592,6 +2592,46 @@ def test_EACCES
25922592
d.instance_shutdown if d && d.instance
25932593
end
25942594

2595+
def test_warn_without_directory_permission
2596+
omit "Cannot test with root user" if Process::UID.eid == 0
2597+
omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
2598+
path = "#{@tmp_dir}/noaccess/tail.txt"
2599+
begin
2600+
FileUtils.mkdir_p("#{@tmp_dir}/noaccess")
2601+
FileUtils.touch(path)
2602+
FileUtils.chmod(0400, path)
2603+
FileUtils.chmod(0600, "#{@tmp_dir}/noaccess")
2604+
config = config_element('', '', {
2605+
'tag' => "tail",
2606+
'path' => path,
2607+
'format' => 'none',
2608+
"pos_file" => "#{@tmp_dir}/tail.pos",
2609+
})
2610+
d = create_driver(config, false)
2611+
fname = File.expand_path("#{@tmp_dir}/noaccess")
2612+
assert(d.logs.any?{|log| log.include?("Skip #{path} because '#{fname}' lacks execute permission.\n") })
2613+
end
2614+
end
2615+
2616+
def test_no_warn_with_directory_permission
2617+
omit "Cannot test with root user" if Process::UID.eid == 0
2618+
omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
2619+
path = "#{@tmp_dir}/noaccess/tail.txt"
2620+
begin
2621+
FileUtils.mkdir_p("#{@tmp_dir}/noaccess")
2622+
FileUtils.chmod(0100, "#{@tmp_dir}/noaccess")
2623+
config = config_element('', '', {
2624+
'tag' => "tail",
2625+
'path' => path,
2626+
'format' => 'none',
2627+
"pos_file" => "#{@tmp_dir}/tail.pos",
2628+
})
2629+
d = create_driver(config, false)
2630+
fname = File.expand_path("#{@tmp_dir}/noaccess")
2631+
assert(d.logs.all?{|log| !log.include?("Skip #{path} because '#{fname}' lacks execute permission.\n") })
2632+
end
2633+
end
2634+
25952635
def test_shutdown_timeout
25962636
Fluent::FileWrapper.open("#{@tmp_dir}/tail.txt", "wb") do |f|
25972637
# Should be large enough to take too long time to consume

0 commit comments

Comments
 (0)