class Fluent::CapCtl

Public Class Methods

new(argv = ARGV) click to toggle source
# 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

Public Instance Methods

add_capabilities(opts, target_file) click to toggle source
# 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
call() click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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_capabilities() click to toggle source
# 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) click to toggle source
# 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_parser() click to toggle source
# 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) click to toggle source
# File lib/fluent/command/cap_ctl.rb, line 48
def usage(msg)
  puts @op.to_s
  puts "error: #{msg}" if msg
  exit 1
end