fluentd 1.11.5 → 1.12.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83bcc9640169d819af2a9336cc0bae773d4104b056467b6656115bba46565e02
4
- data.tar.gz: a4e1c27ab6ba4454ae5aa8c2db25072503f10f21b158aecc686f2499e9416d48
3
+ metadata.gz: ea33aa9fbbca10538b329676df8dc024f38836b8c0a3bd78ff8afe9b21e59a27
4
+ data.tar.gz: d3500418626d7f49305b4dee07ab6dfa10c84687ee754fd967aee1200a815dc2
5
5
  SHA512:
6
- metadata.gz: de9b224867b2b9dc5394889246e76b72449b1df6dfb8ddb982260ef0521d3a66d86d7c1cae319ddaa9c8cd00264be1c16539389c42da435c539534b537b567be
7
- data.tar.gz: 4a077991b270c84aa8ab21e746ce75e06a5061ec70a2acd43fdac77127eb627d86241b18238f156a510decd56b8a311a54f51eaa723b69947cbd216c03accd9d
6
+ metadata.gz: 7a43d215a3a026042028643ca627f81411379efe8eb5090c4c98f8886c22efe33595362b82273889b97ecc8a95af8c93d0d2dbf5d8494c3c8e680942dd8c0c67
7
+ data.tar.gz: a17be6c1b92193649412e223ce7bba96d94f1122b309e459dc72a6e7f0a5339874e2a9d9d352a88612c3d7e603c2276b8109af97b8b26cc3967d81cae7925071
@@ -0,0 +1,22 @@
1
+ # Number of days of inactivity before an issue becomes stale
2
+ daysUntilStale: 90
3
+ # Number of days of inactivity before a stale issue is closed
4
+ daysUntilClose: 30
5
+ # Issues with these labels will never be considered stale
6
+ exemptLabels:
7
+ - bug
8
+ - enhancement
9
+ - feature request
10
+ - pending
11
+ - work_in_progress
12
+ - v1
13
+ - v2
14
+ # Label to use when marking an issue as stale
15
+ staleLabel: stale
16
+ # Comment to post when marking an issue as stale. Set to `false` to disable
17
+ markComment: >
18
+ This issue has been automatically marked as stale because it has not had
19
+ recent activity. It will be closed if no further activity occurs. Thank you
20
+ for your contributions.
21
+ # Comment to post when closing a stale issue. Set to `false` to disable
22
+ closeComment: true
@@ -9,44 +9,63 @@ matrix:
9
9
  include:
10
10
  - rvm: 2.4.9
11
11
  os: linux
12
+ env: USE_CAPNG=false
12
13
  - rvm: 2.4.9
13
14
  os: linux-ppc64le
15
+ env: USE_CAPNG=false
14
16
  - rvm: 2.5.7
15
17
  os: linux
18
+ env: USE_CAPNG=false
16
19
  - rvm: 2.5.7
17
20
  os: linux
18
21
  arch: s390x
19
22
  dist: xenial
23
+ env: USE_CAPNG=false
20
24
  - rvm: 2.6.5
21
25
  os: linux
26
+ env: USE_CAPNG=false
27
+ - rvm: 2.6.6
28
+ os: linux
29
+ env: USE_CAPNG=true
22
30
  - rvm: 2.7.0
23
31
  os: linux
32
+ env: USE_CAPNG=false
24
33
  - rvm: ruby-head
25
34
  os: linux
35
+ env: USE_CAPNG=false
26
36
  - rvm: ruby-head
27
37
  os: linux-ppc64le
38
+ env: USE_CAPNG=false
28
39
  - rvm: 2.4.6
29
40
  os: osx
30
41
  osx_image: xcode8.3 # OSX 10.12
42
+ env: USE_CAPNG=false
31
43
  - rvm: ruby-head
32
44
  os: osx
33
45
  osx_image: xcode8.3 # OSX 10.12
46
+ env: USE_CAPNG=false
34
47
  allow_failures:
35
48
  - rvm: 2.4.6
36
49
  os: osx
37
50
  osx_image: xcode8.3
51
+ env: USE_CAPNG=false
38
52
  - rvm: 2.5.7
39
53
  os: linux
40
54
  arch: s390x
41
55
  dist: xenial
56
+ env: USE_CAPNG=false
42
57
  - rvm: ruby-head
58
+ env: USE_CAPNG=false
43
59
 
44
60
  branches:
45
61
  only:
46
62
  - master
47
63
 
