facter 1.6.18 → 1.7.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 facter might be problematic. Click here for more details.

Files changed (126) hide show
  1. data/Gemfile +23 -8
  2. data/bin/facter +4 -1
  3. data/ext/build_defaults.yaml +1 -1
  4. data/ext/debian/changelog.erb +4 -22
  5. data/ext/debian/control +2 -2
  6. data/ext/project_data.yaml +1 -1
  7. data/ext/redhat/facter.spec.erb +10 -9
  8. data/install.rb +27 -53
  9. data/lib/facter.rb +23 -5
  10. data/lib/facter/application.rb +21 -0
  11. data/lib/facter/blockdevices.rb +105 -0
  12. data/lib/facter/domain.rb +19 -7
  13. data/lib/facter/filesystems.rb +38 -0
  14. data/lib/facter/hardwaremodel.rb +3 -2
  15. data/lib/facter/ipaddress6.rb +1 -2
  16. data/lib/facter/kernelrelease.rb +10 -2
  17. data/lib/facter/ldom.rb +47 -0
  18. data/lib/facter/macaddress.rb +1 -1
  19. data/lib/facter/manufacturer.rb +7 -1
  20. data/lib/facter/memory.rb +58 -160
  21. data/lib/facter/operatingsystem.rb +17 -2
  22. data/lib/facter/operatingsystemmajrelease.rb +33 -0
  23. data/lib/facter/operatingsystemrelease.rb +88 -37
  24. data/lib/facter/osfamily.rb +6 -2
  25. data/lib/facter/processor.rb +2 -2
  26. data/lib/facter/ps.rb +5 -0
  27. data/lib/facter/ssh.rb +50 -12
  28. data/lib/facter/util/cfpropertylist.rb +6 -0
  29. data/lib/facter/util/cfpropertylist/LICENSE +19 -0
  30. data/lib/facter/util/cfpropertylist/README +44 -0
  31. data/lib/facter/util/cfpropertylist/Rakefile +44 -0
  32. data/lib/facter/util/cfpropertylist/THANKS +7 -0
  33. data/lib/facter/util/cfpropertylist/lib/cfpropertylist.rb +6 -0
  34. data/lib/facter/util/cfpropertylist/lib/rbBinaryCFPropertyList.rb +562 -0
  35. data/lib/facter/util/cfpropertylist/lib/rbCFPlistError.rb +26 -0
  36. data/lib/facter/util/cfpropertylist/lib/rbCFPropertyList.rb +402 -0
  37. data/lib/facter/util/cfpropertylist/lib/rbCFTypes.rb +244 -0
  38. data/lib/facter/util/cfpropertylist/lib/rbLibXMLParser.rb +135 -0
  39. data/lib/facter/util/cfpropertylist/lib/rbNokogiriParser.rb +140 -0
  40. data/lib/facter/util/cfpropertylist/lib/rbREXMLParser.rb +136 -0
  41. data/lib/facter/util/collection.rb +36 -14
  42. data/lib/facter/util/composite_loader.rb +12 -0
  43. data/lib/facter/util/config.rb +36 -0
  44. data/lib/facter/util/confine.rb +1 -6
  45. data/lib/facter/util/directory_loader.rb +83 -0
  46. data/lib/facter/util/fact.rb +49 -42
  47. data/lib/facter/util/file_read.rb +32 -0
  48. data/lib/facter/util/ip.rb +2 -9
  49. data/lib/facter/util/loader.rb +16 -2
  50. data/lib/facter/util/macosx.rb +15 -2
  51. data/lib/facter/util/memory.rb +154 -27
  52. data/lib/facter/util/nothing_loader.rb +15 -0
  53. data/lib/facter/util/parser.rb +141 -0
  54. data/lib/facter/util/processor.rb +27 -35
  55. data/lib/facter/util/resolution.rb +97 -26
  56. data/lib/facter/util/solaris_zones.rb +153 -0
  57. data/lib/facter/util/virtual.rb +32 -3
  58. data/lib/facter/version.rb +72 -2
  59. data/lib/facter/virtual.rb +56 -3
  60. data/lib/facter/zfs_version.rb +10 -0
  61. data/lib/facter/zonename.rb +6 -0
  62. data/lib/facter/zones.rb +17 -0
  63. data/lib/facter/zpool_version.rb +10 -0
  64. data/spec/fixtures/ifconfig/ifconfig_net_tools_1.60.txt +19 -0
  65. data/spec/fixtures/ifconfig/ifconfig_ubuntu_1204.txt +16 -0
  66. data/spec/fixtures/ldom/ldom_v1 +6 -0
  67. data/spec/fixtures/unit/filesystems/linux +28 -0
  68. data/spec/fixtures/unit/util/manufacturer/intel_linux_dmidecode +549 -0
  69. data/spec/fixtures/unit/virtual/sysfs_dmi_entries_raw.txt +0 -0
  70. data/spec/fixtures/unit/zfs_version/freebsd_8.2 +14 -0
  71. data/spec/fixtures/unit/zfs_version/freebsd_9.0 +13 -0
  72. data/spec/fixtures/unit/zfs_version/linux-fuse_0.6.9 +14 -0
  73. data/spec/fixtures/unit/zfs_version/solaris_10 +10 -0
  74. data/spec/fixtures/unit/zfs_version/solaris_11 +12 -0
  75. data/spec/fixtures/unit/zpool_version/freebsd_8.2 +26 -0
  76. data/spec/fixtures/unit/zpool_version/freebsd_9.0 +38 -0
  77. data/spec/fixtures/unit/zpool_version/linux-fuse_0.6.9 +35 -0
  78. data/spec/fixtures/unit/zpool_version/solaris_10 +31 -0
  79. data/spec/fixtures/unit/zpool_version/solaris_11 +43 -0
  80. data/spec/integration/facter_spec.rb +12 -0
  81. data/spec/spec_helper.rb +9 -0
  82. data/spec/unit/architecture_spec.rb +1 -1
  83. data/spec/unit/blockdevices_spec.rb +109 -0
  84. data/spec/unit/domain_spec.rb +189 -81
  85. data/spec/unit/ec2_spec.rb +15 -8
  86. data/spec/unit/filesystems_spec.rb +50 -0
  87. data/spec/unit/hardwaremodel_spec.rb +8 -1
  88. data/spec/unit/id_spec.rb +6 -5
  89. data/spec/unit/ipaddress6_spec.rb +14 -2
  90. data/spec/unit/ipaddress_spec.rb +1 -1
  91. data/spec/unit/kernel_spec.rb +24 -0
  92. data/spec/unit/kernelmajversion_spec.rb +17 -0
  93. data/spec/unit/kernelrelease_spec.rb +53 -0
  94. data/spec/unit/kernelversion_spec.rb +32 -0
  95. data/spec/unit/ldom_spec.rb +74 -0
  96. data/spec/unit/macaddress_spec.rb +3 -1
  97. data/spec/unit/manufacturer_spec.rb +115 -0
  98. data/spec/unit/memory_spec.rb +442 -75
  99. data/spec/unit/operatingsystem_spec.rb +16 -2
  100. data/spec/unit/operatingsystemmajrelease_spec.rb +16 -0
  101. data/spec/unit/operatingsystemrelease_spec.rb +110 -1
  102. data/spec/unit/processor_spec.rb +22 -7
  103. data/spec/unit/ps_spec.rb +42 -0
  104. data/spec/unit/ssh_spec.rb +76 -0
  105. data/spec/unit/util/collection_spec.rb +94 -118
  106. data/spec/unit/util/config_spec.rb +36 -5
  107. data/spec/unit/util/confine_spec.rb +31 -43
  108. data/spec/unit/util/directory_loader_spec.rb +87 -0
  109. data/spec/unit/util/fact_spec.rb +37 -25
  110. data/spec/unit/util/file_read_spec.rb +29 -0
  111. data/spec/unit/util/ip_spec.rb +4 -2
  112. data/spec/unit/util/loader_spec.rb +102 -45
  113. data/spec/unit/util/macosx_spec.rb +40 -9
  114. data/spec/unit/util/manufacturer_spec.rb +12 -1
  115. data/spec/unit/util/parser_spec.rb +135 -0
  116. data/spec/unit/util/resolution_spec.rb +136 -4
  117. data/spec/unit/util/solaris_zones_spec.rb +127 -0
  118. data/spec/unit/util/virtual_spec.rb +54 -0
  119. data/spec/unit/version_spec.rb +42 -0
  120. data/spec/unit/virtual_spec.rb +102 -27
  121. data/spec/unit/zfs_version_spec.rb +76 -0
  122. data/spec/unit/zonename_spec.rb +14 -0
  123. data/spec/unit/zones_spec.rb +55 -0
  124. data/spec/unit/zpool_version_spec.rb +76 -0
  125. metadata +113 -11
  126. data/lib/facter/arp.rb +0 -28
