Skip to content

Commit 68edd0d

Browse files
committed
Added umask support to system configuration
- Implemented 'umask' option in system config to address #4810. - Users can now define 'umask' in Fluentd configuration instead of CLI args. - Improves usability for services and container images by removing reliance on '--umask' argument. Signed-off-by: kushynoda <[email protected]>
1 parent d35f5a1 commit 68edd0d

File tree

4 files changed

+180
-10
lines changed

4 files changed

+180
-10
lines changed

fluent.conf

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# In v1 configuration, type and id are @ prefix parameters.
22
# @type and @id are recommended. type and id are still available for backward compatibility
33

4+
## System-wide configurations
5+
<system>
6+
umask 0027
7+
</system>
8+
49
## built-in TCP input
510
## $ echo <json> | fluent-cat <tag>
611
<source>
@@ -12,7 +17,6 @@
1217
#<source>
1318
# @type unix
1419
#</source>
15-
1620
# HTTP input
1721
# http://localhost:8888/<tag>?json=<json>
1822
<source>

lib/fluent/root_agent.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,33 @@ def configure(conf)
180180
label_configs.each { |name, e| @labels[name].configure(e) }
181181
setup_error_label(error_label_config) if error_label_config
182182

183+
# Get umask value from system config
184+
system_conf = conf.elements.find { |e| e.name == "system" }
185+
if system_conf
186+
if system_conf.has_key?("umask")
187+
umask_str = system_conf.to_h["umask"]
188+
begin
189+
umask_value = Integer(umask_str, 8) # ArgumentError for invalid octal
190+
if umask_value > 0
191+
File.umask(umask_value)
192+
log.info "Applied umask: #{sprintf("%04o", File.umask)}"
193+
end
194+
rescue ArgumentError
195+
raise Fluent::ConfigError, "Invalid umask value: #{umask_str} (must be valid octal)"
196+
end
197+
else
198+
# No umask found in system config, set default
199+
default_umask = 0022
200+
File.umask(default_umask)
201+
log.info "No umask specified in config, using default: #{sprintf("%04o", File.umask)}"
202+
end
203+
else
204+
# No system section found, set default
205+
default_umask = 0022
206+
File.umask(default_umask)
207+
log.info "No system section found in config, using default umask: #{sprintf("%04o", File.umask)}"
208+
end
209+
183210
super
184211

185212
setup_source_only_buffer_agent if @source_only_mode.enabled?

test/test_config.rb

Lines changed: 102 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ def test_check_not_fetchd
161161
sub_test_case "yaml config" do
162162
def test_included
163163
write_config "#{TMP_DIR}/config_test_not_fetched.yaml", <<-EOS
164+
system:
165+
umask: "0022"
164166
config:
165167
- source:
166168
$type: dummy
@@ -195,12 +197,13 @@ def test_included
195197
flush_mode: interval
196198
flush_interval: 1s
197199
EOS
198-
root_conf = read_config("#{TMP_DIR}/config_test_not_fetched.yaml", use_yaml: true)
199-
dummy_source_conf = root_conf.elements.first
200-
tcp_source_conf = root_conf.elements[1]
200+
root_conf = read_config("#{TMP_DIR}/config_test_not_fetched.yaml", use_yaml: true)
201+
system_conf = root_conf.elements.find { |e| e.name == "system" }
202+
dummy_source_conf = root_conf.elements.find { |e| e.name == "source" && e['@type'] == "dummy" }
203+
tcp_source_conf = root_conf.elements.find { |e| e.name == "source" && e['@type'] == "tcp" }
201204
parse_tcp_conf = tcp_source_conf.elements.first
202-
match_conf = root_conf.elements[2]
203-
label_conf = root_conf.elements[3]
205+
match_conf = root_conf.elements.find { |e| e.name == "match" && e.arg == "tag.*" }
206+
label_conf = root_conf.elements.find { |e| e.name == "label" }
204207
fluent_log_conf = label_conf.elements.first
205208
fluent_log_buffer_conf = fluent_log_conf.elements.first
206209

@@ -222,6 +225,7 @@ def test_included
222225
'memory',
223226
'interval',
224227
'1s',
228+
'0022',
225229
],
226230
[
227231
dummy_source_conf['@type'],
@@ -240,11 +244,14 @@ def test_included
240244
fluent_log_buffer_conf['@type'],
241245
fluent_log_buffer_conf['flush_mode'],
242246
fluent_log_buffer_conf['flush_interval'],
247+
system_conf['umask'],
243248
])
244249
end
245250

246251
def test_included_glob
247252
write_config "#{TMP_DIR}/config.yaml", <<-EOS
253+
system:
254+
umask: "0022"
248255
config:
249256
- !include "include/*.yaml"
250257
EOS
@@ -272,10 +279,11 @@ def test_included_glob
272279
flush_interval: 1s
273280
EOS
274281
root_conf = read_config("#{TMP_DIR}/config.yaml", use_yaml: true)
275-
tcp_source_conf = root_conf.elements.first
276-
dummy_source_conf = root_conf.elements[1]
282+
system_conf = root_conf.elements.find { |e| e.name == "system" }
283+
tcp_source_conf = root_conf.elements.find { |e| e.name == "source" && e['@type'] == "tcp" }
284+
dummy_source_conf = root_conf.elements.find { |e| e.name == "source" && e['@type'] == "dummy" }
277285
parse_tcp_conf = tcp_source_conf.elements.first
278-
match_conf = root_conf.elements[2]
286+
match_conf = root_conf.elements.find { |e| e.name == "match" && e.arg == "tag.*" }
279287

