Skip to content
This repository has been archived by the owner on Jun 19, 2020. It is now read-only.

Commit

Permalink
Merge branch 'master' into FACT-2569
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrei Filipovici committed May 6, 2020
2 parents 3ffb366 + a6d662d commit c0219bd
Show file tree
Hide file tree
Showing 23 changed files with 281 additions and 69 deletions.
9 changes: 8 additions & 1 deletion lib/custom_facts/core/execution.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,14 @@ def which(bin)
# @param path [String] the path to check
# @param platform [:posix,:windows,nil] the platform logic to use
def absolute_path?(path, platform = nil)
@@impl.absolute_path?(path, platform)
case platform
when :posix
Facter::Core::Execution::Posix.new.absolute_path?(path)
when :windows
Facter::Core::Execution::Windows.new.absolute_path?(path)
else
@@impl.absolute_path?(path)
end
end

# Given a command line, this returns the command line with the
Expand Down
27 changes: 17 additions & 10 deletions lib/facter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ class ResolveCustomFactError < StandardError; end

Options.init
Log.add_legacy_logger(STDOUT)
@logger = Log.new(self)
@already_searched = {}
@trace = false

class << self
def clear_messages
@logger.debug('clear_messages is not implemented')
logger.debug('clear_messages is not implemented')
end

# Alias method for Facter.fact()
Expand Down Expand Up @@ -80,7 +79,7 @@ def core_value(user_query)
def debug(msg)
return unless debugging?

@logger.debug(msg)
logger.debug(msg)
nil
end

Expand Down Expand Up @@ -239,9 +238,8 @@ def version
#
# @api private
def to_user_output(cli_options, *args)
cli_options = cli_options.map { |(k, v)| [k.to_sym, v] }.to_h
Facter::Options.init_from_cli(cli_options, args)
@logger.info("executed with command line: #{ARGV.drop(1).join(' ')}")
init_cli_options(cli_options)
logger.info("executed with command line: #{ARGV.drop(1).join(' ')}")
log_blocked_facts

resolved_facts = Facter::FactManager.instance.resolve_facts(args)
Expand All @@ -265,11 +263,20 @@ def log_exception(exception, message = :default)
arr.concat(exception.backtrace)
end

@logger.error(arr.flatten.join("\n"))
logger.error(arr.flatten.join("\n"))
end

private

def logger
@logger ||= Log.new(self)
end

def init_cli_options(options)
options = options.map { |(k, v)| [k.to_sym, v] }.to_h
Facter::Options.init_from_cli(options, args)
end

def add_fact_to_searched_facts(user_query, value)
@already_searched[user_query] ||= ResolvedFact.new(user_query, value)
@already_searched[user_query].value = value
Expand Down Expand Up @@ -327,7 +334,7 @@ def log_blocked_facts
block_list = Facter::FactGroups.new(Facter::Options[:config]).block_list
return unless block_list.any? && Facter::Options[:block]

@logger.debug("blocking collection of #{block_list.join("\s")} facts")
logger.debug("blocking collection of #{block_list.join("\s")} facts")
end

# Used for printing errors regarding CLI user input validation
Expand All @@ -340,7 +347,7 @@ def log_blocked_facts
# @api private
def log_errors(missing_names)
missing_names.each do |missing_name|
@logger.error("fact \"#{missing_name}\" does not exist.", true)
logger.error("fact \"#{missing_name}\" does not exist.", true)
end
end