@@ -0,0 +1,135 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'libxml'
4
+
5
+ module Facter::Util::CFPropertyList
6
+ # XML parser
7
+ class XML < XMLParserInterface
8
+ # read a XML file
9
+ # opts::
10
+ # * :file - The filename of the file to load
11
+ # * :data - The data to parse
12
+ def load(opts)
13
+ if(opts.has_key?(:file)) then
14
+ doc = LibXML::XML::Document.file(opts[:file],:options => LibXML::XML::Parser::Options::NOBLANKS|LibXML::XML::Parser::Options::NOENT)
15
+ else
16
+ doc = LibXML::XML::Document.string(opts[:data],:options => LibXML::XML::Parser::Options::NOBLANKS|LibXML::XML::Parser::Options::NOENT)
17
+ end
18
+
19
+ root = doc.root.first
20
+ return import_xml(root)
21
+ end
22
+
23
+ # serialize Facter::Util::CFPropertyList object to XML
24
+ # opts = {}:: Specify options: :formatted - Use indention and line breaks
25
+ def to_str(opts={})
26
+ doc = LibXML::XML::Document.new
27
+
28
+ doc.root = LibXML::XML::Node.new('plist')
29
+ doc.encoding = LibXML::XML::Encoding::UTF_8
30
+
31
+ doc.root['version'] = '1.0'
32
+ doc.root << opts[:root].to_xml(self)
33
+
34
+ # ugly hack, but there's no other possibility I know
35
+ str = doc.to_s(:indent => opts[:formatted])
36
+ str1 = String.new
37
+ first = false
38
+ str.each_line do |line|
39
+ str1 << line
40
+ unless(first) then
41
+ str1 << "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" if line =~ /^\s*<\?xml/
42
+ end
43
+
44
+ first = true
45
+ end
46
+
47
+ str1.force_encoding('UTF-8') if str1.respond_to?(:force_encoding)
48
+ return str1
49
+ end
50
+
51
+ def new_node(name)
52
+ LibXML::XML::Node.new(name)
53
+ end
54
+
55
+ def new_text(val)
56
+ LibXML::XML::Node.new_text(val)
57
+ end
58
+
59
+ def append_node(parent, child)
60
+ parent << child
61
+ end
62
+
63
+ protected
64
+
65
+ # get the value of a DOM node
66
+ def get_value(n)
67
+ content = if n.children?
68
+ n.first.content
69
+ else
70
+ n.content
71
+ end
72
+
73
+ content.force_encoding('UTF-8') if content.respond_to?(:force_encoding)
74
+ content
75
+ end
76
+
77
+ # import the XML values
78
+ def import_xml(node)
79
+ ret = nil
80
+
81
+ case node.name
82
+ when 'dict'
83
+ hsh = Hash.new
84
+ key = nil
85
+
86
+ if node.children? then
87
+ node.children.each do |n|
88
+ next if n.text? # avoid a bug of libxml
89
+ next if n.comment?
90
+
91
+ if n.name == "key" then
92
+ key = get_value(n)
93
+ else
94
+ raise CFFormatError.new("Format error!") if key.nil?
95
+ hsh[key] = import_xml(n)
96
+ key = nil
97
+ end
98
+ end
99
+ end
100
+
101
+ ret = CFDictionary.new(hsh)
102
+
103
+ when 'array'
104
+ ary = Array.new
105
+
106
+ if node.children? then
107
+ node.children.each do |n|
108
+ ary.push import_xml(n)
109
+ end
110
+ end
111
+
112
+ ret = CFArray.new(ary)
113
+
114
+ when 'true'
115
+ ret = CFBoolean.new(true)
116
+ when 'false'
117
+ ret = CFBoolean.new(false)
118
+ when 'real'
119
+ ret = CFReal.new(get_value(node).to_f)
120
+ when 'integer'
121
+ ret = CFInteger.new(get_value(node).to_i)
122
+ when 'string'
123
+ ret = CFString.new(get_value(node))
124
+ when 'data'
125
+ ret = CFData.new(get_value(node))
126
+ when 'date'
127
+ ret = CFDate.new(CFDate.parse_date(get_value(node)))
128
+ end
129
+
130
+ return ret
131
+ end
132
+ end
133
+ end
134
+
135
+ # eof
@@ -0,0 +1,140 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'nokogiri'
4
+
5
+ module Facter::Util::CFPropertyList
6
+ # XML parser
7
+ class XML < ParserInterface
8
+ # read a XML file
9
+ # opts::
10
+ # * :file - The filename of the file to load
11
+ # * :data - The data to parse
12
+ def load(opts)
13
+ if(opts.has_key?(:file)) then
14
+ File.open(opts[:file], "rb") { |fd| doc = Nokogiri::XML::Document.parse(fd, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS|Nokogiri::XML::ParseOptions::NOENT) }
15
+ else
16
+ doc = Nokogiri::XML::Document.parse(opts[:data], nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS|Nokogiri::XML::ParseOptions::NOENT)
17
+ end
18
+
19
+ root = doc.root.children.first
20
+ return import_xml(root)
21
+ end
22
+
23
+ # serialize Facter::Util::CFPropertyList object to XML
24
+ # opts = {}:: Specify options: :formatted - Use indention and line breaks
25
+ def to_str(opts={})
26
+ doc = Nokogiri::XML::Document.new
27
+ @doc = doc
28
+
29
+ doc.root = doc.create_element 'plist', :version => '1.0'
30
+ doc.encoding = 'UTF-8'
31
+
32
+ doc.root << opts[:root].to_xml(self)
33
+
34
+ # ugly hack, but there's no other possibility I know
35
+ s_opts = Nokogiri::XML::Node::SaveOptions::AS_XML
36
+ s_opts |= Nokogiri::XML::Node::SaveOptions::FORMAT if opts[:formatted]
37
+
38
+ str = doc.serialize(:save_with => s_opts)
39
+ str1 = String.new
40
+ first = false
41
+ str.each_line do |line|
42
+ str1 << line
43
+ unless(first) then
44
+ str1 << "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" if line =~ /^\s*<\?xml/
45
+ end
46
+
47
+ first = true
48
+ end
49
+
50
+ str1.force_encoding('UTF-8') if str1.respond_to?(:force_encoding)
51
+ return str1
52
+ end
53
+
54
+ def new_node(name)
55
+ @doc.create_element name
56
+ end
57
+
58
+ def new_text(val)
59
+ @doc.create_text_node val
60
+ end
61
+
62
+ def append_node(parent, child)
63
+ parent << child
64
+ end
65
+
66
+ protected
67
+
68
+ # get the value of a DOM node
69
+ def get_value(n)
70
+ content = if n.children.empty?
71
+ n.content
72
+ else
73
+ n.children.first.content
74
+ end
75
+
76
+ content.force_encoding('UTF-8') if content.respond_to?(:force_encoding)
77
+ content
78
+ end
79
+
80
+ # import the XML values
81
+ def import_xml(node)
82
+ ret = nil
83
+
84
+ case node.name
85
+ when 'dict'
86
+ hsh = Hash.new
87
+ key = nil
88
+ children = node.children
89
+
90
+ unless children.empty? then
91
+ children.each do |n|
92
+ next if n.text? # avoid a bug of libxml
93
+ next if n.comment?
94
+
95
+ if n.name == "key" then
96
+ key = get_value(n)
97
+ else
98
+ raise CFFormatError.new("Format error!") if key.nil?
99
+ hsh[key] = import_xml(n)
100
+ key = nil
101
+ end
102
+ end
103
+ end
104
+
105
+ ret = CFDictionary.new(hsh)
106
+
107
+ when 'array'
108
+ ary = Array.new
109
+ children = node.children
110
+
111
+ unless children.empty? then
112
+ children.each do |n|
113
+ ary.push import_xml(n)
114
+ end
115
+ end
116
+
117
+ ret = CFArray.new(ary)
118
+
119
+ when 'true'
120
+ ret = CFBoolean.new(true)
121
+ when 'false'
122
+ ret = CFBoolean.new(false)
123
+ when 'real'
124
+ ret = CFReal.new(get_value(node).to_f)
125
+ when 'integer'
126
+ ret = CFInteger.new(get_value(node).to_i)
127
+ when 'string'
128
+ ret = CFString.new(get_value(node))
129
+ when 'data'
130
+ ret = CFData.new(get_value(node))
131
+ when 'date'
132
+ ret = CFDate.new(CFDate.parse_date(get_value(node)))
133
+ end
134
+
135
+ return ret
136
+ end
137
+ end
138
+ end
139
+
140
+ # eof
@@ -0,0 +1,136 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'rexml/document'
4
+
5
+ module Facter::Util::CFPropertyList
6
+ # XML parser
7
+ class XML < ParserInterface
8
+ # read a XML file
9
+ # opts::
10
+ # * :file - The filename of the file to load
11
+ # * :data - The data to parse
12
+ def load(opts)
13
+ if(opts.has_key?(:file)) then
14
+ File.open(opts[:file], "rb") { |fd| doc = REXML::Document.new(fd) }
15
+ else
16
+ doc = REXML::Document.new(opts[:data])
17
+ end
18
+
19
+ root = doc.root.elements[1]
20
+ return import_xml(root)
21
+ end
22
+
23
+ # serialize Facter::Util::CFPropertyList object to XML
24
+ # opts = {}:: Specify options: :formatted - Use indention and line breaks
25
+ def to_str(opts={})
26
+ doc = REXML::Document.new
27
+ @doc = doc
28
+
29
+ doc.context[:attribute_quote] = :quote
30
+
31
+ doc.add_element 'plist', {'version' => '1.0'}
32
+ doc.root << opts[:root].to_xml(self)
33
+
34
+ formatter = if opts[:formatted] then
35
+ f = REXML::Formatters::Pretty.new(2)
36
+ f.compact = true
37
+ f
38
+ else
39
+ REXML::Formatters::Default.new
40
+ end
41
+
42
+ str = formatter.write(doc.root, "")
43
+ str1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" + str + "\n"
44
+ str1.force_encoding('UTF-8') if str1.respond_to?(:force_encoding)
45
+
46
+ return str1
47
+ end
48
+
49
+ def new_node(name)
50
+ #LibXML::XML::Node.new(name)
51
+ REXML::Element.new(name)
52
+ end
53
+
54
+ def new_text(val)
55
+ val
56
+ end
57
+
58
+ def append_node(parent, child)
59
+ if child.is_a?(String) then
60
+ parent.add_text child
61
+ else
62
+ parent.elements << child
63
+ end
64
+ parent
65
+ end
66
+
67
+ protected
68
+
69
+ # get the value of a DOM node
70
+ def get_value(n)
71
+ content = n.text
72
+
73
+ content.force_encoding('UTF-8') if content.respond_to?(:force_encoding)
74
+ content
75
+ end
76
+
77
+ # import the XML values
78
+ def import_xml(node)
79
+ ret = nil
80
+
81
+ case node.name
82
+ when 'dict'
83
+ hsh = Hash.new
84
+ key = nil
85
+
86
+ if node.has_elements? then
87
+ node.elements.each do |n|
88
+ #print n.name + "\n"
89
+ next if n.name == '#text' # avoid a bug of libxml
90
+ next if n.name == '#comment'
91
+
92
+ if n.name == "key" then
93
+ key = get_value(n)
94
+ else
95
+ raise CFFormatError.new("Format error!") if key.nil?
96
+ hsh[key] = import_xml(n)
97
+ key = nil
98
+ end
99
+ end
100
+ end
101
+
102
+ ret = CFDictionary.new(hsh)
103
+
104
+ when 'array'
105
+ ary = Array.new
106
+
107
+ if node.has_elements? then
108
+ node.elements.each do |n|
109
+ ary.push import_xml(n)
110
+ end
111
+ end
112
+
113
+ ret = CFArray.new(ary)
114
+
115
+ when 'true'
116
+ ret = CFBoolean.new(true)
117
+ when 'false'
118
+ ret = CFBoolean.new(false)
119
+ when 'real'
120
+ ret = CFReal.new(get_value(node).to_f)
121
+ when 'integer'
122
+ ret = CFInteger.new(get_value(node).to_i)
123
+ when 'string'
124
+ ret = CFString.new(get_value(node))
125
+ when 'data'
126
+ ret = CFData.new(get_value(node))
127
+ when 'date'
128
+ ret = CFDate.new(CFDate.parse_date(get_value(node)))
129
+ end
130
+
131
+ return ret
132
+ end
133
+ end
134
+ end
135
+
136
+ # eof
@@ -5,6 +5,13 @@ require 'facter/util/loader'
5
5
  # Manage which facts exist and how we access them. Largely just a wrapper
