Skip to content

Commit

Permalink
(FACT-3451) extend amazon linux os release fact
Browse files Browse the repository at this point in the history
  • Loading branch information
h0tw1r3 committed Dec 13, 2023
1 parent 352e2a8 commit c86244a
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ Style/ClassVars:
Exclude:
- !ruby/regexp /(?:(?!.+_resolver.rb).)*$/

Style/FormatStringToken:
Exclude:
- 'lib/facter/resolvers/os_release_rpm.rb'
- 'spec/facter/resolvers/os_release_rpm_spec.rb'

Style/FrozenStringLiteralComment:
Exclude:
- 'spec/custom_facts/util/normalization_spec.rb'
Expand Down
4 changes: 2 additions & 2 deletions lib/facter/facts/amzn/os/distro/release.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ def call_the_resolver
end

def determine_release_version
version = Facter::Resolvers::ReleaseFromFirstLine.resolve(:release, release_file: '/etc/system-release')
version = Facter::Resolvers::OsReleaseRpm.resolve(:version)
version ||= Facter::Resolvers::OsRelease.resolve(:version_id)

Facter::Util::Facts.release_hash_from_string(version)
Facter::Util::Facts.release_hash_from_string(version, include_patch: true)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/amzn/os/release.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def call_the_resolver
end

def determine_release_version
version = Facter::Resolvers::ReleaseFromFirstLine.resolve(:release, release_file: '/etc/system-release')
version = Facter::Resolvers::OsReleaseRpm.resolve(:version)
version ||= Facter::Resolvers::OsRelease.resolve(:version_id)

Facter::Util::Facts.release_hash_from_string(version)
Expand Down
2 changes: 2 additions & 0 deletions lib/facter/framework/core/file_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@
require_relative '../../facts/amzn/os/distro/release.rb'
require_relative '../../facts/amzn/os/release.rb'

require_relative '../../resolvers/os_release_rpm'

when 'bsd'
require_relative '../../facts/bsd/kernelmajversion.rb'
require_relative '../../facts/bsd/kernelversion.rb'
Expand Down
40 changes: 40 additions & 0 deletions lib/facter/resolvers/os_release_rpm.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

module Facter
module Resolvers
class OsReleaseRpm < BaseResolver
init_resolver

QUERY_FORMAT = %()

class << self
private

def post_resolve(fact_name, _options)
@fact_list.fetch(fact_name) { rpm_system_call(fact_name) }
end

def rpm_system_call(fact_name)
output = Facter::Core::Execution.execute(
'rpm -q --qf \'%{NAME}\n%{VERSION}\n%{RELEASE}\n%{VENDOR}\' -f /etc/os-release',
logger: log
)
build_fact_list(output)

@fact_list[fact_name]
end

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

return if rpm_results.empty?

@fact_list[:package],
@fact_list[:version],
@fact_list[:release],
@fact_list[:vendor] = rpm_results.map(&:strip)
end
end
end
end
end
3 changes: 2 additions & 1 deletion lib/facter/util/facts/facts_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ def discover_family(os)
os
end

def release_hash_from_string(output)
def release_hash_from_string(output, include_patch: false)
return unless output

versions = output.split('.')
{}.tap do |release|
release['full'] = output
release['major'] = versions[0]
release['minor'] = versions[1] if versions[1]
release['patch'] = versions[2] if versions[2] && include_patch
end
end

Expand Down
20 changes: 10 additions & 10 deletions spec/facter/facts/amzn/os/distro/release_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
subject(:fact) { Facts::Amzn::Os::Distro::Release.new }

before do
allow(Facter::Resolvers::ReleaseFromFirstLine).to receive(:resolve)
.with(:release, { release_file: '/etc/system-release' })
allow(Facter::Resolvers::OsReleaseRpm).to receive(:resolve)
.with(:version)
.and_return(value)
end

context 'when version is retrieved from specific file' do
context 'when version is retrieved from rpm' do
let(:value) { '2.13.0' }
let(:release) { { 'full' => '2.13.0', 'major' => '2', 'minor' => '13' } }
let(:release) { { 'full' => '2.13.0', 'major' => '2', 'minor' => '13', 'patch' => '0' } }

it 'calls Facter::Resolvers::ReleaseFromFirstLine with version' do
it 'calls Facter::Resolvers::OsReleaseRpm with version' do
fact.call_the_resolver
expect(Facter::Resolvers::ReleaseFromFirstLine).to have_received(:resolve)
.with(:release, release_file: '/etc/system-release')
expect(Facter::Resolvers::OsReleaseRpm).to have_received(:resolve)
.with(:version)
end