48
- before_install:
49
- - gem update --system=3.1.2
64
+ before_install: |
65
+ gem update --system=3.1.2
66
+ if [[ x"${USE_CAPNG}" == "xtrue" ]]; then
67
+ echo 'gem "capng_c"' >> Gemfile.local
68
+ fi
50
69
 
51
70
  sudo: false
52
71
  dist: trusty # for TLSv1.2 support
@@ -55,3 +74,4 @@ addons:
55
74
  apt:
56
75
  packages:
57
76
  - libgmp3-dev
77
+ - libcap-ng-dev
@@ -8,6 +8,7 @@
8
8
  https://github.com/fluent/fluentd/pull/3152
9
9
  * out_http: adding support for intermediate certificates
10
10
  https://github.com/fluent/fluentd/pull/3146
11
+ * Update serverengine dependency to 2.2.2 or later
11
12
 
12
13
  ### Bug fix
13
14
 
@@ -7,6 +7,9 @@ install:
7
7
  - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
8
8
  - ruby --version
9
9
  - gem --version
10
+ # stay 0.14.0 for Windows CI until https://github.com/socketry/protocol-http2/issues/6 will be fixed
11
+ - ps: Write-Output "gem 'protocol-http2', ['<= 0.14.0']" | Out-File -FilePath Gemfile.local -Encoding default
12
+ - type Gemfile.local
10
13
  - ridk.cmd exec bundle install
11
14
  build: off
12
15
  test_script:
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+ here = File.dirname(__FILE__)
4
+ $LOAD_PATH << File.expand_path(File.join(here, '..', 'lib'))
5
+ require 'fluent/command/cap_ctl'
6
+
7
+ Fluent::CapCtl.new.call
@@ -18,6 +18,7 @@ Gem::Specification.new do |gem|
18
18
 
19
19
  gem.required_ruby_version = '>= 2.4'
20
20
 
21
+ gem.add_runtime_dependency("bundler")
21
22
  gem.add_runtime_dependency("msgpack", [">= 1.3.1", "< 2.0.0"])
22
23
  gem.add_runtime_dependency("yajl-ruby", ["~> 1.0"])
23
24
  gem.add_runtime_dependency("cool.io", [">= 1.4.5", "< 2.0.0"])