6
6
  # around a hash of facts.
7
7
  class Facter::Util::Collection
8
+
9
+ def initialize(internal_loader, external_loader)
10
+ @facts = Hash.new
11
+ @internal_loader = internal_loader
12
+ @external_loader = external_loader
13
+ end
14
+
8
15
  # Return a fact object by name. If you use this, you still have to call
9
16
  # 'value' on it to retrieve the actual value.
10
17
  def [](name)
@@ -31,7 +38,14 @@ class Facter::Util::Collection
31
38
  end
32
39
  end
33
40
 
34
- if block_given? and resolve = fact.add(&block)
41
+ if block_given?
42
+ resolve = fact.add(&block)
43
+ else
44
+ resolve = fact.add
45
+ end
46
+
47
+ # Set any resolve-appropriate options
48
+ if resolve
35
49
  # If the resolve was actually added, set any resolve-appropriate options
36
50
  options.each do |opt, value|
37
51
  method = opt.to_s + "="
@@ -53,6 +67,7 @@ class Facter::Util::Collection
53
67
 
54
68
  # Iterate across all of the facts.
55
69
  def each
70
+ load_all
56
71
  @facts.each do |name, fact|
57
72
  value = fact.value
58
73
  unless value.nil?
@@ -66,10 +81,14 @@ class Facter::Util::Collection
66
81
  name = canonize(name)
