diff --git a/fluent.conf b/fluent.conf index 98d7a38856..aa6b02541d 100644 --- a/fluent.conf +++ b/fluent.conf @@ -1,6 +1,11 @@ # In v1 configuration, type and id are @ prefix parameters. # @type and @id are recommended. type and id are still available for backward compatibility +## System-wide configurations + + umask 0027 + + ## built-in TCP input ## $ echo | fluent-cat @@ -12,7 +17,6 @@ # # @type unix # - # HTTP input # http://localhost:8888/?json= diff --git a/lib/fluent/root_agent.rb b/lib/fluent/root_agent.rb index 552819e4bf..8185166977 100644 --- a/lib/fluent/root_agent.rb +++ b/lib/fluent/root_agent.rb @@ -180,6 +180,33 @@ def configure(conf) label_configs.each { |name, e| @labels[name].configure(e) } setup_error_label(error_label_config) if error_label_config + # Get umask value from system config + system_conf = conf.elements.find { |e| e.name == "system" } + if system_conf + if system_conf.has_key?("umask") + umask_str = system_conf.to_h["umask"] + begin + umask_value = Integer(umask_str, 8) # ArgumentError for invalid octal + if umask_value > 0 + File.umask(umask_value) + log.info "Applied umask: #{sprintf("%04o", File.umask)}" + end + rescue ArgumentError + raise Fluent::ConfigError, "Invalid umask value: #{umask_str} (must be valid octal)" + end + else + # No umask found in system config, set default + default_umask = 0022 + File.umask(default_umask) + log.info "No umask specified in config, using default: #{sprintf("%04o", File.umask)}" + end + else + # No system section found, set default + default_umask = 0022 + File.umask(default_umask) + log.info "No system section found in config, using default umask: #{sprintf("%04o", File.umask)}" + end + super setup_source_only_buffer_agent if @source_only_mode.enabled? diff --git a/test/test_config.rb b/test/test_config.rb index 7533e6e16b..7922afb734 100644 --- a/test/test_config.rb +++ b/test/test_config.rb @@ -161,6 +161,8 @@ def test_check_not_fetchd sub_test_case "yaml config" do def test_included write_config "#{TMP_DIR}/config_test_not_fetched.yaml", <<-EOS + system: + umask: "0022" config: - source: $type: dummy @@ -195,12 +197,13 @@ def test_included flush_mode: interval flush_interval: 1s EOS - root_conf = read_config("#{TMP_DIR}/config_test_not_fetched.yaml", use_yaml: true) - dummy_source_conf = root_conf.elements.first - tcp_source_conf = root_conf.elements[1] + root_conf = read_config("#{TMP_DIR}/config_test_not_fetched.yaml", use_yaml: true) + system_conf = root_conf.elements.find { |e| e.name == "system" } + dummy_source_conf = root_conf.elements.find { |e| e.name == "source" && e['@type'] == "dummy" } + tcp_source_conf = root_conf.elements.find { |e| e.name == "source" && e['@type'] == "tcp" } parse_tcp_conf = tcp_source_conf.elements.first - match_conf = root_conf.elements[2] - label_conf = root_conf.elements[3] + match_conf = root_conf.elements.find { |e| e.name == "match" && e.arg == "tag.*" } + label_conf = root_conf.elements.find { |e| e.name == "label" } fluent_log_conf = label_conf.elements.first fluent_log_buffer_conf = fluent_log_conf.elements.first @@ -222,6 +225,7 @@ def test_included 'memory', 'interval', '1s', + '0022', ], [ dummy_source_conf['@type'], @@ -240,11 +244,14 @@ def test_included fluent_log_buffer_conf['@type'], fluent_log_buffer_conf['flush_mode'], fluent_log_buffer_conf['flush_interval'], + system_conf['umask'], ]) end def test_included_glob write_config "#{TMP_DIR}/config.yaml", <<-EOS + system: + umask: "0022" config: - !include "include/*.yaml" EOS @@ -272,10 +279,11 @@ def test_included_glob flush_interval: 1s EOS root_conf = read_config("#{TMP_DIR}/config.yaml", use_yaml: true) - tcp_source_conf = root_conf.elements.first - dummy_source_conf = root_conf.elements[1] + system_conf = root_conf.elements.find { |e| e.name == "system" } + tcp_source_conf = root_conf.elements.find { |e| e.name == "source" && e['@type'] == "tcp" } + dummy_source_conf = root_conf.elements.find { |e| e.name == "source" && e['@type'] == "dummy" } parse_tcp_conf = tcp_source_conf.elements.first - match_conf = root_conf.elements[2] + match_conf = root_conf.elements.find { |e| e.name == "match" && e.arg == "tag.*" } assert_equal( [ @@ -287,6 +295,7 @@ def test_included_glob 'tag.dummy', 'stdout', 'tag.*', + '0022', ], [ tcp_source_conf['@type'], @@ -297,6 +306,7 @@ def test_included_glob dummy_source_conf['tag'], match_conf['@type'], match_conf.arg, + system_conf['umask'], ]) end @@ -343,6 +353,42 @@ def test_check_not_fetchd 10.times { match_conf['type'] } assert_equal before_size, match_conf.unused.size end + + test 'yaml system config with umask' do + write_config "#{TMP_DIR}/config_test_umask.yaml", <<-EOS + system: + umask: "0022" + config: + - source: + $type: dummy + tag: tag.dummy + - match: + $tag: tag.* + $type: stdout + EOS + conf = read_config("#{TMP_DIR}/config_test_umask.yaml", use_yaml: true) + assert_equal "0022", conf.elements.find { |e| e.name == "system" }["umask"] + end + + test 'system config with invalid umask' do + conf = <<-EOC + + umask 0999 # invalid octal + + EOC + conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true) + assert_equal "0999", conf.elements.find { |e| e.name == "system" }["umask"] + end + + test 'system config without umask' do + conf = <<-EOC + + # no umask setting + + EOC + conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true) + assert_nil conf.elements.find { |e| e.name == "system" }["umask"] + end end def write_config(path, data, encoding: 'utf-8') @@ -371,5 +417,52 @@ def write_config(path, data, encoding: 'utf-8') assert_equal('value', c['key']) assert_equal('value2', c['key2']) end + + test 'system config with umask' do + conf = <<-EOC + + umask 0022 + + EOC + conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true) + ra = Fluent::RootAgent.new(log: $log) + old_umask = File.umask + begin + ra.configure(conf) + assert_equal 0022, File.umask + ensure + File.umask(old_umask) + end + end + + test 'system config with invalid umask' do + conf = <<-EOC + + umask 0999 # invalid octal + + EOC + conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true) + ra = Fluent::RootAgent.new(log: $log) + assert_raise(Fluent::ConfigError) do + ra.configure(conf) + end + end + + test 'system config without umask' do + conf = <<-EOC + + # no umask setting + + EOC + conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true) + ra = Fluent::RootAgent.new(log: $log) + old_umask = File.umask + begin + ra.configure(conf) + assert_equal 0022, File.umask + ensure + File.umask(old_umask) + end + end end -end +end \ No newline at end of file diff --git a/test/test_root_agent.rb b/test/test_root_agent.rb index 8b44b68699..3fd0390c0c 100644 --- a/test/test_root_agent.rb +++ b/test/test_root_agent.rb @@ -1167,4 +1167,50 @@ def setup @root_agent.shutdown end end + + def test_configure_with_umask + conf = <<-EOC + + umask 0022 + +EOC + conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true) + ra = Fluent::RootAgent.new(log: $log) + old_umask = File.umask + begin + ra.configure(conf) + assert_equal 0022, File.umask + ensure + File.umask(old_umask) + end + end + + def test_configure_with_invalid_umask + conf = <<-EOC + + umask 0999 # invalid octal + +EOC + conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true) + ra = Fluent::RootAgent.new(log: $log) + assert_raise(Fluent::ConfigError) do + ra.configure(conf) + end + end + + def test_configure_without_umask + conf = <<-EOC + + +EOC + conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true) + ra = Fluent::RootAgent.new(log: $log) + old_umask = File.umask + begin + ra.configure(conf) + assert_equal 0022, File.umask + ensure + File.umask(old_umask) + end + end end