@@ -0,0 +1,87 @@
1
+ #
2
+ # Fluent
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require "fluent/env"
18
+
19
+ if Fluent.linux?
20
+ begin
21
+ require 'capng'
22
+ rescue LoadError
23
+ end
24
+ end
25
+
26
+ module Fluent
27
+ if defined?(CapNG)
28
+ class Capability
29
+ def initialize(target = nil, pid = nil)
30
+ @capng = CapNG.new(target, pid)
31
+ end
32
+
33
+ def usable?
34
+ true
35
+ end
36
+
37
+ def apply(select_set)
38
+ @capng.apply(select_set)
39
+ end
40
+
41
+ def clear(select_set)
42
+ @capng.clear(select_set)
43
+ end
44
+
45
+ def have_capability?(type, capability)
46
+ @capng.have_capability?(type, capability)
47
+ end
48
+
49
+ def update(action, type, capability_or_capability_array)
50
+ @capng.update(action, type, capability_or_capability_array)
51
+ end
52
+
53
+ def have_capabilities?(select_set)
54
+ @capng.have_capabilities?(select_set)
55
+ end
56
+ end
57
+ else
58
+ class Capability
59
+ def initialize(target = nil, pid = nil)
60
+ end
61
+
62
+ def usable?
63
+ false
64
+ end
65
+
66
+ def apply(select_set)
67
+ false
68
+ end
69
+
70
+ def clear(select_set)
71
+ false
72
+ end
73
+
74
+ def have_capability?(type, capability)
75
+ false
76
+ end
77
+
78
+ def update(action, type, capability_or_capability_array)
79
+ false
80
+ end
81
+
82
+ def have_capabilities?(select_set)
83
+ false
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,174 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'optparse'
18
+ require 'fluent/log'
19
+ require 'fluent/env'
20
+ require 'fluent/capability'
21
+
22
+ module Fluent
23
+ class CapCtl
24
+ def prepare_option_parser
25
+ @op = OptionParser.new
26
+
27
+ @op.on('--clear', "Clear Fluentd Ruby capability") {|s|
28
+ @opts[:clear_capabilities] = true
29
+ }
30
+
31
+ @op.on('--add [CAPABILITITY1,CAPABILITY2, ...]', "Add capabilities into Fluentd Ruby") {|s|
32
+ @opts[:add_capabilities] = s
33
+ }
34
+
35
+ @op.on('--drop [CAPABILITITY1,CAPABILITY2, ...]', "Drop capabilities from Fluentd Ruby") {|s|
36
+ @opts[:drop_capabilities] = s
37
+ }
38
+
39
+ @op.on('--get', "Get capabilities for Fluentd Ruby") {|s|
40
+ @opts[:get_capabilities] = true
41
+ }
42
+
43
+ @op.on('-f', '--file FILE', "Specify target file to add Linux capabilities") {|s|
44
+ @opts[:target_file] = s
45
+ }
46
+ end
47
+
48
+ def usage(msg)
49
+ puts @op.to_s
50
+ puts "error: #{msg}" if msg
51
+ exit 1
52
+ end
53
+
54
+ def initialize(argv = ARGV)
55
+ @opts = {}
56
+ @argv = argv
57
+
58
+ if Fluent.linux?
59
+ begin
60
+ require 'capng'
61
+
62
+ @capng = CapNG.new
63
+ rescue LoadError
64
+ puts "Error: capng_c is not loaded. Please install it first."
65
+ exit 1
66
+ end
67
+ else
68
+ puts "Error: This environment is not supported."
69
+ exit 2
70
+ end
71
+
72
+ prepare_option_parser
73
+ end
74
+
75
+ def call
76
+ parse_options!(@argv)
77
+
78
+ target_file = if !!@opts[:target_file]
79
+ @opts[:target_file]
80
+ else
81
+ File.readlink("/proc/self/exe")
82
+ end
83
+
84
+ if @opts[:clear_capabilities]
85
+ clear_capabilities(@opts, target_file)
86
+ elsif @opts[:add_capabilities]
87
+ add_capabilities(@opts, target_file)
88
+ elsif @opts[:drop_capabilities]
89
+ drop_capabilities(@opts, target_file)
90
+ end
91
+ if @opts[:get_capabilities]
92
+ get_capabilities(@opts, target_file)
93
+ end
94
+ end
95
+
96
+ def clear_capabilities(opts, target_file)
97
+ if !!opts[:clear_capabilities]
98
+ @capng.clear(:caps)
99
+ ret = @capng.apply_caps_file(target_file)
100
+ puts "Clear capabilities #{ret ? 'done' : 'fail'}."
101
+ end
102
+ end
103
+
104
+ def add_capabilities(opts, target_file)
105
+ if add_caps = opts[:add_capabilities]
106
+ @capng.clear(:caps)
107
+ @capng.caps_file(target_file)
108
+ capabilities = add_caps.split(/\s*,\s*/)
109
+ check_capabilities(capabilities, get_valid_capabilities)
110
+ ret = @capng.update(:add,
111
+ CapNG::Type::EFFECTIVE | CapNG::Type::INHERITABLE | CapNG::Type::PERMITTED,
112
+ capabilities)
113
+ puts "Updating #{add_caps} #{ret ? 'done' : 'fail'}."
114
+ ret = @capng.apply_caps_file(target_file)
115
+ puts "Adding #{add_caps} #{ret ? 'done' : 'fail'}."
116
+ end
117
+ end
118
+
119
+ def drop_capabilities(opts, target_file)
120
+ if drop_caps = opts[:drop_capabilities]
121
+ @capng.clear(:caps)
122
+ @capng.caps_file(target_file)
123
+ capabilities = drop_caps.split(/\s*,\s*/)
124
+ check_capabilities(capabilities, get_valid_capabilities)
125
+ ret = @capng.update(:drop,
126
+ CapNG::Type::EFFECTIVE | CapNG::Type::INHERITABLE | CapNG::Type::PERMITTED,
127
+ capabilities)
128
+ puts "Updating #{drop_caps} #{ret ? 'done' : 'fail'}."
129
+ @capng.apply_caps_file(target_file)
130
+ puts "Dropping #{drop_caps} #{ret ? 'done' : 'fail'}."
131
+ end
132
+ end
133
+
134
+ def get_capabilities(opts, target_file)
135
+ if opts[:get_capabilities]
136
+ @capng.caps_file(target_file)
137
+ print = CapNG::Print.new
138
+ puts "Capabilities in '#{target_file}',"
139
+ puts "Effective: #{print.caps_text(:buffer, :effective)}"
140
+ puts "Inheritable: #{print.caps_text(:buffer, :inheritable)}"
141
+ puts "Permitted: #{print.caps_text(:buffer, :permitted)}"
142
+ end
143
+ end
144
+
145
+ def get_valid_capabilities
146
+ capabilities = []
147
+ cap = CapNG::Capability.new
148
+ cap.each do |_code, capability|
149
+ capabilities << capability
150
+ end
151
+ capabilities
152
+ end
153
+
154
+ def check_capabilities(capabilities, valid_capabilities)
155
+ capabilities.each do |capability|
156
+ unless valid_capabilities.include?(capability)
157
+ raise ArgumentError, "'#{capability}' is not valid capability. Valid Capabilities are: #{valid_capabilities.join(", ")}"
158
+ end
159
+ end
160
+ end
161
+
162
+ def parse_options!(argv)
163
+ begin
164
+ rest = @op.parse(argv)
165
+
166
+ if rest.length != 0
167
+ usage nil
168
+ end
169
+ rescue
170
+ usage $!.to_s
171
+ end
172
+ end
173
+ end
174
+ end
@@ -28,4 +28,8 @@ module Fluent
28
28
  def self.windows?