67
82
 
68
83
  # Try to load the fact if necessary
69
- loader.load(name) unless @facts[name]
84
+ load(name) unless @facts[name]
70
85
 
71
86
  # Try HARDER
72
- loader.load_all unless @facts[name]
87
+ internal_loader.load_all unless @facts[name]
88
+
89
+ if @facts.empty?
90
+ Facter.warnonce("No facts loaded from #{internal_loader.search_path.join(File::PATH_SEPARATOR)}")
91
+ end
73
92
 
74
93
  @facts[name]
75
94
  end
@@ -79,26 +98,29 @@ class Facter::Util::Collection
79
98
  @facts.each { |name, fact| fact.flush }
80
99
  end
81
100
 
82
- def initialize
83
- @facts = Hash.new
84
- end
85
-
86
101
  # Return a list of all of the facts.
87
102
  def list
103
+ load_all
88
104
  return @facts.keys
89
105
  end
90
106
 
107
+ def load(name)
108
+ internal_loader.load(name)
109
+ external_loader.load(self)
110
+ end
111
+
91
112
  # Load all known facts.
92
113
  def load_all
93
- loader.load_all
114
+ internal_loader.load_all
115
+ external_loader.load(self)
94
116
  end
95
117
 
96
- # The thing that loads facts if we don't have them.
97
- def loader
98
- unless defined?(@loader)
99
- @loader = Facter::Util::Loader.new
100
- end
101
- @loader
118
+ def internal_loader
119
+ @internal_loader
120
+ end
121
+
122
+ def external_loader
123
+ @external_loader
102
124
  end
103
125
 
104
126
  # Return a hash of all of our facts.