Expand All @@ -354,7 +361,7 @@ def log_errors(missing_names)
#
# @api private
def method_missing(name, *args, &block)
@logger.error(
logger.error(
"--#{name}-- not implemented but required \n" \
'with params: ' \
"#{args.inspect} \n" \
Expand Down
43 changes: 43 additions & 0 deletions lib/facts/freebsd/os/release.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

module Facts
module Freebsd
module Os
class Release
FACT_NAME = 'os.release'
ALIASES = %w[operatingsystemmajrelease operatingsystemrelease].freeze

def call_the_resolver
installed_userland = Facter::Resolvers::Freebsd::FreebsdVersion.resolve(:installed_userland)

return Facter::ResolvedFact.new(FACT_NAME, nil) if !installed_userland || installed_userland.empty?

value = build_release_hash_from_version(installed_userland)

[Facter::ResolvedFact.new(FACT_NAME, value),
Facter::ResolvedFact.new(ALIASES.first, value[:major], :legacy),
Facter::ResolvedFact.new(ALIASES.last, installed_userland, :legacy)]
end

private

def build_release_hash_from_version(version_string)
version, branch_value = version_string.split('-', 2)
major_value, minor_value = version.split('.')
patchlevel_value = branch_value.split('-p')[1]

value = {
full: version_string,
major: major_value,
branch: branch_value
}

value[:minor] = minor_value if minor_value
value[:patchlevel] = patchlevel_value if patchlevel_value

value
end
end
end
end
end
4 changes: 2 additions & 2 deletions lib/framework/core/fact_loaders/internal_fact_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ def legacy_facts
@facts.select { |fact| fact.type == :legacy }
end

def initialize
def initialize(os_descendents = nil)
@facts = []

os_descendents = OsDetector.instance.hierarchy
os_descendents ||= OsDetector.instance.hierarchy
load_all_oses_in_descending_order(os_descendents)
end

Expand Down
2 changes: 2 additions & 0 deletions lib/framework/detector/os_detector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ def detect
:macosx
when /linux/
detect_distro
when /freebsd/
:freebsd
when /bsd/
:bsd
when /solaris/
Expand Down
39 changes: 39 additions & 0 deletions lib/resolvers/freebsd/freebsd_version_resolver.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

module Facter
module Resolvers
module Freebsd
class FreebsdVersion < BaseResolver
@semaphore = Mutex.new
@fact_list ||= {}

class << self
private

def post_resolve(fact_name)
@fact_list.fetch(fact_name) { freebsd_version_system_call(fact_name) }
end

def freebsd_version_system_call(fact_name)
output, _stderr, status = Open3.capture3('/bin/freebsd-version -kru')
return nil unless status.success?

build_fact_list(output)

@fact_list[fact_name]
rescue Errno::ENOENT
nil
end

def build_fact_list(output)
freebsd_version_results = output.split("\n")

@fact_list[:installed_kernel] = freebsd_version_results[0].strip
@fact_list[:running_kernel] = freebsd_version_results[1].strip
@fact_list[:installed_userland] = freebsd_version_results[2].strip
end
end
end
end
end
end
6 changes: 5 additions & 1 deletion os_hierarchy.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
},
{
"Solaris": [
"Bsd"
{
"Bsd": [
"Freebsd"
]
}
]
},
"Macosx",
Expand Down
2 changes: 1 addition & 1 deletion spec/custom_facts/core/aggregate_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
end

it 'fact_type does not raise error' do
expect { aggregate_res.options(fact_type: 'custom') }.not_to raise_error(ArgumentError)
expect { aggregate_res.options(fact_type: 'custom') }.not_to raise_error
end
end

Expand Down
9 changes: 7 additions & 2 deletions spec/custom_facts/core/execution_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@
describe Facter::Core::Execution do
subject(:execution) { Facter::Core::Execution }

let(:windows_impl) { instance_spy(Facter::Core::Execution::Windows) }
let(:impl) { Facter::Core::Execution.impl }

before do
allow(Facter::Core::Execution::Windows).to receive(:new).and_return(windows_impl)
end

it 'delegates #search_paths to the implementation' do
expect(impl).to receive(:search_paths)
execution.search_paths
Expand All @@ -18,12 +23,12 @@
end

it 'delegates #absolute_path? to the implementation' do
expect(impl).to receive(:absolute_path?).with('waffles', nil)
expect(impl).to receive(:absolute_path?).with('waffles')
execution.absolute_path?('waffles')
end

it 'delegates #absolute_path? with an optional platform to the implementation' do
expect(impl).to receive(:absolute_path?).with('waffles', :windows)
expect(windows_impl).to receive(:absolute_path?).with('waffles')
execution.absolute_path?('waffles', :windows)
end

Expand Down
7 changes: 3 additions & 4 deletions spec/custom_facts/util/parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
shared_examples_for 'handling a not readable file' do
before do
allow(Facter::Util::FileHelper).to receive(:safe_read).with(data_file, nil).and_return(nil)
allow(LegacyFacter).to receive(:warn).at_least(:one)
allow(Facter).to receive(:log_exception).at_least(:once)
end

it 'handles not readable file' do
Expand All @@ -72,11 +72,10 @@
expect(LegacyFacter::Util::Parser.parser_for(data_file).results).to eq data
end

it 'handles exceptions and warn' do
# YAML data with an error
it 'handles exceptions' do
allow(Facter::Util::FileHelper).to receive(:safe_read)
.with(data_file, nil).and_return(data_in_yaml + '}')
allow(LegacyFacter).to receive(:warn).at_least(:one)
allow(Facter).to receive(:log_exception).at_least(:once)

expect { LegacyFacter::Util::Parser.parser_for(data_file).results }.not_to raise_error
end
Expand Down
7 changes: 4 additions & 3 deletions spec/custom_facts/util/resolution_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
end

it 'fact_type does not raise error' do
expect { resolution.options(fact_type: 'simple') }.not_to raise_error(ArgumentError)
expect { resolution.options(fact_type: 'simple') }.not_to raise_error
end

it 'fails on unhandled options' do
Expand All @@ -120,8 +120,9 @@

describe 'evaluating' do
it 'evaluates the block in the context of the given resolution' do
expect(resolution).to receive(:weight).with(5)
resolution.evaluate { weight(5) }
expect(resolution).to receive(:setcode).with('code')

resolution.evaluate { setcode('code') }
end

it 'raises a warning if the resolution is evaluated twice' do
Expand Down
21 changes: 12 additions & 9 deletions spec/facter/facter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@
allow(config_reader_double).to receive(:ttls).and_return([])
allow(config_reader_double).to receive(:block_list).and_return([])

allow(Facter::FactGroups).to receive(:instance).and_return(block_list_double)
allow(Facter::FactGroups).to receive(:new).and_return(block_list_double)
allow(block_list_double).to receive(:blocked_facts).and_return([])
allow(block_list_double).to receive(:block_list).and_return([])

Facter.instance_variable_set(:@logger, logger)
allow(Facter::Log).to receive(:new).and_return(logger)
Facter.clear
allow(Facter::SessionCache).to receive(:invalidate_all_caches)
allow(Facter::FactManager).to receive(:instance).and_return(fact_manager_spy)
allow(Facter::FactCollection).to receive(:new).and_return(fact_collection_spy)
end

after do
Facter.remove_instance_variable(:@logger)
Facter.instance_variable_set(:@logger, nil)
end

def mock_fact_manager(method, return_value)
Expand Down Expand Up @@ -101,7 +101,6 @@ def mock_collection(method, os_name = nil, error = nil)
expected_json_output = '{}'
allow(Facter::Options).to receive(:[]).and_call_original
allow(Facter::Options).to receive(:[]).with(:strict).and_return(true)
allow(OsDetector).to receive(:detect).and_return(:solaris)

formatted_facts = Facter.to_user_output({}, *user_query)

Expand Down Expand Up @@ -208,10 +207,11 @@ def mock_collection(method, os_name = nil, error = nil)

describe '#search' do
it 'sends call to Facter::Options' do
allow(Facter::Options).to receive(:[]=)
dirs = ['/dir1', '/dir2']

expect(Facter::Options).to receive(:[]=).with(:custom_dir, dirs)
Facter.search(*dirs)

expect(Facter::Options).to have_received(:[]=).with(:custom_dir, dirs)
end
end

Expand All @@ -224,10 +224,11 @@ def mock_collection(method, os_name = nil, error = nil)

describe '#search_external' do
it 'sends call to Facter::Options' do
allow(Facter::Options).to receive(:[]=)
dirs = ['/dir1', '/dir2']
expect(Facter::Options).to receive(:[]=).with(:external_dir, dirs)

Facter.search_external(dirs)

expect(Facter::Options).to have_received(:[]=).with(:external_dir, dirs)
end
end

Expand Down Expand Up @@ -314,8 +315,10 @@ def mock_collection(method, os_name = nil, error = nil)

describe '#debugging' do
it 'sets log level to debug' do
expect(Facter::Options).to receive(:[]=).with(:debug, true)
allow(Facter::Options).to receive(:[]=)
Facter.debugging(true)

expect(Facter::Options).to have_received(:[]=).with(:debug, true)
end
end

Expand Down

0 comments on commit c0219bd

Please sign in to comment.