29
29
  ServerEngine.windows?
30
30
  end
31
+
32
+ def self.linux?
33
+ /linux/ === RUBY_PLATFORM
34
+ end
31
35
  end
@@ -143,33 +143,14 @@ module Fluent
143
143
  end
144
144
  end
145
145
 
146
- # timekey should be unixtime as usual.
147
- # So, unixtime should be bigger than 2^30 - 1 (= 1073741823) nowadays.
148
- # We should check object_id stability to use object_id as optimization for comparing operations.
149
- # e.g.)
150
- # irb> Time.parse("2020/07/31 18:30:00+09:00").to_i
151
- # => 1596187800
152
- # irb> Time.parse("2020/07/31 18:30:00+09:00").to_i > 2**30 -1
153
- # => true
154
- def self.enable_optimize?
155
- a1 = 2**30 - 1
156
- a2 = 2**30 - 1
157
- b1 = 2**62 - 1
158
- b2 = 2**62 - 1
159
- (a1.object_id == a2.object_id) && (b1.object_id == b2.object_id)
160
- end
161
-
162
146
  # This is an optimization code. Current Struct's implementation is comparing all data.
163
147
  # https://github.com/ruby/ruby/blob/0623e2b7cc621b1733a760b72af246b06c30cf96/struct.c#L1200-L1203
164
148
  # Actually this overhead is very small but this class is generated *per chunk* (and used in hash object).
165
149
  # This means that this class is one of the most called object in Fluentd.
166
150
  # See https://github.com/fluent/fluentd/pull/2560
167
- # But, this optimization has a side effect on Windows and 32bit environment(s) due to differing object_id.
168
- # This difference causes flood of buffer files.
169
- # So, this optimization should be enabled on `enable_optimize?` as true platforms.
170
151
  def hash
171
- timekey.object_id
172
- end if enable_optimize?
152
+ timekey.hash
153
+ end
173
154
  end
174
155
 
175
156
  # for tests
@@ -63,9 +63,9 @@ module Fluent
63
63
  super
64
64
  @newline = case newline
65
65
  when :lf
66
- "\n"
66
+ "\n".freeze
67
67
  when :crlf
68
- "\r\n"
68
+ "\r\n".freeze
69
69
  end
70
70
  end
71
71
  end
@@ -27,7 +27,7 @@ module Fluent
27
27
  helpers :record_accessor
28
28
 
29
29
  config_param :delimiter, default: ',' do |val|
30
- ['\t', 'TAB'].include?(val) ? "\t" : val
30
+ ['\t', 'TAB'].include?(val) ? "\t".freeze : val.freeze
31
31
  end
32
32
  config_param :force_quotes, :bool, default: true
33
33
  # "array" looks good for type of :fields, but this implementation removes tailing comma
@@ -27,7 +27,7 @@ module Fluent
27
27
 
28
28
  def format(tag, time, record)
29
29
  line = record.to_s
30
- line << @newline.freeze if @add_newline
30
+ line << @newline if @add_newline
31
31
  line
32
32
  end
33
33
  end
@@ -25,8 +25,8 @@ module Fluent
25
25
 
26
26
  # http://ltsv.org/
27
27
 
28
- config_param :delimiter, :string, default: "\t"
29
- config_param :label_delimiter, :string, default: ":"
28
+ config_param :delimiter, :string, default: "\t".freeze
29
+ config_param :label_delimiter, :string, default: ":".freeze
30
30
  config_param :add_newline, :bool, default: true
31
31
 
32
32
  # TODO: escaping for \t in values
@@ -36,7 +36,7 @@ module Fluent
36
36
  formatted << @delimiter if formatted.length.nonzero?
37
37
  formatted << "#{label}#{@label_delimiter}#{value}"
38
38
  end
39
- formatted << @newline.freeze if @add_newline
39
+ formatted << @newline if @add_newline
40
40
  formatted
