This file is indexed.

/usr/share/pcsd/fenceagent.rb is in pcs 0.9.149-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
def getFenceAgents(auth_user, fence_agent = nil)
  fence_agent_list = {}
  agents = Dir.glob('/usr/sbin/fence_' + '*')
  agents.each { |a|
    fa = FenceAgent.new
    fa.name =  a.sub(/.*\//,"")
    next if fa.name == "fence_ack_manual"

    if fence_agent and a.sub(/.*\//,"") == fence_agent.sub(/.*:/,"")
      required_options, optional_options, advanced_options, info = getFenceAgentMetadata(auth_user, fa.name)
      fa.required_options = required_options
      fa.optional_options = optional_options
      fa.advanced_options = advanced_options
      fa.info = info
    end
    fence_agent_list[fa.name] = fa
  }
  fence_agent_list
end

def getFenceAgentMetadata(auth_user, fenceagentname)
  options_required = {}
  options_optional = {}
  options_advanced = {
      "priority" => "",
      "pcmk_host_argument" => "",
      "pcmk_host_map" => "",
      "pcmk_host_list" => "",
      "pcmk_host_check" => ""
  }
  for a in ["reboot", "list", "status", "monitor", "off"]
    options_advanced["pcmk_" + a + "_action"] = ""
    options_advanced["pcmk_" + a + "_timeout"] = ""
    options_advanced["pcmk_" + a + "_retries"] = ""
  end

  # There are bugs in stonith_admin & the new fence_agents interaction
  # eventually we'll want to switch back to this, but for now we directly
  # call the agent to get metadata
  #metadata = `stonith_admin --metadata -a #{fenceagentname}`
  if not fenceagentname.start_with?('fence_') or fenceagentname.include?('/')
    $logger.error "Invalid fence agent '#{fenceagentname}'"
    return [options_required, options_optional, options_advanced]
  end
  stdout, stderr, retval = run_cmd(
    auth_user, "/usr/sbin/#{fenceagentname}", '-o', 'metadata'
  )
  metadata = stdout.join
  begin
    doc = REXML::Document.new(metadata)
  rescue REXML::ParseException => e
    $logger.error(
      "Unable to parse metadata of fence agent '#{resourcepath}': #{e}"
    )
    return [options_required, options_optional, options_advanced]
  end

  short_desc = ""
  long_desc = ""
  if doc.root
    short_desc = doc.root.attributes["shortdesc"]
  end
  if short_desc == ""
    doc.elements.each('resource-agent/shortdesc') {|sd|
      short_desc = sd.text ? sd.text.strip : sd.text
    }
  end
  doc.elements.each('resource-agent/longdesc') {|ld|
    long_desc = ld.text ? ld.text.strip : ld.text
  }

  doc.elements.each('resource-agent/parameters/parameter') { |param|
    temp_array = []
    if param.elements["shortdesc"]
      temp_array << param.elements["shortdesc"].text
    else
      temp_array << ""
    end
    if param.elements["longdesc"]
      temp_array << param.elements["longdesc"].text
    else
      temp_array << ""
    end
    if param.attributes["required"] == "1" and param.attributes["name"] != "action"
      options_required[param.attributes["name"]] = temp_array
    else
      options_optional[param.attributes["name"]] = temp_array
    end
  }
  [options_required, options_optional, options_advanced, [short_desc, long_desc]]
end

class FenceAgent
  attr_accessor :name, :resource_class, :required_options, :optional_options, :advanced_options, :info
  def initialize(name=nil, required_options={}, optional_options={}, resource_class=nil, advanced_options={})
    @name = name
    @required_options = {}
    @optional_options = {}
    @required_options = required_options
    @optional_options = optional_options
    @advanced_options = advanced_options
    @resource_class = nil
  end

  def type
    name
  end

  def to_json(options = {})
    JSON.generate({:type => name})
  end

  def long_desc
    if info && info.length >= 2
      return info[1]
    end
    return ""
  end

  def short_desc
    if info && info.length >= 1
      return info[0]
    end
    return ""
  end
end