From 794740813dde0ca76e62b88f82b4d1222e3c111e Mon Sep 17 00:00:00 2001 From: Spencer Krum Date: Thu, 19 Feb 2015 13:55:24 -0800 Subject: [PATCH 01/17] Remove travis badge --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 9feb900..e46efc1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # apt -[![Build Status](https://travis-ci.org/puppetlabs/puppetlabs-apt.png?branch=master)](https://travis-ci.org/puppetlabs/puppetlabs-apt) - ## Overview The apt module provides a simple interface for managing Apt source, key, and definitions with Puppet. From 08192b3927c39089526b322f9d7450300bc6ceb2 Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Tue, 24 Feb 2015 14:38:43 +0100 Subject: [PATCH 02/17] fix hiera example in documentation --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e46efc1..1c06e17 100644 --- a/README.md +++ b/README.md @@ -244,8 +244,8 @@ apt::sources: key: '9AA38DCD55BE302B' key_server: 'subkeys.pgp.net' pin: '-10' - include_src: 'true' - include_deb: 'true' + include_src: true + include_deb: true 'puppetlabs': location: 'http://apt.puppetlabs.com' From 4802a6fc776122d1ea77f1a5904b78442dcc205f Mon Sep 17 00:00:00 2001 From: Leslie Carr Date: Thu, 5 Mar 2015 16:56:03 -0800 Subject: [PATCH 03/17] MODULES-1827 adding Cumulus Linux detection the apt module did not correctly detect Cumulus Linux with lsbdistid. This change adds several lines in params.pp to detect Cumulus Linux and set $distid and $distcodename --- manifests/params.pp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/manifests/params.pp b/manifests/params.pp index 1c6cc99..f824c91 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -25,6 +25,10 @@ class apt::params { } } } + 'Cumulus Networks': { + $distid = 'debian' + $distcodename = $::lsbdistcodename + } '': { fail('Unable to determine lsbdistid, is lsb-release installed?') } From 31f732e7894d18a52bb11f96160dc0e0be4f35e9 Mon Sep 17 00:00:00 2001 From: Johan Fleury Date: Mon, 9 Mar 2015 00:01:57 +0100 Subject: [PATCH 04/17] Cleaning 50unattended-upgrades.erb --- templates/50unattended-upgrades.erb | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/templates/50unattended-upgrades.erb b/templates/50unattended-upgrades.erb index 1177922..47ecb34 100644 --- a/templates/50unattended-upgrades.erb +++ b/templates/50unattended-upgrades.erb @@ -33,25 +33,30 @@ Unattended-Upgrade::MinimalSteps "<%= @minimal_steps %>"; // This will (obviously) make shutdown slower Unattended-Upgrade::InstallOnShutdown "<%= @install_on_shutdown %>"; +<% if @mail_to != "NONE" %> // Send email to this address for problems or packages upgrades // If empty or unset then no email is sent, make sure that you // have a working mail setup on your system. A package that provides // 'mailx' must be installed. -<% if @mail_to != "NONE" %>Unattended-Upgrade::Mail "<%= @mail_to %>";<% end %> +Unattended-Upgrade::Mail "<%= @mail_to %>"; +<% end %> +<% if @mail_to != "NONE" %> // Set this value to "true" to get emails only on errors. Default // is to always send a mail if Unattended-Upgrade::Mail is set -<% if @mail_to != "NONE" %>Unattended-Upgrade::MailOnlyOnError "<%= @mail_only_on_error %>";<% end %> +Unattended-Upgrade::MailOnlyOnError "<%= @mail_only_on_error %>"; +<% end %> // Do automatic removal of new unused dependencies after the upgrade // (equivalent to apt-get autoremove) Unattended-Upgrade::Remove-Unused-Dependencies "<%= @remove_unused %>"; -// Automatically reboot *WITHOUT CONFIRMATION* if a -// the file /var/run/reboot-required is found after the upgrade +// Automatically reboot *WITHOUT CONFIRMATION* if a +// the file /var/run/reboot-required is found after the upgrade Unattended-Upgrade::Automatic-Reboot "<%= @auto_reboot %>"; - +<% if @dl_limit != "NONE" %> // Use apt bandwidth limit feature, this example limits the download // speed to 70kb/sec -<% if @dl_limit != "NONE" %>Acquire::http::Dl-Limit "<%= @dl_limit %>";<% end %> +Acquire::http::Dl-Limit "<%= @dl_limit %>"; +<% end %> From f588f2651a68c5863aac7dac910d96bbc7531ef9 Mon Sep 17 00:00:00 2001 From: tphoney Date: Fri, 6 Mar 2015 16:14:40 +0000 Subject: [PATCH 05/17] initial commit for gpg key checking better attempt at gpg version checking adding in key length warning removing version check, adding key check adding tests clean up the code small changes use commands documentation updates --- README.md | 2 +- lib/puppet/provider/apt_key/apt_key.rb | 13 +++++++++ lib/puppet/type/apt_key.rb | 3 +++ spec/acceptance/apt_key_provider_spec.rb | 34 ++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c06e17..45e9052 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ The apt module provides a simple interface for managing Apt source, key, and def The apt module automates obtaining and installing software packages on \*nix systems. -**Note**: While this module allows the use of short keys, **we urge you NOT to use short keys**, as they pose a serious security issue by opening you up to collision attacks. +**Note**: While this module allows the use of short keys, **warnings are thrown if a full fingerprint is not used**, as they pose a serious security issue by opening you up to collision attacks. ## Setup diff --git a/lib/puppet/provider/apt_key/apt_key.rb b/lib/puppet/provider/apt_key/apt_key.rb index 67a8aa0..687c995 100644 --- a/lib/puppet/provider/apt_key/apt_key.rb +++ b/lib/puppet/provider/apt_key/apt_key.rb @@ -16,6 +16,7 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do confine :osfamily => :debian defaultfor :osfamily => :debian commands :apt_key => 'apt-key' + commands :gpg => '/usr/bin/gpg' def self.instances cli_args = ['adv','--list-keys', '--with-colons', '--fingerprint'] @@ -136,6 +137,18 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do file = Tempfile.new('apt_key') file.write content file.close + #confirm that the fingerprint from the file, matches the long key that is in the manifest + if name.size == 40 + if File.executable? command(:gpg) + extracted_key = execute(["#{command(:gpg)} --with-fingerprint --with-colons #{file.path} | awk -F: '/^fpr:/ { print $10 }'"], :failonfail => false) + extracted_key = extracted_key.chomp + if extracted_key != name + fail ("The id in your manifest #{resource[:name]} and the fingerprint from content/source do not match. Please check there is not an error in the id or check the content/source is legitimate.") + end + else + warning ('/usr/bin/gpg cannot be found for verification of the id.') + end + end file.path end diff --git a/lib/puppet/type/apt_key.rb b/lib/puppet/type/apt_key.rb index 70825ac..7130496 100644 --- a/lib/puppet/type/apt_key.rb +++ b/lib/puppet/type/apt_key.rb @@ -23,6 +23,9 @@ Puppet::Type.newtype(:apt_key) do if self[:content] and self[:source] fail('The properties content and source are mutually exclusive.') end + if self[:id].length < 40 + warning('The id should be a full fingerprint (40 characters), see README.') + end end newparam(:id, :namevar => true) do diff --git a/spec/acceptance/apt_key_provider_spec.rb b/spec/acceptance/apt_key_provider_spec.rb index 24277d2..1f703c9 100644 --- a/spec/acceptance/apt_key_provider_spec.rb +++ b/spec/acceptance/apt_key_provider_spec.rb @@ -520,4 +520,38 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= end end end + + describe 'fingerprint validation against source/content' do + context 'fingerprint in id matches fingerprint from remote key' do + it 'works' do + pp = <<-EOS + apt_key { 'puppetlabs': + id => '#{PUPPETLABS_GPG_KEY_FINGERPRINT}', + ensure => 'present', + source => 'https://#{PUPPETLABS_APT_URL}/#{PUPPETLABS_GPG_KEY_FILE}', + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_failures => true) + end + end + + context 'fingerprint in id does NOT match fingerprint from remote key' do + it 'works' do + pp = <<-EOS + apt_key { 'puppetlabs': + id => '47B320EB4C7C375AA9DAE1A01054B7A24BD6E666', + ensure => 'present', + source => 'https://#{PUPPETLABS_APT_URL}/#{PUPPETLABS_GPG_KEY_FILE}', + } + EOS + + apply_manifest(pp, :expect_failures => true) do |r| + expect(r.stderr).to match(/do not match/) + end + end + end + end + end From 0c357042451c13af66b25985a04a81cf0d3f8262 Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Fri, 20 Feb 2015 14:25:53 -0800 Subject: [PATCH 06/17] Make installation of software-properties optional This is cherry-picked from the PPA cleanup happening for the 2.0.0 release. Conflicts: manifests/params.pp manifests/ppa.pp --- README.md | 8 +++++ manifests/params.pp | 12 ++++++- manifests/ppa.pp | 74 +++++++++++++++++++--------------------- spec/defines/ppa_spec.rb | 72 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 1c06e17..7e39c8d 100644 --- a/README.md +++ b/README.md @@ -332,6 +332,14 @@ apt::sources: It is recommended to read the manpage 'apt_preferences(5)' +####apt::ppa + +* `ensure`: Whether we are adding or removing the PPA. Can be 'present' or 'absent'. Defaults to 'present'. +* `release`: The codename for the operating system you're running. Defaults to `$lsbdistcodename`. Required if lsb-release is not installed. +* `options`: Options to be passed to the `apt-add-repository` command. OS-dependent defaults are set in `apt::params`. +* `package_name`: The package that provides the `apt-add-repository` command. OS-dependent defaults are set in `apt::params`. +* `package_manage`: Whether or not to manage the package providing `apt-add-repository`. Defaults to true. + ### Testing The apt module is mostly a collection of defined resource types, which provide reusable logic for managing Apt. It provides smoke tests for testing functionality on a target system, as well as spec tests for checking a compiled catalog against an expected set of resources. diff --git a/manifests/params.pp b/manifests/params.pp index f824c91..4efe872 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -64,18 +64,28 @@ class apt::params { 'lucid': { $backports_location = 'http://us.archive.ubuntu.com/ubuntu' $ppa_options = undef + $ppa_package = 'python-software-properties' $legacy_origin = true $origins = ['${distro_id} ${distro_codename}-security'] #lint:ignore:single_quote_string_with_variables } - 'precise', 'trusty', 'utopic', 'vivid': { + 'precise': { $backports_location = 'http://us.archive.ubuntu.com/ubuntu' $ppa_options = '-y' + $ppa_package = 'python-software-properties' + $legacy_origin = true + $origins = ['${distro_id}:${distro_codename}-security'] #lint:ignore:single_quote_string_with_variables + } + 'trusty', 'utopic', 'vivid': { + $backports_location = 'http://us.archive.ubuntu.com/ubuntu' + $ppa_options = '-y' + $ppa_package = 'software-properties-common' $legacy_origin = true $origins = ['${distro_id}:${distro_codename}-security'] #lint:ignore:single_quote_string_with_variables } default: { $backports_location = 'http://old-releases.ubuntu.com/ubuntu' $ppa_options = '-y' + $ppa_package = 'python-software-properties' $legacy_origin = true $origins = ['${distro_id}:${distro_codename}-security'] #lint:ignore:single_quote_string_with_variables } diff --git a/manifests/ppa.pp b/manifests/ppa.pp index 0fdcc95..e86a19f 100644 --- a/manifests/ppa.pp +++ b/manifests/ppa.pp @@ -1,9 +1,11 @@ # ppa.pp define apt::ppa( - $ensure = 'present', - $release = $::lsbdistcodename, - $options = $apt::params::ppa_options, + $ensure = 'present', + $release = $::lsbdistcodename, + $options = $::apt::params::ppa_options, + $package_name = $::apt::params::ppa_package, + $package_manage = true, ) { include apt::params include apt::update @@ -24,52 +26,48 @@ define apt::ppa( $sources_list_d_filename = "${filename_without_ppa}-${release}.list" if $ensure == 'present' { - $package = $::lsbdistrelease ? { - /^[1-9]\..*|1[01]\..*|12.04$/ => 'python-software-properties', - default => 'software-properties-common', - } + if $package_manage { + if ! defined(Package[$package_name]) { + package { $package_name: } + } - if ! defined(Package[$package]) { - package { $package: } - } - - if defined(Class[apt]) { - $proxy_host = $apt::proxy_host - $proxy_port = $apt::proxy_port - case $proxy_host { - false, '', undef: { - $proxy_env = [] - } - default: { - $proxy_env = ["http_proxy=http://${proxy_host}:${proxy_port}", "https_proxy=http://${proxy_host}:${proxy_port}"] - } - } + $_require = [File['sources.list.d'], Package[$package_name]] } else { - $proxy_env = [] + $_require = File['sources.list.d'] } + + if defined(Class['apt']) { + case $::apt::proxy_host { + false, '', undef: { + $proxy_env = [] + } + default: { + $proxy_env = ["http_proxy=http://${::apt::proxy_host}:${::apt::proxy_port}", "https_proxy=http://${::apt::proxy_host}:${::apt::proxy_port}"] + } + } + } else { + $proxy_env = [] + } + exec { "add-apt-repository-${name}": - environment => $proxy_env, - command => "/usr/bin/add-apt-repository ${options} ${name}", - unless => "/usr/bin/test -s ${sources_list_d}/${sources_list_d_filename}", - user => 'root', - logoutput => 'on_failure', - notify => Exec['apt_update'], - require => [ - File['sources.list.d'], - Package[$package], - ], + environment => $proxy_env, + command => "/usr/bin/add-apt-repository ${options} ${name}", + unless => "/usr/bin/test -s ${sources_list_d}/${sources_list_d_filename}", + user => 'root', + logoutput => 'on_failure', + notify => Exec['apt_update'], + require => $_require, } file { "${sources_list_d}/${sources_list_d_filename}": - ensure => file, - require => Exec["add-apt-repository-${name}"], + ensure => file, + require => Exec["add-apt-repository-${name}"], } } else { - file { "${sources_list_d}/${sources_list_d_filename}": - ensure => 'absent', - notify => Exec['apt_update'], + ensure => 'absent', + notify => Exec['apt_update'], } } diff --git a/spec/defines/ppa_spec.rb b/spec/defines/ppa_spec.rb index 3a4c381..866d323 100644 --- a/spec/defines/ppa_spec.rb +++ b/spec/defines/ppa_spec.rb @@ -32,6 +32,78 @@ describe 'apt::ppa', :type => :define do } end + describe 'package_name => software-properties-common' do + let :pre_condition do + 'class { "apt": }' + end + let :params do + { + :package_name => 'software-properties-common' + } + end + let :facts do + { + :lsbdistrelease => '11.04', + :lsbdistcodename => 'natty', + :operatingsystem => 'Ubuntu', + :osfamily => 'Debian', + :lsbdistid => 'Ubuntu', + } + end + + let(:title) { 'ppa:needs/such.substitution/wow' } + it { is_expected.to contain_package('software-properties-common') } + it { is_expected.to contain_exec('add-apt-repository-ppa:needs/such.substitution/wow').that_notifies('Exec[apt_update]').with({ + 'environment' => [], + 'command' => '/usr/bin/add-apt-repository -y ppa:needs/such.substitution/wow', + 'unless' => '/usr/bin/test -s /etc/apt/sources.list.d/needs-such_substitution-wow-natty.list', + 'user' => 'root', + 'logoutput' => 'on_failure', + }) + } + + it { is_expected.to contain_file('/etc/apt/sources.list.d/needs-such_substitution-wow-natty.list').that_requires('Exec[add-apt-repository-ppa:needs/such.substitution/wow]').with({ + 'ensure' => 'file', + }) + } + end + + describe 'package_manage => false' do + let :pre_condition do + 'class { "apt": }' + end + let :facts do + { + :lsbdistrelease => '11.04', + :lsbdistcodename => 'natty', + :operatingsystem => 'Ubuntu', + :osfamily => 'Debian', + :lsbdistid => 'Ubuntu', + } + end + let :params do + { + :package_manage => false, + } + end + + let(:title) { 'ppa:needs/such.substitution/wow' } + it { is_expected.to_not contain_package('python-software-properties') } + it { is_expected.to contain_exec('add-apt-repository-ppa:needs/such.substitution/wow').that_notifies('Exec[apt_update]').with({ + 'environment' => [], + 'command' => '/usr/bin/add-apt-repository -y ppa:needs/such.substitution/wow', + 'unless' => '/usr/bin/test -s /etc/apt/sources.list.d/needs-such_substitution-wow-natty.list', + 'user' => 'root', + 'logoutput' => 'on_failure', + }) + } + + it { is_expected.to contain_file('/etc/apt/sources.list.d/needs-such_substitution-wow-natty.list').that_requires('Exec[add-apt-repository-ppa:needs/such.substitution/wow]').with({ + 'ensure' => 'file', + }) + } + end + describe 'apt included, no proxy' do let :pre_condition do 'class { "apt": }' From 3799e3a23c7d4e74c99aa4ec7e42de0b486ffe67 Mon Sep 17 00:00:00 2001 From: Mikko Pesari Date: Wed, 18 Feb 2015 18:09:53 +0200 Subject: [PATCH 07/17] unattended_upgrades: Allow changing legacy_origin This enables using Origins-Pattern in Ubuntu. --- README.md | 13 +++++++------ manifests/unattended_upgrades.pp | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b325ba9..0bf17c4 100644 --- a/README.md +++ b/README.md @@ -74,12 +74,13 @@ class { 'apt': ``` class { 'apt::unattended_upgrades': - origins => $::apt::params::origins, - blacklist => [], - update => '1', - download => '1', - upgrade => '1', - autoclean => '7', + legacy_origin => $::apt::params::legacy_origin, + origins => $::apt::params::origins, + blacklist => [], + update => '1', + download => '1', + upgrade => '1', + autoclean => '7', } ``` diff --git a/manifests/unattended_upgrades.pp b/manifests/unattended_upgrades.pp index b835b9a..028ffc6 100644 --- a/manifests/unattended_upgrades.pp +++ b/manifests/unattended_upgrades.pp @@ -14,6 +14,7 @@ # file and in /etc/cron.daily/apt # class apt::unattended_upgrades ( + $legacy_origin = $::apt::params::legacy_origin, $origins = $::apt::params::origins, $blacklist = [], $update = '1', @@ -40,6 +41,7 @@ class apt::unattended_upgrades ( ) inherits ::apt::params { validate_bool( + $legacy_origin, $auto_fix, $minimal_steps, $install_on_shutdown, From 81bb96c898657f7d6045ddeb4b3701ab94cffa4d Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Fri, 13 Mar 2015 14:56:53 -0700 Subject: [PATCH 08/17] Update docs and test for $legacy_origin --- README.md | 1 + spec/classes/unattended_upgrades_spec.rb | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0bf17c4..501adc6 100644 --- a/README.md +++ b/README.md @@ -278,6 +278,7 @@ apt::sources: ####apt::unattended_upgrades +* `legacy_origin`: If set to true, use the old `Unattended-Upgrade::Allowed-Origins` variable. If false, use `Unattended-Upgrade::Origins-Pattern`. OS-dependent defaults are defined in `apt::params`. * `origins`: The repositories from which to automatically upgrade included packages. * `blacklist`: A list of packages to **not** automatically upgrade. * `update`: How often, in days, to run `apt-get update`. diff --git a/spec/classes/unattended_upgrades_spec.rb b/spec/classes/unattended_upgrades_spec.rb index 3742bf1..0a02755 100644 --- a/spec/classes/unattended_upgrades_spec.rb +++ b/spec/classes/unattended_upgrades_spec.rb @@ -155,6 +155,7 @@ describe 'apt::unattended_upgrades', :type => :class do let :params do { + 'legacy_origin' => true, 'enable' => '0', 'backup_interval' => '3', 'backup_level' => '1', @@ -181,7 +182,7 @@ describe 'apt::unattended_upgrades', :type => :class do } end - it { is_expected.to contain_file("/etc/apt/apt.conf.d/50unattended-upgrades").with_content %r{Unattended-Upgrade::Origins-Pattern \{\n\t"bananas";\n\};} } + it { is_expected.to contain_file("/etc/apt/apt.conf.d/50unattended-upgrades").with_content %r{Unattended-Upgrade::Allowed-Origins \{\n\t"bananas";\n\};} } it { is_expected.to contain_file("/etc/apt/apt.conf.d/50unattended-upgrades").with_content %r{Unattended-Upgrade::Package-Blacklist \{\n\t"foo";\n\t"bar";\n\};} } it { is_expected.to contain_file("/etc/apt/apt.conf.d/50unattended-upgrades").with_content %r{Unattended-Upgrade::AutoFixInterruptedDpkg "false";}} it { is_expected.to contain_file("/etc/apt/apt.conf.d/50unattended-upgrades").with_content %r{Unattended-Upgrade::MinimalSteps "true";}} From 399d3cae5ab82e53e1ced1f0f9cdd48e815b952b Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Fri, 13 Mar 2015 14:56:53 -0700 Subject: [PATCH 09/17] Update docs and test for $legacy_origin --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 501adc6..63e6a85 100644 --- a/README.md +++ b/README.md @@ -74,8 +74,6 @@ class { 'apt': ``` class { 'apt::unattended_upgrades': - legacy_origin => $::apt::params::legacy_origin, - origins => $::apt::params::origins, blacklist => [], update => '1', download => '1', From 42ab470d00ac45ceb5a4a5a9cec6260d7be98822 Mon Sep 17 00:00:00 2001 From: Chris Boot Date: Sun, 15 Mar 2015 22:33:22 +0000 Subject: [PATCH 10/17] apt_key: fix parsing invalid dates when using GnuPG 2.x If one should happen to have redirected /usr/bin/gpg to run GnuPG 2.x rather than the more usual GnuPG 1.x, the apt_key provider fails with the following error: Could not prefetch apt_key provider 'apt_key': invalid date This is because the output of "--with-colons" defaults to using "fixed-list-mode" in 2.x but did not do so for 1.x. This new format gives much more information about keys and also uses timestamps in seconds from 1970-01-01 (UNIX epoch) rather than dates in the format YYYY-MM-DD. This patch adds "--fixed-list-mode" when calling apt-key, and adjusts the code to parse the timestamps instead. This actually has several advantages: - Works the same with GnuPG 1.x and 2.x. - More accurate expiry time tracking, not just entire days. - No need to require 'date' any longer. - Will allow the provider to expose more key information in future. Tested on: - Debian Wheezy (Puppet 2.7.23, Ruby 1.8.7p358) - Debian Jessie (Puppet 3.7.2, Ruby 2.1.5p273) --- lib/puppet/provider/apt_key/apt_key.rb | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/puppet/provider/apt_key/apt_key.rb b/lib/puppet/provider/apt_key/apt_key.rb index 687c995..8878022 100644 --- a/lib/puppet/provider/apt_key/apt_key.rb +++ b/lib/puppet/provider/apt_key/apt_key.rb @@ -1,4 +1,3 @@ -require 'date' require 'open-uri' require 'net/ftp' require 'tempfile' @@ -19,7 +18,7 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do commands :gpg => '/usr/bin/gpg' def self.instances - cli_args = ['adv','--list-keys', '--with-colons', '--fingerprint'] + cli_args = ['adv','--list-keys', '--with-colons', '--fingerprint', '--fixed-list-mode'] if RUBY_VERSION > '1.8.7' key_output = apt_key(cli_args).encode('UTF-8', 'binary', :invalid => :replace, :undef => :replace, :replace => '') @@ -46,7 +45,7 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do expired = false if line_hash[:key_expiry] - expired = Date.today > Date.parse(line_hash[:key_expiry]) + expired = Time.now >= line_hash[:key_expiry] end new( @@ -57,10 +56,10 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do :long => line_hash[:key_long], :ensure => :present, :expired => expired, - :expiry => line_hash[:key_expiry], + :expiry => line_hash[:key_expiry].nil? ? nil : line_hash[:key_expiry].strftime("%Y-%m-%d"), :size => line_hash[:key_size], :type => line_hash[:key_type], - :created => line_hash[:key_created] + :created => line_hash[:key_created].strftime("%Y-%m-%d") ) end key_array.compact! @@ -96,8 +95,8 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do :key_short => fingerprint[-8..-1], # last 8 characters of fingerprint :key_size => pub_split[2], :key_type => nil, - :key_created => pub_split[5], - :key_expiry => pub_split[6].empty? ? nil : pub_split[6], + :key_created => Time.at(pub_split[5].to_i), + :key_expiry => pub_split[6].empty? ? nil : Time.at(pub_split[6].to_i), } # set key type based on types defined in /usr/share/doc/gnupg/DETAILS.gz From a24c41247f3b5e17fb20dce7e9ea4e9356f39d66 Mon Sep 17 00:00:00 2001 From: Chris Boot Date: Sun, 15 Mar 2015 22:47:15 +0000 Subject: [PATCH 11/17] apt_key: fix some whitespace issues --- lib/puppet/provider/apt_key/apt_key.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/puppet/provider/apt_key/apt_key.rb b/lib/puppet/provider/apt_key/apt_key.rb index 8878022..cd68d37 100644 --- a/lib/puppet/provider/apt_key/apt_key.rb +++ b/lib/puppet/provider/apt_key/apt_key.rb @@ -142,11 +142,11 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do extracted_key = execute(["#{command(:gpg)} --with-fingerprint --with-colons #{file.path} | awk -F: '/^fpr:/ { print $10 }'"], :failonfail => false) extracted_key = extracted_key.chomp if extracted_key != name - fail ("The id in your manifest #{resource[:name]} and the fingerprint from content/source do not match. Please check there is not an error in the id or check the content/source is legitimate.") + fail("The id in your manifest #{resource[:name]} and the fingerprint from content/source do not match. Please check there is not an error in the id or check the content/source is legitimate.") end else - warning ('/usr/bin/gpg cannot be found for verification of the id.') - end + warning('/usr/bin/gpg cannot be found for verification of the id.') + end end file.path end From 61a4fb6979f4269ddfbd6400940000fb12753e26 Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Mon, 16 Mar 2015 19:34:24 +0100 Subject: [PATCH 12/17] Fix gpg key checking warings after f588f26 Use the full fingerprint for all keys to silence the warning. --- README.md | 2 +- manifests/backports.pp | 4 ++-- manifests/debian/testing.pp | 2 +- manifests/debian/unstable.pp | 2 +- spec/acceptance/apt_spec.rb | 2 +- spec/classes/apt_spec.rb | 4 ++-- spec/classes/backports_spec.rb | 12 ++++++------ tests/source.pp | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 63e6a85..186c2c2 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,7 @@ class { 'apt': release => 'unstable', repos => 'main contrib non-free', required_packages => 'debian-keyring debian-archive-keyring', - key => '8B48AD6246925553', + key => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', key_server => 'subkeys.pgp.net', pin => '-10', include_src => true, diff --git a/manifests/backports.pp b/manifests/backports.pp index a3ddb76..ff8cb44 100644 --- a/manifests/backports.pp +++ b/manifests/backports.pp @@ -58,8 +58,8 @@ class apt::backports( } $key = $distid ? { - 'debian' => '46925553', - 'ubuntu' => '437D05B5', + 'debian' => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', + 'ubuntu' => '630239CC130E1A7FD81A27B140976EAF437D05B5', } $repos = $distid ? { 'debian' => 'main contrib non-free', diff --git a/manifests/debian/testing.pp b/manifests/debian/testing.pp index 3a82b4f..7af48d2 100644 --- a/manifests/debian/testing.pp +++ b/manifests/debian/testing.pp @@ -14,7 +14,7 @@ class apt::debian::testing { release => 'testing', repos => 'main contrib non-free', required_packages => 'debian-keyring debian-archive-keyring', - key => '46925553', + key => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', key_server => 'subkeys.pgp.net', pin => '-10', } diff --git a/manifests/debian/unstable.pp b/manifests/debian/unstable.pp index 77df94b..23ce9b4 100644 --- a/manifests/debian/unstable.pp +++ b/manifests/debian/unstable.pp @@ -14,7 +14,7 @@ class apt::debian::unstable { release => 'unstable', repos => 'main contrib non-free', required_packages => 'debian-keyring debian-archive-keyring', - key => '46925553', + key => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', key_server => 'subkeys.pgp.net', pin => '-10', } diff --git a/spec/acceptance/apt_spec.rb b/spec/acceptance/apt_spec.rb index 3011f9d..9ace221 100644 --- a/spec/acceptance/apt_spec.rb +++ b/spec/acceptance/apt_spec.rb @@ -25,7 +25,7 @@ describe 'apt class' do 'ensure' => present, 'location' => 'http://apt.puppetlabs.com', 'repos' => 'main', - 'key' => '4BD6EC30', + 'key' => '47B320EB4C7C375AA9DAE1A01054B7A24BD6EC30', 'key_server' => 'pgp.mit.edu', } }, diff --git a/spec/classes/apt_spec.rb b/spec/classes/apt_spec.rb index f65ed03..d3ef34d 100644 --- a/spec/classes/apt_spec.rb +++ b/spec/classes/apt_spec.rb @@ -155,7 +155,7 @@ describe 'apt', :type => :class do 'release' => 'unstable', 'repos' => 'main contrib non-free', 'required_packages' => 'debian-keyring debian-archive-keyring', - 'key' => '55BE302B', + 'key' => '150C8614919D8446E01E83AF9AA38DCD55BE302B', 'key_server' => 'subkeys.pgp.net', 'pin' => '-10', 'include_src' => true @@ -163,7 +163,7 @@ describe 'apt', :type => :class do 'puppetlabs' => { 'location' => 'http://apt.puppetlabs.com', 'repos' => 'main', - 'key' => '4BD6EC30', + 'key' => '47B320EB4C7C375AA9DAE1A01054B7A24BD6EC30', 'key_server' => 'pgp.mit.edu', } } } } diff --git a/spec/classes/backports_spec.rb b/spec/classes/backports_spec.rb index 3c1f438..721a4a6 100644 --- a/spec/classes/backports_spec.rb +++ b/spec/classes/backports_spec.rb @@ -17,7 +17,7 @@ describe 'apt::backports', :type => :class do 'location' => 'http://old-releases.ubuntu.com/ubuntu', 'release' => 'karmic-backports', 'repos' => 'main universe multiverse restricted', - 'key' => '437D05B5', + 'key' => '630239CC130E1A7FD81A27B140976EAF437D05B5', 'key_server' => 'pgp.mit.edu', }) } @@ -51,7 +51,7 @@ describe 'apt::backports', :type => :class do 'location' => 'http://old-releases.ubuntu.com/ubuntu', 'release' => 'karmic-backports', 'repos' => 'main universe multiverse restricted', - 'key' => '437D05B5', + 'key' => '630239CC130E1A7FD81A27B140976EAF437D05B5', 'key_server' => 'pgp.mit.edu', }) } @@ -77,7 +77,7 @@ describe 'apt::backports', :type => :class do 'location' => 'http://backports.debian.org/debian-backports', 'release' => 'squeeze-backports', 'repos' => 'main contrib non-free', - 'key' => '46925553', + 'key' => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', 'key_server' => 'pgp.mit.edu', }) } @@ -103,7 +103,7 @@ describe 'apt::backports', :type => :class do 'location' => 'http://ftp.debian.org/debian/', 'release' => 'wheezy-backports', 'repos' => 'main contrib non-free', - 'key' => '46925553', + 'key' => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', 'key_server' => 'pgp.mit.edu', }) } @@ -129,7 +129,7 @@ describe 'apt::backports', :type => :class do 'location' => 'http://us.archive.ubuntu.com/ubuntu', 'release' => 'trusty-backports', 'repos' => 'main universe multiverse restricted', - 'key' => '437D05B5', + 'key' => '630239CC130E1A7FD81A27B140976EAF437D05B5', 'key_server' => 'pgp.mit.edu', }) } @@ -163,7 +163,7 @@ describe 'apt::backports', :type => :class do 'location' => location, 'release' => 'squeeze-backports', 'repos' => 'main contrib non-free', - 'key' => '46925553', + 'key' => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', 'key_server' => 'pgp.mit.edu', }) } diff --git a/tests/source.pp b/tests/source.pp index c20b596..823b37b 100644 --- a/tests/source.pp +++ b/tests/source.pp @@ -15,7 +15,7 @@ apt::source { 'debian_testing': location => 'http://debian.mirror.iweb.ca/debian/', release => 'testing', repos => 'main contrib non-free', - key => '46925553', + key => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', key_server => 'subkeys.pgp.net', pin => '-10', } @@ -23,7 +23,7 @@ apt::source { 'debian_unstable': location => 'http://debian.mirror.iweb.ca/debian/', release => 'unstable', repos => 'main contrib non-free', - key => '46925553', + key => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', key_server => 'subkeys.pgp.net', pin => '-10', } From 58d06816e76acb5475afa6064f057e568c69a4c8 Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Mon, 16 Mar 2015 14:05:58 -0700 Subject: [PATCH 13/17] 1.8.0 prep --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ metadata.json | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 736c017..5b2a45a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,37 @@ +##2015-03-17 - Supported Release 1.8.0 +###Summary + +This is the last planned feature release of the 1.x series of this module. All new features will be evaluated for puppetlabs-apt 2.x. + +This release includes many important features, including support for full fingerprints, and fixes issues where `apt_key` was not supporting user/password and `apt_has_updates` was not properly parsing the `apt-check` output. + +####Changes to default behavior +- The apt module will now throw warnings if you don't use full fingerprints for `apt_key`s + +####Features +- Use gpg to check keys to work around https://bugs.launchpad.net/ubuntu/+source/gnupg2/+bug/1409117 (MODULES-1675) +- Add 'oldstable' to the default update origins for wheezy +- Add utopic, vivid, and cumulus compatibility +- Add support for full fingerprints +- New parameter for `apt::source` + - `trusted_source` +- New parameters for `apt::ppa` + - `package_name` + - `package_manage` +- New parameter for `apt::unattended_upgrades` + - `legacy_origin` +- Separate `apt::pin` from `apt::backports` to allow pin by release instead of origin + +####Bugfixes +- Cleanup lint and future parser issues +- Fix to support username and passwords again for `apt_key` (MODULES-1119) +- Fix issue where `apt::force` `$install_check` didn't work with non-English locales (MODULES-1231) +- Allow 5 digit ports in `apt_key` +- Fix for `ensure => absent` in `apt_key` (MODULES-1661) +- Fix `apt_has_updates` not parsing `apt-check` output correctly +- Fix inconsistent headers across files (MODULES-1200) +- Clean up formatting for 50unattended-upgrades.erb + ##2014-10-28 - Supported Release 1.7.0 ###Summary diff --git a/metadata.json b/metadata.json index 4c0e3d8..5b14ae4 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-apt", - "version": "1.7.0", + "version": "1.8.0", "author": "Puppet Labs", "summary": "Provides an interface for managing Apt source, key, and definitions with Puppet", "license": "Apache-2.0", From 6bf1ac351f9982c93b99ef828076bae3317406ed Mon Sep 17 00:00:00 2001 From: Morgan Haskel Date: Mon, 16 Mar 2015 16:40:46 -0700 Subject: [PATCH 14/17] Update all the unit tests to look for full fingerprints Merged #466 too quickly --- spec/classes/debian_testing_spec.rb | 2 +- spec/classes/debian_unstable_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/classes/debian_testing_spec.rb b/spec/classes/debian_testing_spec.rb index 6e03326..a2e35f5 100644 --- a/spec/classes/debian_testing_spec.rb +++ b/spec/classes/debian_testing_spec.rb @@ -7,7 +7,7 @@ describe 'apt::debian::testing', :type => :class do "release" => "testing", "repos" => "main contrib non-free", "required_packages" => "debian-keyring debian-archive-keyring", - "key" => "46925553", + "key" => "A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553", "key_server" => "subkeys.pgp.net", "pin" => "-10" }) diff --git a/spec/classes/debian_unstable_spec.rb b/spec/classes/debian_unstable_spec.rb index 8477a39..14d8650 100644 --- a/spec/classes/debian_unstable_spec.rb +++ b/spec/classes/debian_unstable_spec.rb @@ -7,7 +7,7 @@ describe 'apt::debian::unstable', :type => :class do "release" => "unstable", "repos" => "main contrib non-free", "required_packages" => "debian-keyring debian-archive-keyring", - "key" => "46925553", + "key" => "A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553", "key_server" => "subkeys.pgp.net", "pin" => "-10" }) From 6751213bc3b966766a5c1a55c08952e7b983c9dc Mon Sep 17 00:00:00 2001 From: Alexander Skiba Date: Sun, 22 Mar 2015 21:02:59 +0100 Subject: [PATCH 15/17] Extend docs for unattended_upgrades documented more common parameters --- README.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 186c2c2..5064fed 100644 --- a/README.md +++ b/README.md @@ -277,13 +277,21 @@ apt::sources: ####apt::unattended_upgrades * `legacy_origin`: If set to true, use the old `Unattended-Upgrade::Allowed-Origins` variable. If false, use `Unattended-Upgrade::Origins-Pattern`. OS-dependent defaults are defined in `apt::params`. -* `origins`: The repositories from which to automatically upgrade included packages. -* `blacklist`: A list of packages to **not** automatically upgrade. -* `update`: How often, in days, to run `apt-get update`. -* `download`: How often, in days, to run `apt-get upgrade --download-only`. -* `upgrade`: How often, in days, to upgrade packages included in the origins list. -* `autoclean`: How often, in days, to run `apt-get autoclean`. -* `randomsleep`: How long, in seconds, to randomly wait before applying upgrades. +* `origins`: The repositories from which to automatically upgrade included packages. OS-dependent defaults are defined in `apt::params`. (Usually only security updates are enabled by default) +* `blacklist`: A list of packages to **not** automatically upgrade. This list is empty by default. +* `update`: How often, in days, to run `apt-get update`. Defaults to '1'. +* `download`: How often, in days, to run `apt-get upgrade --download-only`. Defaults to '1'. +* `upgrade`: How often, in days, to upgrade packages included in the origins list. Defaults to '1'. +* `autoclean`: How often, in days, to run `apt-get autoclean`. Defaults to '7'. +* `auto_fix`: Tries to automatically fix interrupted package installations. Defaults to 'true'. +* `minimal_steps`: Split the upgrade process into sections to allow shutdown during upgrade. Defaults to 'false'. +* `install_on_shutdown`: Install updates on shutdown instead of in the background. Defaults to 'false'. +* `mail_to`: Send e-mail to this address about packages upgrades or errors. This is not set by default. +* `mail_only_on_error`: Send e-mail only in case of error, not on successful upgrade. Defaults to 'false'. +* `remove_unused`: Removes unused dependencies. Defaults to 'true'. +* `auto_reboot`: Reboot the system **without confirmation** if an update requires rebooting. Defaults to 'false'. +* `dl_limit`: Use a bandwidth limit for downloading, specified in kb/sec. This is not set by default. +* `randomsleep`: How long, in seconds, to randomly wait before applying upgrades. This is not set by default. ####apt::source From 36e7dfef5af45448a6bc60dd280e757b760e51ea Mon Sep 17 00:00:00 2001 From: Alice Nodelman Date: Tue, 24 Mar 2015 11:40:24 -0700 Subject: [PATCH 16/17] (BKR-147) add Gemfile setting for BEAKER_VERSION for puppet... puppetdb, etc - support for BEAKER_VERSION and BEAKER_RSPEC_VERSION in gemfile --- Gemfile | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 62c5693..e1ae0fa 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,15 @@ source ENV['GEM_SOURCE'] || "https://rubygems.org" +def location_for(place, fake_version = nil) + if place =~ /^(git:[^#]*)#(.*)/ + [fake_version, { :git => $1, :branch => $2, :require => false }].compact + elsif place =~ /^file:\/\/(.*)/ + ['>= 0', { :path => File.expand_path($1), :require => false }] + else + [place, { :require => false }] + end +end + group :development, :unit_tests do gem 'rake', :require => false gem 'rspec-core', '3.1.7', :require => false @@ -11,8 +21,17 @@ group :development, :unit_tests do gem 'json', :require => false end +beaker_version = ENV['BEAKER_VERSION'] +beaker_rspec_version = ENV['BEAKER_RSPEC_VERSION'] group :system_tests do - gem 'beaker-rspec', :require => false + if beaker_version + gem 'beaker', *location_for(beaker_version) + end + if beaker_rspec_version + gem 'beaker-rspec', *location_for(beaker_rspec_version) + else + gem 'beaker-rspec', :require => false + end gem 'serverspec', :require => false end From a96df4b25b81d928e4056fcbac06ae9c54392139 Mon Sep 17 00:00:00 2001 From: Leo Arnold Date: Wed, 25 Mar 2015 20:09:22 +0100 Subject: [PATCH 17/17] Updated key fingerprints in README to match v1.8.0 requirements --- README.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 5064fed..3fd74b3 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ class { 'apt': ``` apt_key { 'puppetlabs': ensure => 'present', - id => '1054B7A24BD6EC30', + id => '47B320EB4C7C375AA9DAE1A01054B7A24BD6EC30', } ``` @@ -157,12 +157,12 @@ class { 'apt': ``` apt::key { 'puppetlabs': - key => '1054B7A24BD6EC30', + key => '47B320EB4C7C375AA9DAE1A01054B7A24BD6EC30', key_server => 'pgp.mit.edu', } apt::key { 'jenkins': - key => '9B7D32F2D50582E6', + key => '150FDE3F7787E7D11EF4E12A9B7D32F2D50582E6', key_source => 'http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key', } ``` @@ -213,10 +213,10 @@ class { 'apt': ``` apt::source { 'puppetlabs': location => 'http://apt.puppetlabs.com', - repos => 'main', - key => '1054B7A24BD6EC30', + repos => 'main dependencies', + key => '47B320EB4C7C375AA9DAE1A01054B7A24BD6EC30', key_server => 'pgp.mit.edu', - } + } ``` ### Facts @@ -248,8 +248,8 @@ apt::sources: 'puppetlabs': location: 'http://apt.puppetlabs.com' - repos: 'main' - key: '1054B7A24BD6EC30' + repos: 'main dependencies' + key: '47B320EB4C7C375AA9DAE1A01054B7A24BD6EC30' key_server: 'pgp.mit.edu' ``` @@ -357,10 +357,12 @@ The apt module is mostly a collection of defined resource types, which provide r This test sets up a Puppet Labs Apt repository. Start by creating a new smoke test, called puppetlabs-apt.pp, in the apt module's test folder. In this test, declare a single resource representing the Puppet Labs Apt source and GPG key: ``` +class { 'apt': } + apt::source { 'puppetlabs': location => 'http://apt.puppetlabs.com', - repos => 'main', - key => '1054B7A24BD6EC30', + repos => 'main dependencies', + key => '47B320EB4C7C375AA9DAE1A01054B7A24BD6EC30', key_server => 'pgp.mit.edu', } ``` @@ -380,7 +382,7 @@ info: /Stage[main]//Apt::Source[puppetlabs]/File[puppetlabs.list]: Scheduling re notice: /Stage[main]//Apt::Source[puppetlabs]/Exec[puppetlabs apt update]: Triggered 'refresh' from 1 events> ``` -The above example uses a smoke test to lay out a resource declaration and apply it on your system. In production, you might want to declare your Apt sources inside the classes where they’re needed. +The above example uses a smoke test to lay out a resource declaration and apply it on your system. In production, you might want to declare your Apt sources inside the classes where they're needed. Limitations ----------- @@ -390,7 +392,7 @@ This module should work across all versions of Debian/Ubuntu and support all maj Development ------------ -Puppet Labs modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can’t access the huge number of platforms and myriad of hardware, software, and deployment configurations that Puppet is intended to serve. +Puppet Labs modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can't access the huge number of platforms and myriad of hardware, software, and deployment configurations that Puppet is intended to serve. We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things.