41
41
  end
42
42
  end
@@ -29,9 +29,9 @@ module Fluent
29
29
  config_param :output_tag, :bool, default: true
30
30
  config_param :delimiter, default: "\t" do |val|
31
31
  case val
32
- when /SPACE/i then ' '
33
- when /COMMA/i then ','
34
- else "\t"
32
+ when /SPACE/i then ' '.freeze
33
+ when /COMMA/i then ','.freeze
34
+ else "\t".freeze
35
35
  end
36
36
  end
37
37
  config_set_default :time_type, :string
@@ -23,12 +23,12 @@ module Fluent
23
23
 
24
24
  Plugin.register_formatter('single_value', self)
25
25
 
26
- config_param :message_key, :string, default: 'message'
26
+ config_param :message_key, :string, default: 'message'.freeze
27
27
  config_param :add_newline, :bool, default: true
28
28
 
29
29
  def format(tag, time, record)
30
30
  text = record[@message_key].to_s.dup
31
- text << @newline.freeze if @add_newline
31
+ text << @newline if @add_newline
32
32
  text
33
33
  end
34
34
  end
@@ -26,13 +26,13 @@ module Fluent
26
26
  desc 'Field names included in each lines'
27
27
  config_param :keys, :array, value_type: :string
28
28
  desc 'The delimiter character (or string) of TSV values'
29
- config_param :delimiter, :string, default: "\t"
29
+ config_param :delimiter, :string, default: "\t".freeze
30
30
  desc 'The parameter to enable writing to new lines'
31
31
  config_param :add_newline, :bool, default: true
32
32
 
33
33
  def format(tag, time, record)
34
34
  formatted = @keys.map{|k| record[k].to_s }.join(@delimiter)
35
- formatted << @newline.freeze if @add_newline
35
+ formatted << @newline if @add_newline
36
36
  formatted
37
37
  end
38
38
  end
@@ -22,6 +22,7 @@ require 'fluent/event'
22
22
  require 'fluent/plugin/buffer'
23
23
  require 'fluent/plugin/parser_multiline'
24
24
  require 'fluent/variable_store'
25
+ require 'fluent/capability'
25
26
  require 'fluent/plugin/in_tail/position_file'
26
27
 
27
28
  if Fluent.windows?
@@ -171,6 +172,7 @@ module Fluent::Plugin
171
172
  @dir_perm = system_config.dir_permission || Fluent::DEFAULT_DIR_PERMISSION
172
173
  # parser is already created by parser helper
173
174
  @parser = parser_create(usage: parser_config['usage'] || @parser_configs.first.usage)
175
+ @capability = Fluent::Capability.new(:current_process)
174
176
  end
175
177
 
176
178
  def configure_tag
@@ -250,6 +252,11 @@ module Fluent::Plugin
250
252
  close_watcher_handles
251
253
  end
252
254
 
255
+ def have_read_capability?
256
+ @capability.have_capability?(:effective, :dac_read_search) ||
257
+ @capability.have_capability?(:effective, :dac_override)
258
+ end
259
+
253
260
  def expand_paths
254
261
  date = Fluent::EventTime.now
255
262
  paths = []
