Class: Fluent::CapCtl

Inherits:
Object
  • Object
show all
Defined in:
lib/fluent/command/cap_ctl.rb

Instance Method Summary collapse

Constructor Details

#initialize(argv = ARGV) ⇒ CapCtl

Returns a new instance of CapCtl.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/fluent/command/cap_ctl.rb', line 54

def initialize(argv = ARGV)
  @opts = {}
  @argv = argv

  if Fluent.linux?
    begin
      require 'capng'

      @capng = CapNG.new
    rescue LoadError
      puts "Error: capng_c is not loaded. Please install it first."
      exit 1
    end
  else
    puts "Error: This environment is not supported."
    exit 2
  end

  prepare_option_parser
end

Instance Method Details

#add_capabilities(opts, target_file) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/fluent/command/cap_ctl.rb', line 104

def add_capabilities(opts, target_file)
  if add_caps = opts[:add_capabilities]
    @capng.clear(:caps)
    @capng.caps_file(target_file)
    capabilities = add_caps.split(/\s*,\s*/)
    check_capabilities(capabilities, get_valid_capabilities)
    ret = @capng.update(:add,
                        CapNG::Type::EFFECTIVE | CapNG::Type::INHERITABLE | CapNG::Type::PERMITTED,
                        capabilities)
    puts "Updating #{add_caps} #{ret ? 'done' : 'fail'}."
    ret = @capng.apply_caps_file(target_file)
    puts "Adding #{add_caps} #{ret ? 'done' : 'fail'}."
  end
end

#callObject



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/fluent/command/cap_ctl.rb', line 75

def call
  parse_options!(@argv)

  target_file = if !!@opts[:target_file]
                  @opts[:target_file]
                else
                  File.readlink("/proc/self/exe")
                end

  if @opts[:clear_capabilities]
    clear_capabilities(@opts, target_file)
  elsif @opts[:add_capabilities]
    add_capabilities(@opts, target_file)
  elsif @opts[:drop_capabilities]
    drop_capabilities(@opts, target_file)
  end
  if @opts[:get_capabilities]
    get_capabilities(@opts, target_file)
  end
end

#check_capabilities(capabilities, valid_capabilities) ⇒ Object



154
155
156
157
158
159
160
# File 'lib/fluent/command/cap_ctl.rb', line 154

def check_capabilities(capabilities, valid_capabilities)
  capabilities.each do |capability|
    unless valid_capabilities.include?(capability)
      raise ArgumentError, "'#{capability}' is not valid capability. Valid Capabilities are:  #{valid_capabilities.join(", ")}"
    end
  end
end

#clear_capabilities(opts, target_file) ⇒ Object



96
97
98
99
100
101
102
# File 'lib/fluent/command/cap_ctl.rb', line 96

def clear_capabilities(opts, target_file)
  if !!opts[:clear_capabilities]
    @capng.clear(:caps)
    ret = @capng.apply_caps_file(target_file)
    puts "Clear capabilities #{ret ? 'done' : 'fail'}."
  end
end

#drop_capabilities(opts, target_file) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/fluent/command/cap_ctl.rb', line 119

def drop_capabilities(opts, target_file)
  if drop_caps = opts[:drop_capabilities]
    @capng.clear(:caps)
    @capng.caps_file(target_file)
    capabilities = drop_caps.split(/\s*,\s*/)
    check_capabilities(capabilities, get_valid_capabilities)
    ret = @capng.update(:drop,
                        CapNG::Type::EFFECTIVE | CapNG::Type::INHERITABLE | CapNG::Type::PERMITTED,
                        capabilities)
    puts "Updating #{drop_caps} #{ret ? 'done' : 'fail'}."
    @capng.apply_caps_file(target_file)
    puts "Dropping #{drop_caps} #{ret ? 'done' : 'fail'}."
  end
end

#get_capabilities(opts, target_file) ⇒ Object



134
135
136
137
138
139
140
141
142
143
# File 'lib/fluent/command/cap_ctl.rb', line 134

def get_capabilities(opts, target_file)
  if opts[:get_capabilities]
    @capng.caps_file(target_file)
    print = CapNG::Print.new
    puts "Capabilities in '#{target_file}',"
    puts "Effective:   #{print.caps_text(:buffer, :effective)}"
    puts "Inheritable: #{print.caps_text(:buffer, :inheritable)}"
    puts "Permitted:   #{print.caps_text(:buffer, :permitted)}"
  end
end

#get_valid_capabilitiesObject



145
146
147
148
149
150
151
152
# File 'lib/fluent/command/cap_ctl.rb', line 145

def get_valid_capabilities
  capabilities = []
  cap = CapNG::Capability.new
  cap.each do |_code, capability|
    capabilities << capability
  end
  capabilities
end

#parse_options!(argv) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
# File 'lib/fluent/command/cap_ctl.rb', line 162

def parse_options!(argv)
  begin
    rest = @op.parse(argv)

    if rest.length != 0
      usage nil
    end
  rescue
    usage $!.to_s
  end
end

#prepare_option_parserObject



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/fluent/command/cap_ctl.rb', line 24

def prepare_option_parser
  @op = OptionParser.new

  @op.on('--clear', "Clear Fluentd Ruby capability") {|s|
    @opts[:clear_capabilities] = true
  }

  @op.on('--add [CAPABILITITY1,CAPABILITY2, ...]', "Add capabilities into Fluentd Ruby") {|s|
    @opts[:add_capabilities] = s
  }

  @op.on('--drop [CAPABILITITY1,CAPABILITY2, ...]', "Drop capabilities from Fluentd Ruby") {|s|
    @opts[:drop_capabilities] = s
  }

  @op.on('--get', "Get capabilities for Fluentd Ruby") {|s|
    @opts[:get_capabilities] = true
  }

  @op.on('-f', '--file FILE', "Specify target file to add Linux capabilities") {|s|
    @opts[:target_file] = s
  }
end

#usage(msg) ⇒ Object



48
49
50
51
52
# File 'lib/fluent/command/cap_ctl.rb', line 48

def usage(msg)
  puts @op.to_s
  puts "error: #{msg}" if msg
  exit 1
end