From ab5c977b5d66840a74df12a7e64d7dff144acd73 Mon Sep 17 00:00:00 2001 From: Will Meek Date: Tue, 7 Nov 2017 16:21:55 +0000 Subject: [PATCH] Add a facter fact for dist-upgrade This commit adds a facter fact for dist-upgrade, along with associated facter facts. --- README.md | 12 +++- lib/facter/apt_updates.rb | 65 ++++++++++++++++--- spec/unit/facter/apt_dist_has_updates_spec.rb | 40 ++++++++++++ .../apt_dist_package_security_updates_spec.rb | 64 ++++++++++++++++++ .../facter/apt_dist_package_updates_spec.rb | 37 +++++++++++ .../facter/apt_dist_security_updates_spec.rb | 52 +++++++++++++++ spec/unit/facter/apt_dist_updates_spec.rb | 31 +++++++++ spec/unit/facter/apt_has_updates_spec.rb | 10 ++- spec/unit/facter/apt_package_updates_spec.rb | 10 ++- spec/unit/facter/apt_updates_spec.rb | 11 ++-- 10 files changed, 303 insertions(+), 29 deletions(-) create mode 100644 spec/unit/facter/apt_dist_has_updates_spec.rb create mode 100644 spec/unit/facter/apt_dist_package_security_updates_spec.rb create mode 100644 spec/unit/facter/apt_dist_package_updates_spec.rb create mode 100644 spec/unit/facter/apt_dist_security_updates_spec.rb create mode 100644 spec/unit/facter/apt_dist_updates_spec.rb diff --git a/README.md b/README.md index a93d7bda7b..6542b936d0 100644 --- a/README.md +++ b/README.md @@ -255,11 +255,17 @@ apt::source { "archive.ubuntu.com-${lsbdistcodename}-backports": ### Facts -* `apt_updates`: The number of installed packages with available updates. +* `apt_updates`: The number of installed packages with available updates from `upgrade`. -* `apt_security_updates`: The number of installed packages with available security updates. +* `apt_dist_updates`: The number of installed packages with available updates from `dist-upgrade`. -* `apt_package_updates`: The names of all installed packages with available updates. In Facter 2.0 and later this data is formatted as an array; in earlier versions it is a comma-delimited string. +* `apt_security_updates`: The number of installed packages with available security updates from `upgrade`. + +* `apt_security_dist_updates`: The number of installed packages with available security updates from `dist-upgrade`. + +* `apt_package_updates`: The names of all installed packages with available updates from `upgrade`. In Facter 2.0 and later this data is formatted as an array; in earlier versions it is a comma-delimited string. + +* `apt_package_dist_updates`: The names of all installed packages with available updates from `dist-upgrade`. In Facter 2.0 and later this data is formatted as an array; in earlier versions it is a comma-delimited string. * `apt_update_last_success`: The date, in epochtime, of the most recent successful `apt-get update` run (based on the mtime of /var/lib/apt/periodic/update-success-stamp). diff --git a/lib/facter/apt_updates.rb b/lib/facter/apt_updates.rb index 89bc37e20b..cf7d12f4c2 100644 --- a/lib/facter/apt_updates.rb +++ b/lib/facter/apt_updates.rb @@ -1,14 +1,16 @@ apt_package_updates = nil -Facter.add('apt_has_updates') do - confine osfamily: 'Debian' +apt_dist_updates = nil + +def get_updates(upgrade_option) + apt_updates = nil if File.executable?('/usr/bin/apt-get') - apt_get_result = Facter::Util::Resolution.exec('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1') + apt_get_result = Facter::Util::Resolution.exec("/usr/bin/apt-get -s -o Debug::NoLocking=true #{upgrade_option} 2>&1") unless apt_get_result.nil? - apt_package_updates = [[], []] + apt_updates = [[], []] apt_get_result.each_line do |line| next unless line =~ %r{^Inst\s} package = line.gsub(%r{^Inst\s([^\s]+)\s.*}, '\1').strip - apt_package_updates[0].push(package) + apt_updates[0].push(package) security_matches = [ %r{ Debian-Security:}, %r{ Ubuntu[^\s]+-security[, ]}, @@ -16,17 +18,28 @@ ] re = Regexp.union(security_matches) if line.match(re) - apt_package_updates[1].push(package) + apt_updates[1].push(package) end end end end setcode do - if !apt_package_updates.nil? && apt_package_updates.length == 2 - apt_package_updates != [[], []] + if !apt_updates.nil? && apt_updates.length == 2 + apt_updates != [[], []] end end + apt_updates +end + +Facter.add('apt_has_updates') do + confine osfamily: 'Debian' + apt_package_updates = get_updates('upgrade') +end + +Facter.add('apt_has_dist_updates') do + confine osfamily: 'Debian' + apt_dist_updates = get_updates('dist-upgrade') end Facter.add('apt_package_updates') do @@ -40,6 +53,17 @@ end end +Facter.add('apt_package_dist_updates') do + confine apt_has_dist_updates: true + setcode do + if Facter.version < '2.0.0' + apt_dist_updates[0].join(',') + else + apt_dist_updates[0] + end + end +end + Facter.add('apt_package_security_updates') do confine apt_has_updates: true setcode do @@ -51,6 +75,17 @@ end end +Facter.add('apt_package_security_dist_updates') do + confine apt_has_dist_updates: true + setcode do + if Facter.version < '2.0.0' + apt_dist_updates[1].join(',') + else + apt_dist_updates[1] + end + end +end + Facter.add('apt_updates') do confine apt_has_updates: true setcode do @@ -58,9 +93,23 @@ end end +Facter.add('apt_dist_updates') do + confine apt_has_dist_updates: true + setcode do + Integer(apt_dist_updates[0].length) + end +end + Facter.add('apt_security_updates') do confine apt_has_updates: true setcode do Integer(apt_package_updates[1].length) end end + +Facter.add('apt_security_dist_updates') do + confine apt_has_dist_updates: true + setcode do + Integer(apt_dist_updates[1].length) + end +end diff --git a/spec/unit/facter/apt_dist_has_updates_spec.rb b/spec/unit/facter/apt_dist_has_updates_spec.rb new file mode 100644 index 0000000000..ae67bcf110 --- /dev/null +++ b/spec/unit/facter/apt_dist_has_updates_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe 'apt_has_dist_updates fact' do + subject { Facter.fact(:apt_has_dist_updates).value } + + after(:each) { Facter.clear } + + describe 'on non-Debian distro' do + before(:each) do + Facter.fact(:osfamily).expects(:value).at_least(1).returns 'RedHat' + end + it { is_expected.to be_nil } + end + + describe 'on Debian based distro missing apt-get' do + before(:each) do + Facter.fact(:osfamily).expects(:value).at_least(1).returns 'Debian' + File.stubs(:executable?) # Stub all other calls + File.expects(:executable?).with('/usr/bin/apt-get').returns false + end + it { is_expected.to be_nil } + end + + describe 'on Debian based distro' do + before(:each) do + Facter.fact(:osfamily).expects(:value).at_least(1).returns 'Debian' + File.stubs(:executable?) # Stub all other calls + Facter::Util::Resolution.stubs(:exec) # Catch all other calls + File.expects(:executable?).with('/usr/bin/apt-get').returns true + Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns 'test' + File.expects(:executable?).with('/usr/bin/apt-get').returns true + apt_output = "Inst extremetuxracer [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Conf extremetuxracer (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Inst planet.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ + "Conf planet.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" + Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').returns apt_output + end + it { is_expected.to be true } + end +end diff --git a/spec/unit/facter/apt_dist_package_security_updates_spec.rb b/spec/unit/facter/apt_dist_package_security_updates_spec.rb new file mode 100644 index 0000000000..316dbfc6ff --- /dev/null +++ b/spec/unit/facter/apt_dist_package_security_updates_spec.rb @@ -0,0 +1,64 @@ +require 'spec_helper' + +describe 'apt_package_security_dist_updates fact' do + subject { Facter.fact(:apt_package_security_dist_updates).value } + + after(:each) { Facter.clear } + + describe 'when apt has no updates' do + before(:each) do + Facter.fact(:apt_has_dist_updates).stubs(:value).returns false + end + it { is_expected.to be nil } + end + + describe 'when apt has updates' do + before(:each) do + Facter.fact(:osfamily).stubs(:value).returns 'Debian' + File.stubs(:executable?) # Stub all other calls + Facter::Util::Resolution.stubs(:exec) # Catch all other calls + File.expects(:executable?).with('/usr/bin/apt-get').returns true + Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns 'test' + File.expects(:executable?).with('/usr/bin/apt-get').returns true + Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').returns apt_get_upgrade_output + end + + describe 'on Debian' do + let(:apt_get_upgrade_output) do + "Inst extremetuxracer [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Conf extremetuxracer (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Inst planet.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ + "Conf planet.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ + "Inst vim [7.52.1-5] (7.52.1-5+deb9u2 Debian-Security:9/stable [amd64]) []\n" \ + "Conf vim (7.52.1-5+deb9u2 Debian-Security:9/stable [amd64])\n" \ + end + + it { + if Facter.version < '2.0.0' + is_expected.to eq('vim') + else + is_expected.to eq(['vim']) + end + } + end + + describe 'on Ubuntu' do + let(:apt_get_upgrade_output) do + "Inst extremetuxracer [2016f-0ubuntu0.16.04] (2016j-0ubuntu0.16.04 Ubuntu:16.04/xenial-security, Ubuntu:16.04/xenial-updates [all])\n" \ + "Conf extremetuxracer (2016j-0ubuntu0.16.04 Ubuntu:16.04/xenial-security, Ubuntu:16.04/xenial-updates [all])\n" \ + "Inst vim [7.47.0-1ubuntu2] (7.47.0-1ubuntu2.2 Ubuntu:16.04/xenial-security [amd64]) []\n" \ + "Conf vim (7.47.0-1ubuntu2.2 Ubuntu:16.04/xenial-security [amd64])\n" \ + "Inst onioncircuits [2:3.3.10-4ubuntu2] (2:3.3.10-4ubuntu2.3 Ubuntu:16.04/xenial-updates [amd64])\n" \ + "Conf onioncircuits (2:3.3.10-4ubuntu2.3 Ubuntu:16.04/xenial-updates [amd64])\n" + end + + it { + if Facter.version < '2.0.0' + is_expected.to eq('extremetuxracer,vim') + else + is_expected.to eq(%w[extremetuxracer vim]) + end + } + end + end +end diff --git a/spec/unit/facter/apt_dist_package_updates_spec.rb b/spec/unit/facter/apt_dist_package_updates_spec.rb new file mode 100644 index 0000000000..557e3b3b2f --- /dev/null +++ b/spec/unit/facter/apt_dist_package_updates_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe 'apt_package_dist_updates fact' do + subject { Facter.fact(:apt_package_dist_updates).value } + + after(:each) { Facter.clear } + + describe 'when apt has no updates' do + before(:each) do + Facter.fact(:apt_has_dist_updates).stubs(:value).returns false + end + it { is_expected.to be nil } + end + + describe 'when apt has updates' do + before(:each) do + Facter.fact(:osfamily).stubs(:value).returns 'Debian' + File.stubs(:executable?) # Stub all other calls + Facter::Util::Resolution.stubs(:exec) # Catch all other calls + File.expects(:executable?).with('/usr/bin/apt-get').returns true + Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns 'test' + File.expects(:executable?).with('/usr/bin/apt-get').returns true + apt_output = "Inst extremetuxracer [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Conf extremetuxracer (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Inst planet.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ + "Conf planet.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" + Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').returns apt_output + end + it { + if Facter.version < '2.0.0' + is_expected.to eq('extremetuxracer,planet.rb') + else + is_expected.to eq(['extremetuxracer', 'planet.rb']) + end + } + end +end diff --git a/spec/unit/facter/apt_dist_security_updates_spec.rb b/spec/unit/facter/apt_dist_security_updates_spec.rb new file mode 100644 index 0000000000..9b58b6e696 --- /dev/null +++ b/spec/unit/facter/apt_dist_security_updates_spec.rb @@ -0,0 +1,52 @@ +require 'spec_helper' + +describe 'apt_security_updates fact' do + subject { Facter.fact(:apt_security_dist_updates).value } + + after(:each) { Facter.clear } + + describe 'when apt has no updates' do + before(:each) do + Facter.fact(:apt_has_dist_updates).stubs(:value).returns false + end + it { is_expected.to be nil } + end + + describe 'when apt has security updates' do + before(:each) do + Facter.fact(:osfamily).stubs(:value).returns 'Debian' + File.stubs(:executable?) # Stub all other calls + Facter::Util::Resolution.stubs(:exec) # Catch all other calls + File.expects(:executable?).with('/usr/bin/apt-get').returns true + Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns 'test' + File.expects(:executable?).with('/usr/bin/apt-get').returns true + Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').returns apt_get_upgrade_output + end + + describe 'on Debian' do + let(:apt_get_upgrade_output) do + "Inst extremetuxracer [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Conf extremetuxracer (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Inst planet.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ + "Conf planet.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ + "Inst vim [7.52.1-5] (7.52.1-5+deb9u2 Debian-Security:9/stable [amd64]) []\n" \ + "Conf vim (7.52.1-5+deb9u2 Debian-Security:9/stable [amd64])\n" \ + end + + it { is_expected.to eq(1) } + end + + describe 'on Ubuntu' do + let(:apt_get_upgrade_output) do + "Inst extremetuxracer [2016f-0ubuntu0.16.04] (2016j-0ubuntu0.16.04 Ubuntu:16.04/xenial-security, Ubuntu:16.04/xenial-updates [all])\n" \ + "Conf extremetuxracer (2016j-0ubuntu0.16.04 Ubuntu:16.04/xenial-security, Ubuntu:16.04/xenial-updates [all])\n" \ + "Inst vim [7.47.0-1ubuntu2] (7.47.0-1ubuntu2.2 Ubuntu:16.04/xenial-security [amd64]) []\n" \ + "Conf vim (7.47.0-1ubuntu2.2 Ubuntu:16.04/xenial-security [amd64])\n" \ + "Inst onioncircuits [2:3.3.10-4ubuntu2] (2:3.3.10-4ubuntu2.3 Ubuntu:16.04/xenial-updates [amd64])\n" \ + "Conf onioncircuits (2:3.3.10-4ubuntu2.3 Ubuntu:16.04/xenial-updates [amd64])\n" + end + + it { is_expected.to eq(2) } + end + end +end diff --git a/spec/unit/facter/apt_dist_updates_spec.rb b/spec/unit/facter/apt_dist_updates_spec.rb new file mode 100644 index 0000000000..737d1b6578 --- /dev/null +++ b/spec/unit/facter/apt_dist_updates_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe 'apt_updates fact' do + subject { Facter.fact(:apt_dist_updates).value } + + after(:each) { Facter.clear } + + describe 'when apt has no updates' do + before(:each) do + Facter.fact(:apt_has_dist_updates).stubs(:value).returns false + end + it { is_expected.to be nil } + end + + describe 'when apt has updates' do + before(:each) do + Facter.fact(:osfamily).stubs(:value).returns 'Debian' + File.stubs(:executable?) # Stub all other calls + Facter::Util::Resolution.stubs(:exec) # Catch all other calls + File.expects(:executable?).with('/usr/bin/apt-get').returns true + Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns 'test' + File.expects(:executable?).with('/usr/bin/apt-get').returns true + apt_output = "Inst extremetuxracer [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Conf extremetuxracer (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Inst planet.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ + "Conf planet.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" + Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').returns apt_output + end + it { is_expected.to eq(2) } + end +end diff --git a/spec/unit/facter/apt_has_updates_spec.rb b/spec/unit/facter/apt_has_updates_spec.rb index fcc874d651..5c06c2fb9c 100644 --- a/spec/unit/facter/apt_has_updates_spec.rb +++ b/spec/unit/facter/apt_has_updates_spec.rb @@ -27,12 +27,10 @@ File.stubs(:executable?) # Stub all other calls Facter::Util::Resolution.stubs(:exec) # Catch all other calls File.expects(:executable?).with('/usr/bin/apt-get').returns true - apt_output = <<-EOT -Inst tzdata [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all]) -Conf tzdata (2015g-0+deb8u1 Debian:stable-updates [all]) -Inst unhide.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all]) -Conf unhide.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all]) -EOT + apt_output = "Inst tzdata [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Conf tzdata (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Inst unhide.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ + "Conf unhide.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns apt_output end it { is_expected.to be true } diff --git a/spec/unit/facter/apt_package_updates_spec.rb b/spec/unit/facter/apt_package_updates_spec.rb index 875a29005f..355ab183d2 100644 --- a/spec/unit/facter/apt_package_updates_spec.rb +++ b/spec/unit/facter/apt_package_updates_spec.rb @@ -18,12 +18,10 @@ File.stubs(:executable?) # Stub all other calls Facter::Util::Resolution.stubs(:exec) # Catch all other calls File.expects(:executable?).with('/usr/bin/apt-get').returns true - apt_output = <<-EOT -Inst tzdata [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all]) -Conf tzdata (2015g-0+deb8u1 Debian:stable-updates [all]) -Inst unhide.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all]) -Conf unhide.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all]) -EOT + apt_output = "Inst tzdata [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Conf tzdata (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Inst unhide.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ + "Conf unhide.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns apt_output end it { diff --git a/spec/unit/facter/apt_updates_spec.rb b/spec/unit/facter/apt_updates_spec.rb index cc1aa94e21..d0a5dbb0fe 100644 --- a/spec/unit/facter/apt_updates_spec.rb +++ b/spec/unit/facter/apt_updates_spec.rb @@ -18,12 +18,11 @@ File.stubs(:executable?) # Stub all other calls Facter::Util::Resolution.stubs(:exec) # Catch all other calls File.expects(:executable?).with('/usr/bin/apt-get').returns true - apt_output = <<-EOT -Inst tzdata [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all]) -Conf tzdata (2015g-0+deb8u1 Debian:stable-updates [all]) -Inst unhide.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all]) -Conf unhide.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all]) -EOT + apt_output = "Inst tzdata [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Conf tzdata (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ + "Inst unhide.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ + "Conf unhide.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" + puts apt_output Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns apt_output end it { is_expected.to eq(2) }