it 'returns operating system name fact' do
it 'returns os distro release fact' do
expect(fact.call_the_resolver).to be_an_instance_of(Array).and \
contain_exactly(an_object_having_attributes(name: 'os.distro.release', value: release),
an_object_having_attributes(name: 'lsbdistrelease',
Expand All @@ -46,7 +46,7 @@
expect(Facter::Resolvers::OsRelease).to have_received(:resolve).with(:version_id)
end

it 'returns operating system name fact' do
it 'returns os distro release fact' do
expect(fact.call_the_resolver).to be_an_instance_of(Array).and \
contain_exactly(an_object_having_attributes(name: 'os.distro.release', value: release),
an_object_having_attributes(name: 'lsbdistrelease',
Expand All @@ -60,7 +60,7 @@
context 'when release can\'t be received' do
let(:os_release) { nil }

it 'returns operating system name fact' do
it 'returns os distro release fact as nil' do
expect(fact.call_the_resolver).to be_an_instance_of(Facter::ResolvedFact).and \
have_attributes(name: 'os.distro.release', value: nil)
end
Expand Down
20 changes: 10 additions & 10 deletions spec/facter/facts/amzn/os/release_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
subject(:fact) { Facts::Amzn::Os::Release.new }

before do
allow(Facter::Resolvers::ReleaseFromFirstLine).to receive(:resolve)
.with(:release, { release_file: '/etc/system-release' })
allow(Facter::Resolvers::OsReleaseRpm).to receive(:resolve)
.with(:version)
.and_return(value)
end

context 'when version is retrieved from specific file' do
context 'when version is retrieved from rpm' do
let(:value) { '2.13.0' }
let(:release) { { 'full' => '2.13.0', 'major' => '2', 'minor' => '13' } }

it 'calls Facter::Resolvers::ReleaseFromFirstLine with version' do
it 'calls Facter::Resolvers::OsReleaseRpm with version' do
fact.call_the_resolver
expect(Facter::Resolvers::ReleaseFromFirstLine).to have_received(:resolve)
.with(:release, release_file: '/etc/system-release')
expect(Facter::Resolvers::OsReleaseRpm).to have_received(:resolve)
.with(:version)
end

it 'returns operating system name fact' do
it 'returns os release fact' do
expect(fact.call_the_resolver).to be_an_instance_of(Array).and \
contain_exactly(an_object_having_attributes(name: 'os.release', value: release),
an_object_having_attributes(name: 'operatingsystemmajrelease',
Expand All @@ -44,7 +44,7 @@
expect(Facter::Resolvers::OsRelease).to have_received(:resolve).with(:version_id)
end

it 'returns operating system name fact' do
it 'returns os release fact' do
expect(fact.call_the_resolver).to be_an_instance_of(Array).and \
contain_exactly(an_object_having_attributes(name: 'os.release', value: release),
an_object_having_attributes(name: 'operatingsystemmajrelease',
Expand All @@ -53,10 +53,10 @@
value: release['full'], type: :legacy))
end

context 'when release can\'t be received' do
context 'when version can\'t be retrieved' do
let(:os_release) { nil }

it 'returns operating system name fact' do
it 'returns os release fact as nil' do
expect(fact.call_the_resolver).to be_an_instance_of(Facter::ResolvedFact).and \
have_attributes(name: 'os.release', value: nil)
end
Expand Down
54 changes: 54 additions & 0 deletions spec/facter/resolvers/os_release_rpm_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

describe Facter::Resolvers::OsReleaseRpm do
subject(:os_release_resolver) { Facter::Resolvers::OsReleaseRpm }

let(:log_spy) { Facter::Log }

before do
os_release_resolver.instance_variable_set(:@log, log_spy)
allow(Facter::Core::Execution).to receive(:execute)
.with("rpm -q --qf '%{NAME}\\n%{VERSION}\\n%{RELEASE}\\n%{VENDOR}' -f /etc/os-release", { logger: log_spy })
.and_return(os_release_content)
end

after do
os_release_resolver.invalidate_cache
end

context 'when on AmazonLinux 2023' do
let(:os_release_content) { "system-release\n2023.2.20231113\n1.amzn2023\nAmazon Linux" }

it 'returns os release package version' do
expect(os_release_resolver.resolve(:version)).to eq('2023.2.20231113')
end

it 'returns os release package release' do
expect(os_release_resolver.resolve(:release)).to eq('1.amzn2023')
end

it 'returns os release package vendor' do
expect(os_release_resolver.resolve(:vendor)).to eq('Amazon Linux')
end
end

context 'when on AmazonLinux 2' do
let(:os_release_content) { "system-release\n2\n16.amzn2\nAmazon Linux" }

it 'returns os release package version' do
expect(os_release_resolver.resolve(:version)).to eq('2')
end

it 'returns os release package release' do
expect(os_release_resolver.resolve(:release)).to eq('16.amzn2')
end
end

context 'when on os-release file missing' do
let(:os_release_content) { '' }

it 'returns nil VERSION' do
expect(os_release_resolver.resolve(:version)).to be_nil
end
end
end
12 changes: 12 additions & 0 deletions spec/facter/util/facts/facts_utils_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@
expect(facts_util.release_hash_from_string('6')['minor']).to be_nil
end

it 'returns valid patch release if requested' do
expect(facts_util.release_hash_from_string('6.2.1', include_patch: true)['patch']).to eq('1')
end

it 'returns patch release as nil if not requested' do
expect(facts_util.release_hash_from_string('6.2.1')['patch']).to be_nil
end

it 'returns patch release as nil if requested but not in version' do
expect(facts_util.release_hash_from_string('6.2')['patch']).to be_nil
end

it 'returns nil if data is nil' do
expect(facts_util.release_hash_from_string(nil)).to be_nil
end
Expand Down

0 comments on commit c86244a

Please sign in to comment.