@@ -263,7 +270,7 @@ module Fluent::Plugin
263
270
  paths += Dir.glob(path).select { |p|
264
271
  begin
265
272
  is_file = !File.directory?(p)
266
- if File.readable?(p) && is_file
273
+ if (File.readable?(p) || have_read_capability?) && is_file
267
274
  if @limit_recently_modified && File.mtime(p) < (date.to_time - @limit_recently_modified)
268
275
  false
269
276
  else
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '1.11.5'
19
+ VERSION = '1.12.0.rc1'
20
20
 
21
21
  end
@@ -0,0 +1,100 @@
1
+ require_relative '../helper'
2
+
3
+ require 'tempfile'
4
+ require 'fluent/command/cap_ctl'
5
+
6
+ class TestFluentCapCtl < Test::Unit::TestCase
7
+ setup do
8
+ omit "This environment does not handle Linux capability" unless defined?(CapNG)
9
+ end
10
+
11
+ sub_test_case "success" do
12
+ test "clear capability" do
13
+ logs = capture_stdout do
14
+ Fluent::CapCtl.new(["--clear"]).call
15
+ end
16
+ expression = /\AClear capabilities .*\n/m
17
+ assert_match expression, logs
18
+ end
19
+
20
+ test "add capability" do
21
+ logs = capture_stdout do
22
+ Fluent::CapCtl.new(["--add", "dac_override"]).call
23
+ end
24
+ expression = /\AUpdating .* done.\nAdding .*\n/m
25
+ assert_match expression, logs
26
+ end
27
+
28
+ test "drop capability" do
29
+ logs = capture_stdout do
30
+ Fluent::CapCtl.new(["--drop", "chown"]).call
31
+ end
32
+ expression = /\AUpdating .* done.\nDropping .*\n/m
33
+ assert_match expression, logs
34
+ end
35
+
36
+ test "get capability" do
37
+ logs = capture_stdout do
38
+ Fluent::CapCtl.new(["--get"]).call
39
+ end
40
+ expression = /\ACapabilities in .*,\nEffective: .*\nInheritable: .*\nPermitted: .*/m
41
+ assert_match expression, logs
42
+ end
43
+ end
44
+
45
+ sub_test_case "success with file" do
46
+ test "clear capability" do
47
+ logs = capture_stdout do
48
+ Tempfile.create("fluent-cap-") do |tempfile|
49
+ Fluent::CapCtl.new(["--clear-cap", "-f", tempfile.path]).call
50
+ end
51
+ end
52
+ expression = /\AClear capabilities .*\n/m
53
+ assert_match expression, logs
54
+ end
55
+
56
+ test "add capability" do
57
+ logs = capture_stdout do
58
+ Tempfile.create("fluent-cap-") do |tempfile|
59
+ Fluent::CapCtl.new(["--add", "dac_override", "-f", tempfile.path]).call
60
+ end
61
+ end
62
+ expression = /\AUpdating .* done.\nAdding .*\n/m
63
+ assert_match expression, logs
64
+ end
65
+
66
+ test "drop capability" do
67
+ logs = capture_stdout do
68
+ Tempfile.create("fluent-cap-") do |tempfile|
69
+ Fluent::CapCtl.new(["--drop", "chown", "-f", tempfile.path]).call
70
+ end
71
+ end
72
+ expression = /\AUpdating .* done.\nDropping .*\n/m
73
+ assert_match expression, logs
74
+ end
75
+
76
+ test "get capability" do
77
+ logs = capture_stdout do
78
+ Tempfile.create("fluent-cap-") do |tempfile|
79
+ Fluent::CapCtl.new(["--get", "-f", tempfile.path]).call
80
+ end
81
+ end
82
+ expression = /\ACapabilities in .*,\nEffective: .*\nInheritable: .*\nPermitted: .*/m
83
+ assert_match expression, logs
84
+ end
85
+ end
86
+
87
+ sub_test_case "invalid" do
88
+ test "add capability" do
89
+ assert_raise(ArgumentError) do
90
+ Fluent::CapCtl.new(["--add", "nonexitent"]).call
91
+ end
92
+ end
93
+
94
+ test "drop capability" do
95
+ assert_raise(ArgumentError) do
96
+ Fluent::CapCtl.new(["--drop", "invalid"]).call
97
+ end
98
+ end
99
+ end
100
+ end
@@ -86,6 +86,9 @@ class TailInputTest < Test::Unit::TestCase
86
86
  assert_equal "#{TMP_DIR}/tail.pos", d.instance.pos_file
87
87
  assert_equal 1000, d.instance.read_lines_limit
88
88
  assert_equal false, d.instance.ignore_repeated_permission_error
89
+ assert_nothing_raised do
90
+ d.instance.have_read_capability?
91
+ end
89
92
  end
90
93
 
91
94
  data("empty" => config_element,
@@ -229,7 +232,7 @@ class TailInputTest < Test::Unit::TestCase
229
232
  d = create_driver(config)
230
233
  msg = 'test' * 2000 # in_tail reads 8192 bytes at once.
231
234
 
232
- d.run(expect_emits: num_events, timeout: 1) do
235
+ d.run(expect_emits: num_events, timeout: 2) do
233
236
  File.open("#{TMP_DIR}/tail.txt", "ab") {|f|
234
237
  f.puts msg
235
238
  f.puts msg
@@ -1112,6 +1115,49 @@ class TailInputTest < Test::Unit::TestCase
1112
1115
  end
1113
1116
  end
1114
1117
 
1118
+ sub_test_case "path w/ Linux capability" do
1119
+ def capability_enabled?
1120
+ if Fluent.linux?
1121
+ begin
1122
+ require 'capng'
1123
+ true
1124
+ rescue LoadError
1125
+ false
1126
+ end
1127
+ else
1128
+ false
1129
+ end
1130
+ end
1131
+
1132
+ setup do
1133
+ omit "This environment is not enabled Linux capability handling feature" unless capability_enabled?
1134
+
1135
+ @capng = CapNG.new(:current_process)
1136
+ flexstub(Fluent::Capability) do |klass|
1137
+ klass.should_receive(:new).with(:current_process).and_return(@capng)
1138
+ end
1139
+ end
1140
+
1141
+ data("dac_read_search" => [:dac_read_search, true, 1],
1142
+ "dac_override" => [:dac_override, true, 1],
1143
+ "chown" => [:chown, false, 0],
1144
+ )
1145
+ test "with partially elevated privileges" do |data|
1146
+ cap, result, readable_paths = data
1147
+ @capng.update(:add, :effective, cap)
1148
+
1149
+ d = create_driver(
1150
+ config_element("ROOT", "", {
1151
+ "path" => "/var/log/ker*.log", # Use /var/log/kern.log
1152
+ "tag" => "t1",
1153
+ "rotate_wait" => "2s"
1154
+ }) + PARSE_SINGLE_LINE_CONFIG, false)
1155
+
1156
+ assert_equal readable_paths, d.instance.expand_paths.length
1157
+ assert_equal result, d.instance.have_read_capability?
1158
+ end
1159
+ end
1160
+
1115
1161
  def test_pos_file_dir_creation
1116
1162
  config = config_element("", "", {
1117
1163
  "tag" => "tail",
@@ -0,0 +1,74 @@
1
+ require_relative 'helper'
2
+ require 'fluent/test'
3
+ require 'fluent/capability'
4
+
5
+ class FluentCapabilityTest < ::Test::Unit::TestCase
6
+ setup do
7
+ @capability = Fluent::Capability.new(:current_process)
8
+ omit "Fluent::Capability class is not usable on this environment" unless @capability.usable?
9
+ end
10
+
11
+ sub_test_case "check capability" do
12
+ test "effective" do
13
+ @capability.clear(:both)
14
+ assert_true @capability.update(:add, :effective, :dac_read_search)
15
+ assert_equal CapNG::Result::PARTIAL, @capability.have_capabilities?(:caps)
16
+ assert_nothing_raised do
17
+ @capability.apply(:caps)
18
+ end
19
+ assert_equal CapNG::Result::NONE, @capability.have_capabilities?(:bounds)
20
+ assert_true @capability.have_capability?(:effective, :dac_read_search)
21
+ assert_false @capability.have_capability?(:inheritable, :dac_read_search)
22
+ assert_false @capability.have_capability?(:permitted, :dac_read_search)
23
+ end
24
+
25
+ test "inheritable" do
26
+ @capability.clear(:both)
27
+ capabilities = [:chown, :dac_override]
28
+ assert_equal [true, true], @capability.update(:add, :inheritable, capabilities)
29
+ assert_equal CapNG::Result::NONE, @capability.have_capabilities?(:caps)
30
+ assert_nothing_raised do
31
+ @capability.apply(:caps)
32
+ end
33
+ assert_equal CapNG::Result::NONE, @capability.have_capabilities?(:bounds)
34
+ capabilities.each do |capability|
35
+ assert_false @capability.have_capability?(:effective, capability)
36
+ assert_true @capability.have_capability?(:inheritable, capability)
37
+ assert_false @capability.have_capability?(:permitted, capability)
38
+ end
39
+ end
40
+
41
+ test "permitted" do
42
+ @capability.clear(:both)
43
+ capabilities = [:fowner, :fsetid, :kill]
44
+ assert_equal [true, true, true], @capability.update(:add, :permitted, capabilities)
45
+ assert_equal CapNG::Result::NONE, @capability.have_capabilities?(:caps)
46
+ assert_nothing_raised do
47
+ @capability.apply(:caps)
48
+ end
49
+ assert_equal CapNG::Result::NONE, @capability.have_capabilities?(:bounds)
50
+ capabilities.each do |capability|
51
+ assert_false @capability.have_capability?(:effective, capability)
52
+ assert_false @capability.have_capability?(:inheritable, capability)
53
+ assert_true @capability.have_capability?(:permitted, capability)
54
+ end
55
+ end
56
+
57
+ test "effective/inheritable/permitted" do
58
+ @capability.clear(:both)
59
+ capabilities = [:setpcap, :net_admin, :net_raw, :sys_boot, :sys_time]
60
+ update_type = CapNG::Type::EFFECTIVE | CapNG::Type::INHERITABLE | CapNG::Type::PERMITTED
61
+ assert_equal [true, true, true, true, true], @capability.update(:add, update_type, capabilities)
62
+ assert_equal CapNG::Result::PARTIAL, @capability.have_capabilities?(:caps)
63
+ assert_nothing_raised do
64
+ @capability.apply(:caps)
65
+ end
66
+ assert_equal CapNG::Result::NONE, @capability.have_capabilities?(:bounds)
67
+ capabilities.each do |capability|
68
+ assert_true @capability.have_capability?(:effective, capability)
69
+ assert_true @capability.have_capability?(:inheritable, capability)
70
+ assert_true @capability.have_capability?(:permitted, capability)
71
+ end
72
+ end
73
+ end
74
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluentd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.5
4
+ version: 1.12.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-06 00:00:00.000000000 Z
11
+ date: 2020-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: msgpack
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -345,6 +359,7 @@ email:
345
359
  executables:
346
360
  - fluent-binlog-reader
347
361
  - fluent-ca-generate
362
+ - fluent-cap-ctl
348
363
  - fluent-cat
349
364
  - fluent-debug
350
365
  - fluent-gem
@@ -359,6 +374,7 @@ files:
359
374
  - ".github/ISSUE_TEMPLATE/bug_report.md"
360
375
  - ".github/ISSUE_TEMPLATE/feature_request.md"
361
376
  - ".github/PULL_REQUEST_TEMPLATE.md"
377
+ - ".github/stale.yml"
362
378
  - ".github/workflows/issue-auto-closer.yml"
363
379
  - ".gitignore"
364
380
  - ".gitlab-ci.yml"
@@ -377,6 +393,7 @@ files:
377
393
  - appveyor.yml
378
394
  - bin/fluent-binlog-reader
379
395
  - bin/fluent-ca-generate
396
+ - bin/fluent-cap-ctl
380
397
  - bin/fluent-cat
381
398
  - bin/fluent-debug
382
399
  - bin/fluent-gem
@@ -425,10 +442,12 @@ files:
425
442
  - fluent.conf
426
443
  - fluentd.gemspec
427
444
  - lib/fluent/agent.rb
445
+ - lib/fluent/capability.rb
428
446
  - lib/fluent/clock.rb
429
447
  - lib/fluent/command/binlog_reader.rb
430
448
  - lib/fluent/command/bundler_injection.rb
431
449
  - lib/fluent/command/ca_generate.rb
450
+ - lib/fluent/command/cap_ctl.rb
432
451
  - lib/fluent/command/cat.rb
433
452
  - lib/fluent/command/debug.rb
434
453
  - lib/fluent/command/fluentd.rb
@@ -675,6 +694,7 @@ files:
675
694
  - templates/plugin_config_formatter/section.md.erb
676
695
  - test/command/test_binlog_reader.rb
677
696
  - test/command/test_ca_generate.rb
697
+ - test/command/test_cap_ctl.rb
678
698
  - test/command/test_fluentd.rb
679
699
  - test/command/test_plugin_config_formatter.rb
680
700
  - test/command/test_plugin_generator.rb
@@ -851,6 +871,7 @@ files:
851
871
  - test/scripts/fluent/plugin/out_test.rb
852
872
  - test/scripts/fluent/plugin/out_test2.rb
853
873
  - test/scripts/fluent/plugin/parser_known.rb
874
+ - test/test_capability.rb
854
875
  - test/test_clock.rb
855
876
  - test/test_config.rb
856
877
  - test/test_configdsl.rb
@@ -898,9 +919,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
898
919
  version: '2.4'
899
920
  required_rubygems_version: !ruby/object:Gem::Requirement
900
921
  requirements:
901
- - - ">="
922
+ - - ">"
902
923
  - !ruby/object:Gem::Version
903
- version: '0'
924
+ version: 1.3.1
904
925
  requirements: []
905
926
  rubygems_version: 3.0.3
906
927
  signing_key:
@@ -909,6 +930,7 @@ summary: Fluentd event collector
909
930
  test_files:
910
931
  - test/command/test_binlog_reader.rb
911
932
  - test/command/test_ca_generate.rb
933
+ - test/command/test_cap_ctl.rb
912
934
  - test/command/test_fluentd.rb
913
935
  - test/command/test_plugin_config_formatter.rb
914
936
  - test/command/test_plugin_generator.rb
@@ -1085,6 +1107,7 @@ test_files:
1085
1107
  - test/scripts/fluent/plugin/out_test.rb
1086
1108
  - test/scripts/fluent/plugin/out_test2.rb
1087
1109
  - test/scripts/fluent/plugin/parser_known.rb
1110
+ - test/test_capability.rb
1088
1111
  - test/test_clock.rb
1089
1112
  - test/test_config.rb
1090
1113
  - test/test_configdsl.rb