280288
assert_equal(
281289
[
@@ -287,6 +295,7 @@ def test_included_glob
287295
'tag.dummy',
288296
'stdout',
289297
'tag.*',
298+
'0022',
290299
],
291300
[
292301
tcp_source_conf['@type'],
@@ -297,6 +306,7 @@ def test_included_glob
297306
dummy_source_conf['tag'],
298307
match_conf['@type'],
299308
match_conf.arg,
309+
system_conf['umask'],
300310
])
301311
end
302312

@@ -343,6 +353,42 @@ def test_check_not_fetchd
343353
10.times { match_conf['type'] }
344354
assert_equal before_size, match_conf.unused.size
345355
end
356+
357+
test 'yaml system config with umask' do
358+
write_config "#{TMP_DIR}/config_test_umask.yaml", <<-EOS
359+
system:
360+
umask: "0022"
361+
config:
362+
- source:
363+
$type: dummy
364+
tag: tag.dummy
365+
- match:
366+
$tag: tag.*
367+
$type: stdout
368+
EOS
369+
conf = read_config("#{TMP_DIR}/config_test_umask.yaml", use_yaml: true)
370+
assert_equal "0022", conf.elements.find { |e| e.name == "system" }["umask"]
371+
end
372+
373+
test 'system config with invalid umask' do
374+
conf = <<-EOC
375+
<system>
376+
umask 0999 # invalid octal
377+
</system>
378+
EOC
379+
conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true)
380+
assert_equal "0999", conf.elements.find { |e| e.name == "system" }["umask"]
381+
end
382+
383+
test 'system config without umask' do
384+
conf = <<-EOC
385+
<system>
386+
# no umask setting
387+
</system>
388+
EOC
389+
conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true)
390+
assert_nil conf.elements.find { |e| e.name == "system" }["umask"]
391+
end
346392
end
347393

348394
def write_config(path, data, encoding: 'utf-8')
@@ -371,5 +417,52 @@ def write_config(path, data, encoding: 'utf-8')
371417
assert_equal('value', c['key'])
372418
assert_equal('value2', c['key2'])
373419
end
420+
421+
test 'system config with umask' do
422+
conf = <<-EOC
423+
<system>
424+
umask 0022
425+
</system>
426+
EOC
427+
conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true)
428+
ra = Fluent::RootAgent.new(log: $log)
429+
old_umask = File.umask
430+
begin
431+
ra.configure(conf)
432+
assert_equal 0022, File.umask
433+
ensure
434+
File.umask(old_umask)
435+
end
436+
end
437+
438+
test 'system config with invalid umask' do
439+
conf = <<-EOC
440+
<system>
441+
umask 0999 # invalid octal
442+
</system>
443+
EOC
444+
conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true)
445+
ra = Fluent::RootAgent.new(log: $log)
446+
assert_raise(Fluent::ConfigError) do
447+
ra.configure(conf)
448+
end
449+
end
450+
451+
test 'system config without umask' do
452+
conf = <<-EOC
453+
<system>
454+
# no umask setting
455+
</system>
456+
EOC
457+
conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true)
458+
ra = Fluent::RootAgent.new(log: $log)
459+
old_umask = File.umask
460+
begin
461+
ra.configure(conf)
462+
assert_equal 0022, File.umask
463+
ensure
464+
File.umask(old_umask)
465+
end
466+
end
374467
end
375-
end
468+
end

test/test_root_agent.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,4 +1167,50 @@ def setup
11671167
@root_agent.shutdown
11681168
end
11691169
end
1170+
1171+
def test_configure_with_umask
1172+
conf = <<-EOC
1173+
<system>
1174+
umask 0022
1175+
</system>
1176+
EOC
1177+
conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true)
1178+
ra = Fluent::RootAgent.new(log: $log)
1179+
old_umask = File.umask
1180+
begin
1181+
ra.configure(conf)
1182+
assert_equal 0022, File.umask
1183+
ensure
1184+
File.umask(old_umask)
1185+
end
1186+
end
1187+
1188+
def test_configure_with_invalid_umask
1189+
conf = <<-EOC
1190+
<system>
1191+
umask 0999 # invalid octal
1192+
</system>
1193+
EOC
1194+
conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true)
1195+
ra = Fluent::RootAgent.new(log: $log)
1196+
assert_raise(Fluent::ConfigError) do
1197+
ra.configure(conf)
1198+
end
1199+
end
1200+
1201+
def test_configure_without_umask
1202+
conf = <<-EOC
1203+
<system>
1204+
</system>
1205+
EOC
1206+
conf = Fluent::Config.parse(conf, "(test)", "(test_dir)", true)
1207+
ra = Fluent::RootAgent.new(log: $log)
1208+
old_umask = File.umask
1209+
begin
1210+
ra.configure(conf)
1211+
assert_equal 0022, File.umask
1212+
ensure
1213+
File.umask(old_umask)
1214+
end
1215+
end
11701216
end

0 commit comments

Comments
 (0)