From d318a6c23eb4134095ee83a8e8dd14e8c8a84cec Mon Sep 17 00:00:00 2001 From: James Paton-Smith Date: Wed, 6 Mar 2024 15:39:07 +0000 Subject: [PATCH 01/26] Initial testing for deb822 APT sources --- manifests/params.pp | 111 +++++++++++++++++++++++++++++ manifests/setting.pp | 2 +- manifests/source_deb822.pp | 31 ++++++++ spec/defines/source_deb822_spec.rb | 18 +++++ templates/source_deb822.epp | 43 +++++++++++ 5 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 manifests/params.pp create mode 100644 manifests/source_deb822.pp create mode 100644 spec/defines/source_deb822_spec.rb create mode 100644 templates/source_deb822.epp diff --git a/manifests/params.pp b/manifests/params.pp new file mode 100644 index 0000000000..2ff72648ee --- /dev/null +++ b/manifests/params.pp @@ -0,0 +1,111 @@ +# @summary Provides defaults for the Apt module parameters. +# +# @api private +# +class apt::params { + if $facts['os']['family'] != 'Debian' { + fail('This module only works on Debian or derivatives like Ubuntu') + } + + $root = '/etc/apt' + $provider = '/usr/bin/apt-get' + $sources_list = "${root}/sources.list" + $sources_list_force = false + $sources_list_d = "${root}/sources.list.d" + $trusted_gpg_d = "${root}/trusted.gpg.d" + $conf_d = "${root}/apt.conf.d" + $preferences = "${root}/preferences" + $preferences_d = "${root}/preferences.d" + $apt_conf_d = "${root}/apt.conf.d" + $keyserver = 'keyserver.ubuntu.com' + $key_options = undef + $confs = {} + $update = {} + $purge = {} + $proxy = {} + $sources = {} + $keys = {} + $ppas = {} + $pins = {} + $settings = {} + $manage_auth_conf = true + $auth_conf_entries = [] + + $config_files = { + 'conf' => { + 'path' => $conf_d, + 'ext' => '', + }, + 'pref' => { + 'path' => $preferences_d, + 'ext' => '.pref', + }, + 'list' => { + 'path' => $sources_list_d, + 'ext' => '.list', + }, + 'source' => { + 'path' => $sources_list_d, + 'ext' => '.sources', + }, + } + + $update_defaults = { + 'frequency' => 'reluctantly', + 'loglevel' => undef, + 'timeout' => undef, + 'tries' => undef, + } + + $proxy_defaults = { + 'ensure' => undef, + 'host' => undef, + 'port' => 8080, + 'https' => false, + 'https_acng' => false, + 'direct' => false, + } + + $purge_defaults = { + 'sources.list' => false, + 'sources.list.d' => false, + 'preferences' => false, + 'preferences.d' => false, + 'apt.conf.d' => false, + } + + $include_defaults = { + 'deb' => true, + 'src' => false, + } + + case $facts['os']['name'] { + 'Debian': { + $backports = { + 'location' => 'http://deb.debian.org/debian', + 'repos' => 'main contrib non-free', + } + $ppa_options = undef + $ppa_package = undef + $auth_conf_owner = '_apt' + } + 'Ubuntu': { + $backports = { + 'location' => 'http://archive.ubuntu.com/ubuntu', + 'repos' => 'main universe multiverse restricted', + } + $ppa_options = ['-y'] + $ppa_package = 'software-properties-common' + $auth_conf_owner = '_apt' + } + undef: { + fail('Unable to determine value for fact os[\"name\"]') + } + default: { + $ppa_options = undef + $ppa_package = undef + $backports = undef + $auth_conf_owner = 'root' + } + } +} diff --git a/manifests/setting.pp b/manifests/setting.pp index 46b347d96a..524d9baf1f 100644 --- a/manifests/setting.pp +++ b/manifests/setting.pp @@ -51,7 +51,7 @@ } } - if ($setting_type == 'list') or ($setting_type == 'pref') { + if ($setting_type == 'list') or ($setting_type == 'pref') or ($setting_type == 'source') { $_priority = '' } else { $_priority = $priority diff --git a/manifests/source_deb822.pp b/manifests/source_deb822.pp new file mode 100644 index 0000000000..b226caaa77 --- /dev/null +++ b/manifests/source_deb822.pp @@ -0,0 +1,31 @@ +# @summary A short summary of the purpose of this defined type. +# +# A description of what this defined type does +# +# @example +# apt::source_deb822 { 'namevar': } +define apt::source_deb822 ( + Array[String] $uris, + Array[String] $suites, + Array[String] $components, + Array[Enum['deb','deb-src'], 1, 2] $types = ['deb'], + Enum['present','absent'] $ensure = 'present', + String $comment = $name, + Boolean $enabled = true, + Boolean $notify_update = true, + Optional[Array[String]] $architectures = undef, + Optional[Boolean] $allow_insecure = undef, + Optional[Boolean] $trusted = undef, + Optional[Variant[Array[Stdlib::AbsolutePath], String]] $signed_by = undef, + Optional[Boolean] $check_valid_until = undef, + Optional[Hash] $options = undef +) { + $header = epp('apt/_header.epp') + $source_content = epp('apt/source_deb822.epp') + + apt::setting { "source-${name}": + ensure => $ensure, + content => "${header}${source_content}", + notify_update => $notify_update, + } +} diff --git a/spec/defines/source_deb822_spec.rb b/spec/defines/source_deb822_spec.rb new file mode 100644 index 0000000000..87060ba406 --- /dev/null +++ b/spec/defines/source_deb822_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'apt::source_deb822' do + let(:title) { 'namevar' } + let(:params) do + {} + end + + on_supported_os.each do |os, os_facts| + context "on #{os}" do + let(:facts) { os_facts } + + it { is_expected.to compile } + end + end +end diff --git a/templates/source_deb822.epp b/templates/source_deb822.epp new file mode 100644 index 0000000000..c82ee4fe78 --- /dev/null +++ b/templates/source_deb822.epp @@ -0,0 +1,43 @@ +<% | String $comment, + Enum['yes','no'] $enabled, + Hash $types,Array[String] $uris, + Array[String] $suites, + Array[String] $components, + Optional[Array] $architectures = undef, + Optional[Enum['yes','no']] $allow_insecure = undef, + Optional[Enum['yes','no']] $repo_trusted = undef, + Optional[Enum['yes','no']] $check_valid_until = undef, + Optional[Variant[Array[String], String]] $signed_by = undef, + Optional[Hash] $options = undef +| -%> +# This file is managed by Puppet. DO NOT EDIT. +# <%= $comment %> +Enabled: <%= $enabled %> +Types:<% if $types['deb'] { %> deb<% } %><% if $types['src'] { %> deb-src<% } %> +URIs: <% $uris.each | String $uri | { -%> <%= $uri %> <% } %> +Suites: <% $suites.each | String $suite | { -%> <%= $suite %> <% } %> +Components: <% $components.each | String $component | { -%> <%= $component %> <% } %> +<% if $architectures { -%> +Architectures:<% $architectures.each | String $arch | { %> <%= $arch %><% } %> +<%- } -%> +<% if $allow_insecure { -%> +Allow-Insecure: <%= $allow_insecure %> +<% } -%> +<% if $repo_trusted { -%> +Trusted: <%= $repo_trusted %> +<% } -%> +<% if $check_valid_until { -%> +Check-Valid-Until: <%= $check_valid_until %> +<% } -%> +<% if $signed_by { -%> +Signed-By: <% if type($signed_by) =~ Type[Array] { -%><%- $signed_by.each |String $keyring| { -%><%= $keyring %> <% } %> +<%- } -%> +<%- elsif type($signed_by) =~ Type[String] { %> + <%= $signed_by -%> +<%- }} -%> +<% if $options { -%> +# Additional Options +<% $options.each |$key, $value| {-%> +<%= $key -%>: <%= $value %> +<% } -%> +<% } -%> From 1ff46c1a20831ea0d0cef510552504ee1a18680b Mon Sep 17 00:00:00 2001 From: James Paton-Smith Date: Thu, 7 Mar 2024 10:22:54 +0000 Subject: [PATCH 02/26] Added defined type for generating deb822 apt sources Should be roughly drop-in alternative to the existing apt::source type Does not currently support inline ascii gpg key --- manifests/setting.pp | 2 +- manifests/source_deb822.pp | 41 ++++++++++++++++++++++++++++--------- templates/source_deb822.epp | 12 +++-------- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/manifests/setting.pp b/manifests/setting.pp index 524d9baf1f..a5ba3b93e7 100644 --- a/manifests/setting.pp +++ b/manifests/setting.pp @@ -40,7 +40,7 @@ $setting_type = $title_array[0] $base_name = join(delete_at($title_array, 0), '-') - assert_type(Pattern[/\Aconf\z/, /\Apref\z/, /\Alist\z/], $setting_type) |$a, $b| { + assert_type(Pattern[/\Aconf\z/, /\Apref\z/, /\Alist\z/, /\Asource\z/], $setting_type) |$a, $b| { fail("apt::setting resource name/title must start with either 'conf-', 'pref-' or 'list-'") } diff --git a/manifests/source_deb822.pp b/manifests/source_deb822.pp index b226caaa77..fb88ee891c 100644 --- a/manifests/source_deb822.pp +++ b/manifests/source_deb822.pp @@ -5,23 +5,44 @@ # @example # apt::source_deb822 { 'namevar': } define apt::source_deb822 ( - Array[String] $uris, - Array[String] $suites, - Array[String] $components, - Array[Enum['deb','deb-src'], 1, 2] $types = ['deb'], - Enum['present','absent'] $ensure = 'present', String $comment = $name, Boolean $enabled = true, + Array[Enum['deb','deb-src'], 1, 2] $types = ['deb'], Boolean $notify_update = true, + Enum['present','absent'] $ensure = 'present', + Optional[Array[String]] $uris = undef, + Optional[Array[String]] $suites = undef, + Optional[Array[String]] $components = undef, Optional[Array[String]] $architectures = undef, Optional[Boolean] $allow_insecure = undef, - Optional[Boolean] $trusted = undef, - Optional[Variant[Array[Stdlib::AbsolutePath], String]] $signed_by = undef, + Optional[Boolean] $repo_trusted = undef, + Optional[Variant[Array[Stdlib::AbsolutePath],String]] $signed_by = undef, Optional[Boolean] $check_valid_until = undef, - Optional[Hash] $options = undef ) { - $header = epp('apt/_header.epp') - $source_content = epp('apt/source_deb822.epp') + case $ensure { + 'present': { + $header = epp('apt/_header.epp') + $source_content = epp('apt/source_deb822.epp', delete_undef_values({ + 'uris' => $uris, + 'suites' => $suites, + 'components' => $components, + 'types' => $types, + 'comment' => $comment, + 'enabled' => $enabled ? { true => 'yes', false => 'no' }, + 'architectures' => $architectures, + 'allow_insecure' => $allow_insecure ? { true => 'yes', false => 'no', default => undef }, + 'repo_trusted' => $repo_trusted ? { true => 'yes', false => 'no', default => undef }, + 'check_valid_until' => $check_valid_until ? { true => 'yes', false => 'no', default => undef }, + 'signed_by' => $signed_by, + } + ) + ) + } + 'absent': { + $header = undef + $source_content = undef + } + } apt::setting { "source-${name}": ensure => $ensure, diff --git a/templates/source_deb822.epp b/templates/source_deb822.epp index c82ee4fe78..99a2d671fd 100644 --- a/templates/source_deb822.epp +++ b/templates/source_deb822.epp @@ -1,6 +1,7 @@ <% | String $comment, Enum['yes','no'] $enabled, - Hash $types,Array[String] $uris, + Array[String] $types, + Array[String] $uris, Array[String] $suites, Array[String] $components, Optional[Array] $architectures = undef, @@ -10,10 +11,9 @@ Optional[Variant[Array[String], String]] $signed_by = undef, Optional[Hash] $options = undef | -%> -# This file is managed by Puppet. DO NOT EDIT. # <%= $comment %> Enabled: <%= $enabled %> -Types:<% if $types['deb'] { %> deb<% } %><% if $types['src'] { %> deb-src<% } %> +Types: <% $types.each |String $type| { -%> <%= $type %> <% } %> URIs: <% $uris.each | String $uri | { -%> <%= $uri %> <% } %> Suites: <% $suites.each | String $suite | { -%> <%= $suite %> <% } %> Components: <% $components.each | String $component | { -%> <%= $component %> <% } %> @@ -35,9 +35,3 @@ Signed-By: <% if type($signed_by) =~ Type[Array] { -%><%- $signed_by.each |Strin <%- elsif type($signed_by) =~ Type[String] { %> <%= $signed_by -%> <%- }} -%> -<% if $options { -%> -# Additional Options -<% $options.each |$key, $value| {-%> -<%= $key -%>: <%= $value %> -<% } -%> -<% } -%> From 3051de465a5d8578706ac024676c2455644bba74 Mon Sep 17 00:00:00 2001 From: James Paton-Smith Date: Thu, 7 Mar 2024 11:15:23 +0000 Subject: [PATCH 03/26] Add puppet strings documentation --- REFERENCE.md | 151 ++++++++++++++++++++++++++++++++++++ manifests/source_deb822.pp | 70 +++++++++++++++-- templates/source_deb822.epp | 1 - 3 files changed, 213 insertions(+), 9 deletions(-) diff --git a/REFERENCE.md b/REFERENCE.md index 980848ac4e..074c139b85 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -25,6 +25,7 @@ * [`apt::ppa`](#apt--ppa): Manages PPA repositories using `add-apt-repository`. Not supported on Debian. * [`apt::setting`](#apt--setting): Manages Apt configuration files. * [`apt::source`](#apt--source): Manages the Apt sources in /etc/apt/sources.list.d/. +* [`apt::source_deb822`](#apt--source_deb822): Manage deb822 formatted APT sources under `/etc/apt/sources.list.d` ### Resource types @@ -1234,6 +1235,156 @@ Specifies whether to check if the package release date is valid. Default value: `true` +### `apt::source_deb822` + +Manage deb822 formatted APT sources under `/etc/apt/sources.list.d` + +#### Examples + +##### Manage the Puppetlabs repo + +```puppet +apt::source_deb822 { 'Puppetlabs-puppet': + comment => 'Manage the puppetlabs repo', + enabled => true, + types => ['deb'], + uris => ['http://apt.puppet.com'], + suites => ['jammy'], + components => ['puppet8'], + signed_by => ['/etc/apt/keyrings/linuxembl-ebi.gpg'], +} +``` + +##### Ensure absence of a repo + +```puppet +apt::source_deb822 { 'testing123': + ensure => 'absent', +} +``` + +#### Parameters + +The following parameters are available in the `apt::source_deb822` defined type: + +* [`notify_update`](#-apt--source_deb822--notify_update) +* [`ensure`](#-apt--source_deb822--ensure) +* [`enabled`](#-apt--source_deb822--enabled) +* [`comment`](#-apt--source_deb822--comment) +* [`types`](#-apt--source_deb822--types) +* [`uris`](#-apt--source_deb822--uris) +* [`suites`](#-apt--source_deb822--suites) +* [`components`](#-apt--source_deb822--components) +* [`architectures`](#-apt--source_deb822--architectures) +* [`allow_insecure`](#-apt--source_deb822--allow_insecure) +* [`repo_trusted`](#-apt--source_deb822--repo_trusted) +* [`check_valid_until`](#-apt--source_deb822--check_valid_until) +* [`signed_by`](#-apt--source_deb822--signed_by) + +##### `notify_update` + +Data type: `Boolean` + +Specifies whether to trigger an `apt-get update` run. + +Default value: `true` + +##### `ensure` + +Data type: `Enum['present','absent']` + +Specifies whether the Apt source file should exist. + +Default value: `'present'` + +##### `enabled` + +Data type: `Boolean` + +Enable or Disable the APT source. + +Default value: `true` + +##### `comment` + +Data type: `String` + +Provide a comment to the APT source file. + +Default value: `$name` + +##### `types` + +Data type: `Array[Enum['deb','deb-src'], 1, 2]` + +The package types this source manages. + +Default value: `['deb']` + +##### `uris` + +Data type: `Optional[Array[String]]` + +A list of URIs for the APT source. + +Default value: `undef` + +##### `suites` + +Data type: `Optional[Array[String]]` + +A list of suites for the APT source ('jammy-updates', 'bookworm', 'stable', etc.). + +Default value: `undef` + +##### `components` + +Data type: `Optional[Array[String]]` + +A list of components for the APT source ('main', 'contrib', 'non-free', etc.). + +Default value: `undef` + +##### `architectures` + +Data type: `Optional[Array[String]]` + +A list of supported architectures for the APT source ('amd64', 'i386', etc.). + +Default value: `undef` + +##### `allow_insecure` + +Data type: `Optional[Boolean]` + +Specifies whether to allow downloads from insecure repositories. + +Default value: `undef` + +##### `repo_trusted` + +Data type: `Optional[Boolean]` + +Consider the APT source trusted, even if authentication checks fail. + +Default value: `undef` + +##### `check_valid_until` + +Data type: `Optional[Boolean]` + +Specifies whether to check if the package release date is valid. + +Default value: `undef` + +##### `signed_by` + +Data type: `Optional[Variant[Array[Stdlib::AbsolutePath],String]]` + +Absolute path to a file containing the PGP keyring used to sign this repository. + +Default value: `undef` + ## Data types ### `Apt::Auth_conf_entry` diff --git a/manifests/source_deb822.pp b/manifests/source_deb822.pp index fb88ee891c..d2b637580e 100644 --- a/manifests/source_deb822.pp +++ b/manifests/source_deb822.pp @@ -1,23 +1,74 @@ -# @summary A short summary of the purpose of this defined type. +# @summary Manage deb822 formatted APT sources under `/etc/apt/sources.list.d` # -# A description of what this defined type does +# @example Manage the Puppetlabs repo +# apt::source_deb822 { 'Puppetlabs-puppet': +# comment => 'Manage the puppetlabs repo', +# enabled => true, +# types => ['deb'], +# uris => ['http://apt.puppet.com'], +# suites => ['jammy'], +# components => ['puppet8'], +# signed_by => ['/etc/apt/keyrings/linuxembl-ebi.gpg'], +# } +# +# @example Ensure absence of a repo +# apt::source_deb822 { 'testing123': +# ensure => 'absent', +# } +# +# @param notify_update +# Specifies whether to trigger an `apt-get update` run. +# +# @param ensure +# Specifies whether the Apt source file should exist. +# +# @param enabled +# Enable or Disable the APT source. +# +# @param comment +# Provide a comment to the APT source file. +# +# @param types +# The package types this source manages. +# +# @param uris +# A list of URIs for the APT source. +# +# @param suites +# A list of suites for the APT source ('jammy-updates', 'bookworm', 'stable', etc.). +# +# @param components +# A list of components for the APT source ('main', 'contrib', 'non-free', etc.). +# +# @param architectures +# A list of supported architectures for the APT source ('amd64', 'i386', etc.). +# +# @param allow_insecure +# Specifies whether to allow downloads from insecure repositories. +# +# @param repo_trusted +# Consider the APT source trusted, even if authentication checks fail. +# +# @param check_valid_until +# Specifies whether to check if the package release date is valid. +# +# @param signed_by +# Absolute path to a file containing the PGP keyring used to sign this repository. # -# @example -# apt::source_deb822 { 'namevar': } define apt::source_deb822 ( - String $comment = $name, + Enum['present','absent'] $ensure = 'present', + Boolean $notify_update = true, Boolean $enabled = true, + String $comment = $name, Array[Enum['deb','deb-src'], 1, 2] $types = ['deb'], - Boolean $notify_update = true, - Enum['present','absent'] $ensure = 'present', Optional[Array[String]] $uris = undef, Optional[Array[String]] $suites = undef, Optional[Array[String]] $components = undef, Optional[Array[String]] $architectures = undef, Optional[Boolean] $allow_insecure = undef, Optional[Boolean] $repo_trusted = undef, - Optional[Variant[Array[Stdlib::AbsolutePath],String]] $signed_by = undef, Optional[Boolean] $check_valid_until = undef, + Optional[Variant[Array[Stdlib::AbsolutePath],String]] $signed_by = undef, ) { case $ensure { 'present': { @@ -42,6 +93,9 @@ $header = undef $source_content = undef } + default: { + fail('Unexpected value for $ensure parameter.') + } } apt::setting { "source-${name}": diff --git a/templates/source_deb822.epp b/templates/source_deb822.epp index 99a2d671fd..2297597c65 100644 --- a/templates/source_deb822.epp +++ b/templates/source_deb822.epp @@ -9,7 +9,6 @@ Optional[Enum['yes','no']] $repo_trusted = undef, Optional[Enum['yes','no']] $check_valid_until = undef, Optional[Variant[Array[String], String]] $signed_by = undef, - Optional[Hash] $options = undef | -%> # <%= $comment %> Enabled: <%= $enabled %> From 73efbc158b5088f45847a83571488582eedbcc76 Mon Sep 17 00:00:00 2001 From: James Paton-Smith Date: Tue, 19 Mar 2024 09:51:27 +0000 Subject: [PATCH 04/26] Replace example with generic content --- REFERENCE.md | 2 +- manifests/source_deb822.pp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/REFERENCE.md b/REFERENCE.md index 074c139b85..955faea339 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -1251,7 +1251,7 @@ apt::source_deb822 { 'Puppetlabs-puppet': uris => ['http://apt.puppet.com'], suites => ['jammy'], components => ['puppet8'], - signed_by => ['/etc/apt/keyrings/linuxembl-ebi.gpg'], + signed_by => ['/etc/apt/keyrings/puppetlabs.gpg'], } ``` diff --git a/manifests/source_deb822.pp b/manifests/source_deb822.pp index d2b637580e..c1b1372d28 100644 --- a/manifests/source_deb822.pp +++ b/manifests/source_deb822.pp @@ -8,7 +8,7 @@ # uris => ['http://apt.puppet.com'], # suites => ['jammy'], # components => ['puppet8'], -# signed_by => ['/etc/apt/keyrings/linuxembl-ebi.gpg'], +# signed_by => ['/etc/apt/keyrings/puppetlabs.gpg'], # } # # @example Ensure absence of a repo From 958bdbfec2bc1e908a275c288966e96bed32f45e Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Tue, 25 Jun 2024 15:32:30 +0100 Subject: [PATCH 05/26] Initial testing of apt::source with deb822 support --- manifests/source.pp | 351 +++++++++++++++++++++++++++----------------- 1 file changed, 213 insertions(+), 138 deletions(-) diff --git a/manifests/source.pp b/manifests/source.pp index e7986697c3..1ae02b4d45 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -21,8 +21,20 @@ # }, # } # +# @param source_format +# The file format to use for the apt source. See https://wiki.debian.org/SourcesList +# # @param location -# Required, unless ensure is set to 'absent'. Specifies an Apt repository. +# Required, unless ensure is set to 'absent'. Specifies an Apt repository. Valid options: a string containing a repository URL. +# +# @param types +# DEB822: The package types this source manages. +# +# @param uris +# DEB822: A list of URIs for the APT source. +# +# @param enabled +# DEB822: Enable or Disable the APT source. # # @param comment # Supplies a comment for adding to the Apt source file. @@ -33,9 +45,15 @@ # @param release # Specifies a distribution of the Apt repository. # +# @param suites +# DEB822: A list of suites for the APT source ('jammy-updates', 'bookworm', 'stable', etc.). +# # @param repos # Specifies a component of the Apt repository. # +# @param components +# DEB822: A list of components for the APT source ('main', 'contrib', 'non-free', etc.). +# # @param include # Configures include options. Valid options: a hash of available keys. # @@ -58,6 +76,9 @@ # This is not necessary if the key is installed with `key` param above. # See https://wiki.debian.org/DebianRepository/UseThirdParty for details. # +# @param signed_by +# DEB822: Absolute path to a file containing the PGP keyring used to sign this repository. +# # @param pin # Creates a declaration of the apt::pin defined type. Valid options: a number or string to be passed to the `priority` parameter of the # `apt::pin` defined type, or a hash of `parameter => value` pairs to be passed to `apt::pin`'s corresponding parameters. @@ -67,9 +88,15 @@ # separated by commas (e.g., 'i386' or 'i386,alpha,powerpc'). # (if unspecified, Apt downloads information for all architectures defined in the Apt::Architectures option) # +# @param architectures +# DEB822: A list of supported architectures for the APT source ('amd64', 'i386', etc.). +# # @param allow_unsigned # Specifies whether to authenticate packages from this release, even if the Release file is not signed or the signature can't be checked. # +# @param repo_trusted +# DEB822: Consider the APT source trusted, even if authentication checks fail. +# # @param allow_insecure # Specifies whether to allow downloads from insecure repositories. # @@ -80,177 +107,225 @@ # Specifies whether to check if the package release date is valid. # define apt::source ( + Enum['legacy', 'deb822'] $source_format = 'legacy', + Array[Enum['deb','deb-src'], 1, 2] $types = ['deb'], Optional[String[1]] $location = undef, String[1] $comment = $name, + Optional[Array[String]] $uris = undef, # deb822 + Boolean $enabled = true, # deb822 Enum['present', 'absent'] $ensure = present, Optional[String[0]] $release = undef, + Optional[Array[String]] $suites = undef, # deb822 String[1] $repos = 'main', + Optional[Array[String]] $components = split($repos, /,/), # deb822 Hash $include = {}, Optional[Variant[String[1], Hash]] $key = undef, Optional[Stdlib::AbsolutePath] $keyring = undef, + Optional[Array[Stdlib::AbsolutePath]] $signed_by = undef, # deb822 Optional[Variant[Hash, Integer, String[1]]] $pin = undef, Optional[String[1]] $architecture = undef, - Boolean $allow_unsigned = false, - Boolean $allow_insecure = false, + Optional[Array[String]] $architectures = undef, # deb822 + Optional[Boolean] $allow_unsigned = undef, + Optional[Boolean] $repo_trusted = undef, # deb822 + Optional[Boolean] $allow_insecure = undef, + Optional[Boolean] $check_valid_until = undef, Boolean $notify_update = true, - Boolean $check_valid_until = true, ) { include apt $_before = Apt::Setting["list-${title}"] - if !$release { - if fact('os.distro.codename') { - $_release = fact('os.distro.codename') - } else { - fail('os.distro.codename fact not available: release parameter required') - } - } else { - $_release = $release - } - - if $release =~ Pattern[/\/$/] { - $_components = $_release - } else { - $_components = "${_release} ${repos}" - } - - if $ensure == 'present' { - if ! $location { - fail('cannot create a source entry without specifying a location') - } - elsif ($apt::proxy['https_acng']) and ($location =~ /(?i:^https:\/\/)/) { - $_location = regsubst($location, 'https://','http://HTTPS///') - } - else { - $_location = $location - } - } else { - $_location = undef - } - - $includes = $apt::include_defaults + $include + case $source_format { + 'legacy': { + $_file_suffix = 'list' - if $keyring { - if $key { - fail('parameters key and keyring are mutually exclusive') - } else { - $_list_keyring = $keyring - } - } elsif $key { - if $key =~ Hash { - unless $key['name'] or $key['id'] { - fail('key hash must contain a key name (for apt::keyring) or an id (for apt::key)') + if !$release { + if fact('os.distro.codename') { + $_release = fact('os.distro.codename') + } else { + fail('os.distro.codename fact not available: release parameter required') + } + } else { + $_release = $release } - if $key['id'] { - # defaults like keyserver are only relevant to apt::key - $_key = $apt::source_key_defaults + $key + + if $release =~ Pattern[/\/$/] { + $_components = $_release } else { - $_key = $key + $_components = "${_release} ${repos}" } - } else { - $_key = { 'id' => assert_type(String[1], $key) } - } - if $_key['ensure'] { - $_key_ensure = $_key['ensure'] - } else { - $_key_ensure = $ensure - } - # Old keyserver keys handled by apt-key - if $_key =~ Hash and $_key['id'] { - # We do not want to remove keys when the source is absent. if $ensure == 'present' { - apt::key { "Add key: ${$_key['id']} from Apt::Source ${title}": - ensure => $_key_ensure, - id => $_key['id'], - server => $_key['server'], - content => $_key['content'], - source => $_key['source'], - options => $_key['options'], - weak_ssl => $_key['weak_ssl'], - before => $_before, + if ! $location { + fail('cannot create a source entry without specifying a location') } - } - $_list_keyring = undef - } - # Modern apt keyrings - elsif $_key =~ Hash and $_key['name'] { - apt::keyring { $_key['name']: - ensure => $_key_ensure, - content => $_key['content'], - source => $_key['source'], - dir => $_key['dir'], - filename => $_key['filename'], - mode => $_key['mode'], - before => $_before, + elsif ($apt::proxy['https_acng']) and ($location =~ /(?i:^https:\/\/)/) { + $_location = regsubst($location, 'https://','http://HTTPS///') + } + else { + $_location = $location + } + } else { + $_location = undef } - $_list_keyring = if $_key['dir'] and $_key['filename'] { - "${_key['dir']}${_key['filename']}" - } elsif $_key['filename'] { - "/etc/apt/keyrings/${_key['filename']}" - } elsif $_key['dir'] { - "${_key['dir']}${_key['name']}" + $includes = $apt::include_defaults + $include + + if $keyring { + if $key { + fail('parameters key and keyring are mutually exclusive') + } else { + $_list_keyring = $keyring + } + } elsif $key { + if $key =~ Hash { + unless $key['name'] or $key['id'] { + fail('key hash must contain a key name (for apt::keyring) or an id (for apt::key)') + } + if $key['id'] { + # defaults like keyserver are only relevant to apt::key + $_key = $apt::source_key_defaults + $key + } else { + $_key = $key + } + } else { + $_key = { 'id' => assert_type(String[1], $key) } + } + if $_key['ensure'] { + $_key_ensure = $_key['ensure'] + } else { + $_key_ensure = $ensure + } + + # Old keyserver keys handled by apt-key + if $_key =~ Hash and $_key['id'] { + # We do not want to remove keys when the source is absent. + if $ensure == 'present' { + apt::key { "Add key: ${$_key['id']} from Apt::Source ${title}": + ensure => $_key_ensure, + id => $_key['id'], + server => $_key['server'], + content => $_key['content'], + source => $_key['source'], + options => $_key['options'], + weak_ssl => $_key['weak_ssl'], + before => $_before, + } + } + $_list_keyring = undef + } + # Modern apt keyrings + elsif $_key =~ Hash and $_key['name'] { + apt::keyring { $_key['name']: + ensure => $_key_ensure, + content => $_key['content'], + source => $_key['source'], + dir => $_key['dir'], + filename => $_key['filename'], + mode => $_key['mode'], + before => $_before, + } + + $_list_keyring = if $_key['dir'] and $_key['filename'] { + "${_key['dir']}${_key['filename']}" + } elsif $_key['filename'] { + "/etc/apt/keyrings/${_key['filename']}" + } elsif $_key['dir'] { + "${_key['dir']}${_key['name']}" + } else { + "/etc/apt/keyrings/${_key['name']}" + } + } } else { - "/etc/apt/keyrings/${_key['name']}" + # No `key` nor `keyring` provided + $_list_keyring = undef } - } - } else { - # No `key` nor `keyring` provided - $_list_keyring = undef - } - $header = epp('apt/_header.epp') + $header = epp('apt/_header.epp') - if $architecture { - $_architecture = regsubst($architecture, '\baarch64\b', 'arm64') - } else { - $_architecture = undef - } + if $architecture { + $_architecture = regsubst($architecture, '\baarch64\b', 'arm64') + } else { + $_architecture = undef + } - $sourcelist = epp('apt/source.list.epp', - { - 'comment' => $comment, - 'includes' => $includes, - 'options' => delete_undef_values( - { - 'arch' => $_architecture, - 'trusted' => $allow_unsigned ? { true => 'yes', false => undef }, - 'allow-insecure' => $allow_insecure ? { true => 'yes', false => undef }, - 'signed-by' => $_list_keyring, - 'check-valid-until' => $check_valid_until? { true => undef, false => 'false' }, - }, - ), - 'location' => $_location, - 'components' => $_components, - }, - ) + $source_content = epp('apt/source.list.epp', { + 'comment' => $comment, + 'includes' => $includes, + 'options' => delete_undef_values({ + 'arch' => $_architecture, + 'trusted' => $allow_unsigned ? { true => 'yes', false => undef, default => undef }, + 'allow-insecure' => $allow_insecure ? { true => 'yes', false => undef, default => undef }, + 'signed-by' => $_list_keyring, + 'check-valid-until' => $check_valid_until? { true => undef, false => 'false', default => undef }, + }, + ), + 'location' => $_location, + 'components' => $_components, + } + ) - apt::setting { "list-${name}": - ensure => $ensure, - content => "${header}${sourcelist}", - notify_update => $notify_update, - } + if $pin { + if $pin =~ Hash { + $_pin = $pin + { 'ensure' => $ensure, 'before' => $_before } + } elsif ($pin =~ Numeric or $pin =~ String) { + $url_split = split($location, '[:\/]+') + $host = $url_split[1] + $_pin = { + 'ensure' => $ensure, + 'priority' => $pin, + 'before' => $_before, + 'origin' => $host, + } + } else { + fail('Received invalid value for pin parameter') + } - if $pin { - if $pin =~ Hash { - $_pin = $pin + { 'ensure' => $ensure, 'before' => $_before } - } elsif ($pin =~ Numeric or $pin =~ String) { - $url_split = split($location, '[:\/]+') - $host = $url_split[1] - $_pin = { - 'ensure' => $ensure, - 'priority' => $pin, - 'before' => $_before, - 'origin' => $host, + apt::pin { $name: + * => $_pin, + } } - } else { - fail('Received invalid value for pin parameter') } - - apt::pin { $name: - * => $_pin, + 'deb822': { + if ($pin) { + fail('apt::source::pin parameter is not supported with deb822 format') + } + $_file_suffix = 'sources' + case $ensure { + 'present': { + $header = epp('apt/_header.epp') + $source_content = epp('apt/source_deb822.epp', delete_undef_values({ + 'uris' => $uris, + 'suites' => $suites, + 'components' => $components, + 'types' => $types, + 'comment' => $comment, + 'enabled' => $enabled ? { true => 'yes', false => 'no' }, + 'architectures' => $architectures, + 'allow_insecure' => $allow_insecure ? { true => 'yes', false => 'no', default => undef }, + 'repo_trusted' => $repo_trusted ? { true => 'yes', false => 'no', default => undef }, + 'check_valid_until' => $check_valid_until ? { true => 'yes', false => 'no', default => undef }, + 'signed_by' => $signed_by, + } + ) + ) + } + 'absent': { + $header = undef + $source_content = undef + } + default: { + fail('Unexpected value for $ensure parameter.') + } + } + } + default: { + fail("Unexpected APT source format: ${source_format}") } } + apt::setting { "${_file_suffix}-${name}": + ensure => $ensure, + content => "${header}${source_content}", + notify_update => $notify_update, + } } From 2d59e6cbd411dabe775f8e711fecd06a05d720fc Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Tue, 25 Jun 2024 16:09:20 +0100 Subject: [PATCH 06/26] Fix setting_type and signed_by Use 'sources' instead of 'source' as the setting_type parsed to apt::setting Fix the data type of apt::source::signed_by --- manifests/params.pp | 2 +- manifests/setting.pp | 6 +++--- manifests/source.pp | 4 ++-- templates/source_deb822.epp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/manifests/params.pp b/manifests/params.pp index 2ff72648ee..22f2af4e29 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -44,7 +44,7 @@ 'path' => $sources_list_d, 'ext' => '.list', }, - 'source' => { + 'sources' => { 'path' => $sources_list_d, 'ext' => '.sources', }, diff --git a/manifests/setting.pp b/manifests/setting.pp index a5ba3b93e7..2308296a45 100644 --- a/manifests/setting.pp +++ b/manifests/setting.pp @@ -40,8 +40,8 @@ $setting_type = $title_array[0] $base_name = join(delete_at($title_array, 0), '-') - assert_type(Pattern[/\Aconf\z/, /\Apref\z/, /\Alist\z/, /\Asource\z/], $setting_type) |$a, $b| { - fail("apt::setting resource name/title must start with either 'conf-', 'pref-' or 'list-'") + assert_type(Pattern[/\Aconf\z/, /\Apref\z/, /\Alist\z/, /\Asources\z/], $setting_type) |$a, $b| { + fail("apt::setting resource name/title must start with either 'conf-', 'pref-', 'list-', or 'sources-'") } if $priority !~ Integer { @@ -51,7 +51,7 @@ } } - if ($setting_type == 'list') or ($setting_type == 'pref') or ($setting_type == 'source') { + if ($setting_type == 'list') or ($setting_type == 'pref') or ($setting_type == 'sources') { $_priority = '' } else { $_priority = $priority diff --git a/manifests/source.pp b/manifests/source.pp index 1ae02b4d45..8e44965f39 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -77,7 +77,7 @@ # See https://wiki.debian.org/DebianRepository/UseThirdParty for details. # # @param signed_by -# DEB822: Absolute path to a file containing the PGP keyring used to sign this repository. +# DEB822: Either an absolute path to a PGP keyring file used to sign this repository OR a list of key fingerprints to trust. # # @param pin # Creates a declaration of the apt::pin defined type. Valid options: a number or string to be passed to the `priority` parameter of the @@ -121,7 +121,7 @@ Hash $include = {}, Optional[Variant[String[1], Hash]] $key = undef, Optional[Stdlib::AbsolutePath] $keyring = undef, - Optional[Array[Stdlib::AbsolutePath]] $signed_by = undef, # deb822 + Optional[Variant[Stdlib::AbsolutePath,Array[String]]] $signed_by = undef, # deb822 Optional[Variant[Hash, Integer, String[1]]] $pin = undef, Optional[String[1]] $architecture = undef, Optional[Array[String]] $architectures = undef, # deb822 diff --git a/templates/source_deb822.epp b/templates/source_deb822.epp index 2297597c65..b1870d1dc1 100644 --- a/templates/source_deb822.epp +++ b/templates/source_deb822.epp @@ -8,7 +8,7 @@ Optional[Enum['yes','no']] $allow_insecure = undef, Optional[Enum['yes','no']] $repo_trusted = undef, Optional[Enum['yes','no']] $check_valid_until = undef, - Optional[Variant[Array[String], String]] $signed_by = undef, + Optional[Variant[Stdlib::AbsolutePath,Array[String]]] $signed_by = undef, | -%> # <%= $comment %> Enabled: <%= $enabled %> From fa48103d62208aa9723e209f78d1a8de2b9e526a Mon Sep 17 00:00:00 2001 From: James Paton-Smith Date: Tue, 25 Jun 2024 18:41:24 +0100 Subject: [PATCH 07/26] Fix source_deb822.epp template Correctly handle newline/whitespace trimming for `signed_by` parameter. --- templates/source_deb822.epp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/source_deb822.epp b/templates/source_deb822.epp index b1870d1dc1..c580d2c75b 100644 --- a/templates/source_deb822.epp +++ b/templates/source_deb822.epp @@ -29,8 +29,8 @@ Trusted: <%= $repo_trusted %> Check-Valid-Until: <%= $check_valid_until %> <% } -%> <% if $signed_by { -%> -Signed-By: <% if type($signed_by) =~ Type[Array] { -%><%- $signed_by.each |String $keyring| { -%><%= $keyring %> <% } %> +Signed-By: <% if type($signed_by) =~ Type[Array] { -%><%- $signed_by.each |String $keyring| { -%><%= $keyring %> <% } -%> <%- } -%> -<%- elsif type($signed_by) =~ Type[String] { %> +<%- elsif type($signed_by) =~ Type[String] { -%> <%= $signed_by -%> -<%- }} -%> +<%- }} %> From 68351d20781c05cf45eb05149debbd63ccf65e8e Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Wed, 26 Jun 2024 09:15:54 +0100 Subject: [PATCH 08/26] Remove link from components to repos --- manifests/source.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifests/source.pp b/manifests/source.pp index 8e44965f39..9d30208080 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -117,7 +117,7 @@ Optional[String[0]] $release = undef, Optional[Array[String]] $suites = undef, # deb822 String[1] $repos = 'main', - Optional[Array[String]] $components = split($repos, /,/), # deb822 + Optional[Array[String]] $components = undef, # deb822 Hash $include = {}, Optional[Variant[String[1], Hash]] $key = undef, Optional[Stdlib::AbsolutePath] $keyring = undef, From 5aa44a1545fbd8d60fb73d6cb58fb80aa2b6200b Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Tue, 2 Jul 2024 10:00:05 +0100 Subject: [PATCH 09/26] Add logic for deb822 sources --- manifests/source.pp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/manifests/source.pp b/manifests/source.pp index 9d30208080..c7a5e56dc9 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -287,9 +287,18 @@ } } 'deb822': { - if ($pin) { + if $pin { fail('apt::source::pin parameter is not supported with deb822 format') } + if !$uris { + fail('You must specify a list of URIs for the apt::source resource') + } + if !$suites { + fail('You must specify a list of suites for the apt::source resource') + } + if !$components { + fail('You must specify a list of components for the apt::source resource') + } $_file_suffix = 'sources' case $ensure { 'present': { From e9bfb98e4c47e4efbefa75882087e9e9d2842f2b Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Tue, 2 Jul 2024 10:49:36 +0100 Subject: [PATCH 10/26] Update documentation for deb822 sources --- REFERENCE.md | 240 ++++++++++++++----------------------- manifests/source.pp | 9 ++ manifests/source_deb822.pp | 106 ---------------- 3 files changed, 100 insertions(+), 255 deletions(-) delete mode 100644 manifests/source_deb822.pp diff --git a/REFERENCE.md b/REFERENCE.md index 955faea339..b63663575f 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -25,7 +25,6 @@ * [`apt::ppa`](#apt--ppa): Manages PPA repositories using `add-apt-repository`. Not supported on Debian. * [`apt::setting`](#apt--setting): Manages Apt configuration files. * [`apt::source`](#apt--source): Manages the Apt sources in /etc/apt/sources.list.d/. -* [`apt::source_deb822`](#apt--source_deb822): Manage deb822 formatted APT sources under `/etc/apt/sources.list.d` ### Resource types @@ -1089,25 +1088,54 @@ apt::source { 'puppetlabs': } ``` +##### Install the puppetlabs apt source (deb822 format) + +```puppet +apt::source { 'puppetlabs': + source_format => 'deb822' + uris => ['http://apt.puppetlabs.com'], + suites => [$facts['os']['distro']['codename']], + components => ['puppet8'], + signed_by => '/etc/apt/keyrings/puppetlabs.gpg', +} +``` + #### Parameters The following parameters are available in the `apt::source` defined type: +* [`source_format`](#-apt--source--source_format) * [`location`](#-apt--source--location) +* [`types`](#-apt--source--types) +* [`uris`](#-apt--source--uris) +* [`enabled`](#-apt--source--enabled) * [`comment`](#-apt--source--comment) * [`ensure`](#-apt--source--ensure) * [`release`](#-apt--source--release) +* [`suites`](#-apt--source--suites) * [`repos`](#-apt--source--repos) +* [`components`](#-apt--source--components) * [`include`](#-apt--source--include) * [`key`](#-apt--source--key) * [`keyring`](#-apt--source--keyring) +* [`signed_by`](#-apt--source--signed_by) * [`pin`](#-apt--source--pin) * [`architecture`](#-apt--source--architecture) +* [`architectures`](#-apt--source--architectures) * [`allow_unsigned`](#-apt--source--allow_unsigned) +* [`repo_trusted`](#-apt--source--repo_trusted) * [`allow_insecure`](#-apt--source--allow_insecure) * [`notify_update`](#-apt--source--notify_update) * [`check_valid_until`](#-apt--source--check_valid_until) +##### `source_format` + +Data type: `Enum['legacy', 'deb822']` + +The file format to use for the apt source. See https://wiki.debian.org/SourcesList + +Default value: `'legacy'` + ##### `location` Data type: `Optional[String[1]]` @@ -1116,6 +1144,30 @@ Required, unless ensure is set to 'absent'. Specifies an Apt repository. Default value: `undef` +##### `types` + +Data type: `Array[Enum['deb','deb-src'], 1, 2]` + +DEB822: The package types this source manages. + +Default value: `['deb']` + +##### `uris` + +Data type: `Optional[Array[String]]` + +DEB822: A list of URIs for the APT source. + +Default value: `undef` + +##### `enabled` + +Data type: `Boolean` + +DEB822: Enable or Disable the APT source. + +Default value: `true` + ##### `comment` Data type: `String[1]` @@ -1140,6 +1192,14 @@ Specifies a distribution of the Apt repository. Default value: `undef` +##### `suites` + +Data type: `Optional[Array[String]]` + +DEB822: A list of suites for the APT source ('jammy-updates', 'bookworm', 'stable', etc.). + +Default value: `undef` + ##### `repos` Data type: `String[1]` @@ -1148,6 +1208,14 @@ Specifies a component of the Apt repository. Default value: `'main'` +##### `components` + +Data type: `Optional[Array[String]]` + +DEB822: A list of components for the APT source ('main', 'contrib', 'non-free', etc.). + +Default value: `undef` + ##### `include` Data type: `Hash` @@ -1184,6 +1252,14 @@ See https://wiki.debian.org/DebianRepository/UseThirdParty for details. Default value: `undef` +##### `signed_by` + +Data type: `Optional[Variant[Stdlib::AbsolutePath,Array[String]]]` + +DEB822: Either an absolute path to a PGP keyring file used to sign this repository OR a list of key fingerprints to trust. + +Default value: `undef` + ##### `pin` Data type: `Optional[Variant[Hash, Integer, String[1]]]` @@ -1203,157 +1279,31 @@ separated by commas (e.g., 'i386' or 'i386,alpha,powerpc'). Default value: `undef` -##### `allow_unsigned` - -Data type: `Boolean` - -Specifies whether to authenticate packages from this release, even if the Release file is not signed or the signature can't be checked. - -Default value: `false` - -##### `allow_insecure` - -Data type: `Boolean` - -Specifies whether to allow downloads from insecure repositories. - -Default value: `false` - -##### `notify_update` - -Data type: `Boolean` - -Specifies whether to trigger an `apt-get update` run. - -Default value: `true` - -##### `check_valid_until` - -Data type: `Boolean` - -Specifies whether to check if the package release date is valid. - -Default value: `true` - -### `apt::source_deb822` - -Manage deb822 formatted APT sources under `/etc/apt/sources.list.d` - -#### Examples - -##### Manage the Puppetlabs repo - -```puppet -apt::source_deb822 { 'Puppetlabs-puppet': - comment => 'Manage the puppetlabs repo', - enabled => true, - types => ['deb'], - uris => ['http://apt.puppet.com'], - suites => ['jammy'], - components => ['puppet8'], - signed_by => ['/etc/apt/keyrings/puppetlabs.gpg'], -} -``` - -##### Ensure absence of a repo - -```puppet -apt::source_deb822 { 'testing123': - ensure => 'absent', -} -``` - -#### Parameters - -The following parameters are available in the `apt::source_deb822` defined type: - -* [`notify_update`](#-apt--source_deb822--notify_update) -* [`ensure`](#-apt--source_deb822--ensure) -* [`enabled`](#-apt--source_deb822--enabled) -* [`comment`](#-apt--source_deb822--comment) -* [`types`](#-apt--source_deb822--types) -* [`uris`](#-apt--source_deb822--uris) -* [`suites`](#-apt--source_deb822--suites) -* [`components`](#-apt--source_deb822--components) -* [`architectures`](#-apt--source_deb822--architectures) -* [`allow_insecure`](#-apt--source_deb822--allow_insecure) -* [`repo_trusted`](#-apt--source_deb822--repo_trusted) -* [`check_valid_until`](#-apt--source_deb822--check_valid_until) -* [`signed_by`](#-apt--source_deb822--signed_by) - -##### `notify_update` - -Data type: `Boolean` - -Specifies whether to trigger an `apt-get update` run. - -Default value: `true` - -##### `ensure` - -Data type: `Enum['present','absent']` - -Specifies whether the Apt source file should exist. - -Default value: `'present'` - -##### `enabled` - -Data type: `Boolean` - -Enable or Disable the APT source. - -Default value: `true` - -##### `comment` - -Data type: `String` - -Provide a comment to the APT source file. - -Default value: `$name` - -##### `types` - -Data type: `Array[Enum['deb','deb-src'], 1, 2]` - -The package types this source manages. - -Default value: `['deb']` - -##### `uris` +##### `architectures` Data type: `Optional[Array[String]]` -A list of URIs for the APT source. +DEB822: A list of supported architectures for the APT source ('amd64', 'i386', etc.). Default value: `undef` -##### `suites` - -Data type: `Optional[Array[String]]` - -A list of suites for the APT source ('jammy-updates', 'bookworm', 'stable', etc.). - -Default value: `undef` - -##### `components` +##### `allow_unsigned` -Data type: `Optional[Array[String]]` +Data type: `Optional[Boolean]` -A list of components for the APT source ('main', 'contrib', 'non-free', etc.). +Specifies whether to authenticate packages from this release, even if the Release file is not signed or the signature can't be checked. Default value: `undef` -##### `architectures` +##### `repo_trusted` -Data type: `Optional[Array[String]]` +Data type: `Optional[Boolean]` -A list of supported architectures for the APT source ('amd64', 'i386', etc.). +DEB822: Consider the APT source trusted, even if authentication checks fail. Default value: `undef` -##### `allow_insecure` +##### `allow_insecure` Data type: `Optional[Boolean]` @@ -1361,15 +1311,15 @@ Specifies whether to allow downloads from insecure repositories. Default value: `undef` -##### `repo_trusted` +##### `notify_update` -Data type: `Optional[Boolean]` +Data type: `Boolean` -Consider the APT source trusted, even if authentication checks fail. +Specifies whether to trigger an `apt-get update` run. -Default value: `undef` +Default value: `true` -##### `check_valid_until` +##### `check_valid_until` Data type: `Optional[Boolean]` @@ -1377,14 +1327,6 @@ Specifies whether to check if the package release date is valid. Default value: `undef` -##### `signed_by` - -Data type: `Optional[Variant[Array[Stdlib::AbsolutePath],String]]` - -Absolute path to a file containing the PGP keyring used to sign this repository. - -Default value: `undef` - ## Data types ### `Apt::Auth_conf_entry` diff --git a/manifests/source.pp b/manifests/source.pp index c7a5e56dc9..d53528f8ab 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -21,6 +21,15 @@ # }, # } # +# @example Install the puppetlabs apt source (deb822 format) +# apt::source { 'puppetlabs': +# source_format => 'deb822' +# uris => ['http://apt.puppetlabs.com'], +# suites => [$facts['os']['distro']['codename']], +# components => ['puppet8'], +# signed_by => '/etc/apt/keyrings/puppetlabs.gpg', +# } +# # @param source_format # The file format to use for the apt source. See https://wiki.debian.org/SourcesList # diff --git a/manifests/source_deb822.pp b/manifests/source_deb822.pp deleted file mode 100644 index c1b1372d28..0000000000 --- a/manifests/source_deb822.pp +++ /dev/null @@ -1,106 +0,0 @@ -# @summary Manage deb822 formatted APT sources under `/etc/apt/sources.list.d` -# -# @example Manage the Puppetlabs repo -# apt::source_deb822 { 'Puppetlabs-puppet': -# comment => 'Manage the puppetlabs repo', -# enabled => true, -# types => ['deb'], -# uris => ['http://apt.puppet.com'], -# suites => ['jammy'], -# components => ['puppet8'], -# signed_by => ['/etc/apt/keyrings/puppetlabs.gpg'], -# } -# -# @example Ensure absence of a repo -# apt::source_deb822 { 'testing123': -# ensure => 'absent', -# } -# -# @param notify_update -# Specifies whether to trigger an `apt-get update` run. -# -# @param ensure -# Specifies whether the Apt source file should exist. -# -# @param enabled -# Enable or Disable the APT source. -# -# @param comment -# Provide a comment to the APT source file. -# -# @param types -# The package types this source manages. -# -# @param uris -# A list of URIs for the APT source. -# -# @param suites -# A list of suites for the APT source ('jammy-updates', 'bookworm', 'stable', etc.). -# -# @param components -# A list of components for the APT source ('main', 'contrib', 'non-free', etc.). -# -# @param architectures -# A list of supported architectures for the APT source ('amd64', 'i386', etc.). -# -# @param allow_insecure -# Specifies whether to allow downloads from insecure repositories. -# -# @param repo_trusted -# Consider the APT source trusted, even if authentication checks fail. -# -# @param check_valid_until -# Specifies whether to check if the package release date is valid. -# -# @param signed_by -# Absolute path to a file containing the PGP keyring used to sign this repository. -# -define apt::source_deb822 ( - Enum['present','absent'] $ensure = 'present', - Boolean $notify_update = true, - Boolean $enabled = true, - String $comment = $name, - Array[Enum['deb','deb-src'], 1, 2] $types = ['deb'], - Optional[Array[String]] $uris = undef, - Optional[Array[String]] $suites = undef, - Optional[Array[String]] $components = undef, - Optional[Array[String]] $architectures = undef, - Optional[Boolean] $allow_insecure = undef, - Optional[Boolean] $repo_trusted = undef, - Optional[Boolean] $check_valid_until = undef, - Optional[Variant[Array[Stdlib::AbsolutePath],String]] $signed_by = undef, -) { - case $ensure { - 'present': { - $header = epp('apt/_header.epp') - $source_content = epp('apt/source_deb822.epp', delete_undef_values({ - 'uris' => $uris, - 'suites' => $suites, - 'components' => $components, - 'types' => $types, - 'comment' => $comment, - 'enabled' => $enabled ? { true => 'yes', false => 'no' }, - 'architectures' => $architectures, - 'allow_insecure' => $allow_insecure ? { true => 'yes', false => 'no', default => undef }, - 'repo_trusted' => $repo_trusted ? { true => 'yes', false => 'no', default => undef }, - 'check_valid_until' => $check_valid_until ? { true => 'yes', false => 'no', default => undef }, - 'signed_by' => $signed_by, - } - ) - ) - } - 'absent': { - $header = undef - $source_content = undef - } - default: { - fail('Unexpected value for $ensure parameter.') - } - } - - apt::setting { "source-${name}": - ensure => $ensure, - content => "${header}${source_content}", - notify_update => $notify_update, - } -} From 0277fe991d728be275aae2a366ff54d59d1aef14 Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Mon, 15 Jul 2024 10:16:46 +0100 Subject: [PATCH 11/26] Update source_format parameter Match the possible values to the file suffix of the created source files. --- REFERENCE.md | 6 +++--- manifests/source.pp | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/REFERENCE.md b/REFERENCE.md index b63663575f..899a007086 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -1092,7 +1092,7 @@ apt::source { 'puppetlabs': ```puppet apt::source { 'puppetlabs': - source_format => 'deb822' + source_format => 'sources' uris => ['http://apt.puppetlabs.com'], suites => [$facts['os']['distro']['codename']], components => ['puppet8'], @@ -1130,11 +1130,11 @@ The following parameters are available in the `apt::source` defined type: ##### `source_format` -Data type: `Enum['legacy', 'deb822']` +Data type: `Enum['list', 'sources']` The file format to use for the apt source. See https://wiki.debian.org/SourcesList -Default value: `'legacy'` +Default value: `'list'` ##### `location` diff --git a/manifests/source.pp b/manifests/source.pp index d53528f8ab..8b0cff3915 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -23,7 +23,7 @@ # # @example Install the puppetlabs apt source (deb822 format) # apt::source { 'puppetlabs': -# source_format => 'deb822' +# source_format => 'sources' # uris => ['http://apt.puppetlabs.com'], # suites => [$facts['os']['distro']['codename']], # components => ['puppet8'], @@ -116,7 +116,7 @@ # Specifies whether to check if the package release date is valid. # define apt::source ( - Enum['legacy', 'deb822'] $source_format = 'legacy', + Enum['list', 'sources'] $source_format = 'list', Array[Enum['deb','deb-src'], 1, 2] $types = ['deb'], Optional[String[1]] $location = undef, String[1] $comment = $name, @@ -145,8 +145,8 @@ $_before = Apt::Setting["list-${title}"] case $source_format { - 'legacy': { - $_file_suffix = 'list' + 'list': { + $_file_suffix = $source_format if !$release { if fact('os.distro.codename') { @@ -295,7 +295,7 @@ } } } - 'deb822': { + 'sources': { if $pin { fail('apt::source::pin parameter is not supported with deb822 format') } @@ -308,7 +308,7 @@ if !$components { fail('You must specify a list of components for the apt::source resource') } - $_file_suffix = 'sources' + $_file_suffix = $source_format case $ensure { 'present': { $header = epp('apt/_header.epp') From 92c11937313058e16b923855184dc3f2fa23fe15 Mon Sep 17 00:00:00 2001 From: James Paton-Smith Date: Thu, 25 Jul 2024 17:12:05 +0100 Subject: [PATCH 12/26] Add forward-compatibility with deb822 Allow array values for certain parameters to allow easy switching between .list and .sources formats. --- manifests/source.pp | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/manifests/source.pp b/manifests/source.pp index 8b0cff3915..96ba0b163d 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -118,21 +118,21 @@ define apt::source ( Enum['list', 'sources'] $source_format = 'list', Array[Enum['deb','deb-src'], 1, 2] $types = ['deb'], - Optional[String[1]] $location = undef, + Optional[Variant[String, Array[String]]] $location = undef, String[1] $comment = $name, Optional[Array[String]] $uris = undef, # deb822 Boolean $enabled = true, # deb822 Enum['present', 'absent'] $ensure = present, - Optional[String[0]] $release = undef, + Optional[Variant[String[0], Array[String[0]]]] $release = undef, Optional[Array[String]] $suites = undef, # deb822 - String[1] $repos = 'main', + Variant[String[1], Array[String[1]]] $repos = 'main', Optional[Array[String]] $components = undef, # deb822 Hash $include = {}, Optional[Variant[String[1], Hash]] $key = undef, Optional[Stdlib::AbsolutePath] $keyring = undef, Optional[Variant[Stdlib::AbsolutePath,Array[String]]] $signed_by = undef, # deb822 - Optional[Variant[Hash, Integer, String[1]]] $pin = undef, - Optional[String[1]] $architecture = undef, + Optional[Variant[Hash, Numeric, String]] $pin = undef, + Optional[Variant[String, Array[String]]] $architecture = undef, Optional[Array[String]] $architectures = undef, # deb822 Optional[Boolean] $allow_unsigned = undef, Optional[Boolean] $repo_trusted = undef, # deb822 @@ -156,23 +156,40 @@ } } else { $_release = $release + # If the release is given as an array, use the first element only + if (type($_release) =~ Array) { + warning("Parameter, 'release', must be a string for 'list' format. Using the first array element instead.") + $_release = $_release[0] + } + } + + if (type($repos =~ Array)) { + $_repos = join($repos, ' ') + } + else { + $_repos = $repos } if $release =~ Pattern[/\/$/] { $_components = $_release } else { - $_components = "${_release} ${repos}" + $_components = "${_release} ${_repos}" } if $ensure == 'present' { if ! $location { fail('cannot create a source entry without specifying a location') } - elsif ($apt::proxy['https_acng']) and ($location =~ /(?i:^https:\/\/)/) { - $_location = regsubst($location, 'https://','http://HTTPS///') - } else { $_location = $location + # If the location is given as an array, use the first element only + if (type($_location) =~ Array) { + warning("Parameter, 'location', must be a string for 'list' format. Using the first array element instead.") + $_location = $_location[0] + } + if ($apt::proxy['https_acng']) and ($_location =~ /(?i:^https:\/\/)/) { + $_location = regsubst($_location, 'https://','http://HTTPS///') + } } } else { $_location = undef @@ -254,6 +271,9 @@ if $architecture { $_architecture = regsubst($architecture, '\baarch64\b', 'arm64') + if (type($_architecture) =~ Array) { + $_architecture = join($_architecture, ',') + } } else { $_architecture = undef } From fde9a1cd37a709730a880bb367dd49cb0c654d75 Mon Sep 17 00:00:00 2001 From: James Paton-Smith Date: Thu, 25 Jul 2024 17:46:40 +0100 Subject: [PATCH 13/26] Add backward-compatibility for deb822 sources Convert string values to arrays where possible and warn the user. --- manifests/source.pp | 54 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/manifests/source.pp b/manifests/source.pp index 96ba0b163d..eedb94d582 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -316,30 +316,62 @@ } } 'sources': { + $_file_suffix = $source_format + if $pin { - fail('apt::source::pin parameter is not supported with deb822 format') + warning('apt::source::pin parameter is not supported with deb822 format.') } - if !$uris { + + if !$location { fail('You must specify a list of URIs for the apt::source resource') } - if !$suites { - fail('You must specify a list of suites for the apt::source resource') + if (type($location =~ String)) { + warning('For deb822 sources, location must be specified as an array.') + $_location = [$location] } - if !$components { - fail('You must specify a list of components for the apt::source resource') + else { + $_location = $location } - $_file_suffix = $source_format + + if !$release { + if fact('os.distro.codename') { + $_release = [fact('os.distro.codename')] + } else { + fail('os.distro.codename fact not available: release parameter required') + } + } else { + if (type($release) =~ String) { + warning("For deb822 sources, 'release' must be specified as an array. Converting to array.") + $_release = [$release] + } + } + + if (type($repos) =~ String) { + warning("For deb822 sources, 'repos' must be specified as an array. Converting to array.") + $_repos = split($repos, /\s+/) + } else { + $_repos = $repos + } + + if (type($architecture =~ String)) { + warning("For deb822 sources, 'architecture' must be specified as an array. Converting to array.") + $_architecture = split($architecture, '[,]') + } + else { + $_architecture = $architecture + } + case $ensure { 'present': { $header = epp('apt/_header.epp') $source_content = epp('apt/source_deb822.epp', delete_undef_values({ - 'uris' => $uris, - 'suites' => $suites, - 'components' => $components, + 'uris' => $_location, + 'suites' => $_release, + 'components' => $_repos, 'types' => $types, 'comment' => $comment, 'enabled' => $enabled ? { true => 'yes', false => 'no' }, - 'architectures' => $architectures, + 'architectures' => $_architecture, 'allow_insecure' => $allow_insecure ? { true => 'yes', false => 'no', default => undef }, 'repo_trusted' => $repo_trusted ? { true => 'yes', false => 'no', default => undef }, 'check_valid_until' => $check_valid_until ? { true => 'yes', false => 'no', default => undef }, From 4b57c298c86f891133ab1b75d0414b92a92d22b0 Mon Sep 17 00:00:00 2001 From: James Paton-Smith Date: Thu, 25 Jul 2024 18:11:18 +0100 Subject: [PATCH 14/26] Fix logic --- manifests/source.pp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/manifests/source.pp b/manifests/source.pp index eedb94d582..992c155bd9 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -343,6 +343,8 @@ if (type($release) =~ String) { warning("For deb822 sources, 'release' must be specified as an array. Converting to array.") $_release = [$release] + } else { + $_release = $release } } @@ -353,14 +355,17 @@ $_repos = $repos } - if (type($architecture =~ String)) { - warning("For deb822 sources, 'architecture' must be specified as an array. Converting to array.") - $_architecture = split($architecture, '[,]') - } - else { + if $architecture != undef { + if (type($architecture =~ String)) { + warning("For deb822 sources, 'architecture' must be specified as an array. Converting to array.") + $_architecture = split($architecture, '[,]') + } + else { + $_architecture = $architecture + } + } else { $_architecture = $architecture } - case $ensure { 'present': { $header = epp('apt/_header.epp') From e610f76a220f17e3a7ba62169cc3f80801e45b0a Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Mon, 29 Jul 2024 15:10:37 +0100 Subject: [PATCH 15/26] Revert "Add forward-compatibility with deb822" This reverts commit 9d88e9392b816e6996998370ecc29a7f1a3dd9bb. --- manifests/source.pp | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/manifests/source.pp b/manifests/source.pp index 992c155bd9..578a07ac99 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -123,16 +123,16 @@ Optional[Array[String]] $uris = undef, # deb822 Boolean $enabled = true, # deb822 Enum['present', 'absent'] $ensure = present, - Optional[Variant[String[0], Array[String[0]]]] $release = undef, + Optional[String[0]] $release = undef, Optional[Array[String]] $suites = undef, # deb822 - Variant[String[1], Array[String[1]]] $repos = 'main', + String[1] $repos = 'main', Optional[Array[String]] $components = undef, # deb822 Hash $include = {}, Optional[Variant[String[1], Hash]] $key = undef, Optional[Stdlib::AbsolutePath] $keyring = undef, Optional[Variant[Stdlib::AbsolutePath,Array[String]]] $signed_by = undef, # deb822 Optional[Variant[Hash, Numeric, String]] $pin = undef, - Optional[Variant[String, Array[String]]] $architecture = undef, + Optional[String[1]] $architecture = undef, Optional[Array[String]] $architectures = undef, # deb822 Optional[Boolean] $allow_unsigned = undef, Optional[Boolean] $repo_trusted = undef, # deb822 @@ -156,40 +156,23 @@ } } else { $_release = $release - # If the release is given as an array, use the first element only - if (type($_release) =~ Array) { - warning("Parameter, 'release', must be a string for 'list' format. Using the first array element instead.") - $_release = $_release[0] - } - } - - if (type($repos =~ Array)) { - $_repos = join($repos, ' ') - } - else { - $_repos = $repos } if $release =~ Pattern[/\/$/] { $_components = $_release } else { - $_components = "${_release} ${_repos}" + $_components = "${_release} ${repos}" } if $ensure == 'present' { if ! $location { fail('cannot create a source entry without specifying a location') } + elsif ($apt::proxy['https_acng']) and ($location =~ /(?i:^https:\/\/)/) { + $_location = regsubst($location, 'https://','http://HTTPS///') + } else { $_location = $location - # If the location is given as an array, use the first element only - if (type($_location) =~ Array) { - warning("Parameter, 'location', must be a string for 'list' format. Using the first array element instead.") - $_location = $_location[0] - } - if ($apt::proxy['https_acng']) and ($_location =~ /(?i:^https:\/\/)/) { - $_location = regsubst($_location, 'https://','http://HTTPS///') - } } } else { $_location = undef @@ -271,9 +254,6 @@ if $architecture { $_architecture = regsubst($architecture, '\baarch64\b', 'arm64') - if (type($_architecture) =~ Array) { - $_architecture = join($_architecture, ',') - } } else { $_architecture = undef } From 48cb116261d0084742ebff3a2c0964d3cf9ba1fc Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Mon, 29 Jul 2024 16:08:01 +0100 Subject: [PATCH 16/26] Fix deb822 backward compatibility Correctly compare data type when generating deb822 sources Remove unused class parameters and descriptions --- manifests/source.pp | 44 ++++++++++---------------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/manifests/source.pp b/manifests/source.pp index 578a07ac99..804ab40dac 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -39,9 +39,6 @@ # @param types # DEB822: The package types this source manages. # -# @param uris -# DEB822: A list of URIs for the APT source. -# # @param enabled # DEB822: Enable or Disable the APT source. # @@ -54,15 +51,9 @@ # @param release # Specifies a distribution of the Apt repository. # -# @param suites -# DEB822: A list of suites for the APT source ('jammy-updates', 'bookworm', 'stable', etc.). -# # @param repos # Specifies a component of the Apt repository. # -# @param components -# DEB822: A list of components for the APT source ('main', 'contrib', 'non-free', etc.). -# # @param include # Configures include options. Valid options: a hash of available keys. # @@ -85,9 +76,6 @@ # This is not necessary if the key is installed with `key` param above. # See https://wiki.debian.org/DebianRepository/UseThirdParty for details. # -# @param signed_by -# DEB822: Either an absolute path to a PGP keyring file used to sign this repository OR a list of key fingerprints to trust. -# # @param pin # Creates a declaration of the apt::pin defined type. Valid options: a number or string to be passed to the `priority` parameter of the # `apt::pin` defined type, or a hash of `parameter => value` pairs to be passed to `apt::pin`'s corresponding parameters. @@ -97,15 +85,9 @@ # separated by commas (e.g., 'i386' or 'i386,alpha,powerpc'). # (if unspecified, Apt downloads information for all architectures defined in the Apt::Architectures option) # -# @param architectures -# DEB822: A list of supported architectures for the APT source ('amd64', 'i386', etc.). -# # @param allow_unsigned # Specifies whether to authenticate packages from this release, even if the Release file is not signed or the signature can't be checked. # -# @param repo_trusted -# DEB822: Consider the APT source trusted, even if authentication checks fail. -# # @param allow_insecure # Specifies whether to allow downloads from insecure repositories. # @@ -118,24 +100,18 @@ define apt::source ( Enum['list', 'sources'] $source_format = 'list', Array[Enum['deb','deb-src'], 1, 2] $types = ['deb'], - Optional[Variant[String, Array[String]]] $location = undef, + Optional[Variant[String[1], Array[String[1]]]] $location = undef, String[1] $comment = $name, - Optional[Array[String]] $uris = undef, # deb822 Boolean $enabled = true, # deb822 Enum['present', 'absent'] $ensure = present, - Optional[String[0]] $release = undef, - Optional[Array[String]] $suites = undef, # deb822 - String[1] $repos = 'main', - Optional[Array[String]] $components = undef, # deb822 + Optional[Variant[String[0], Array[String[0]]]] $release = undef, + Variant[String[1], Array[String[1]]] $repos = 'main', Hash $include = {}, Optional[Variant[String[1], Hash]] $key = undef, Optional[Stdlib::AbsolutePath] $keyring = undef, - Optional[Variant[Stdlib::AbsolutePath,Array[String]]] $signed_by = undef, # deb822 Optional[Variant[Hash, Numeric, String]] $pin = undef, - Optional[String[1]] $architecture = undef, - Optional[Array[String]] $architectures = undef, # deb822 + Optional[Variant[String[1], Array[String[1]]]] $architecture = undef, Optional[Boolean] $allow_unsigned = undef, - Optional[Boolean] $repo_trusted = undef, # deb822 Optional[Boolean] $allow_insecure = undef, Optional[Boolean] $check_valid_until = undef, Boolean $notify_update = true, @@ -305,7 +281,7 @@ if !$location { fail('You must specify a list of URIs for the apt::source resource') } - if (type($location =~ String)) { + if (type($location, 'generalized') !~ Type[Array]) { warning('For deb822 sources, location must be specified as an array.') $_location = [$location] } @@ -320,7 +296,7 @@ fail('os.distro.codename fact not available: release parameter required') } } else { - if (type($release) =~ String) { + if (type($release, 'generalized') !~ Type[Array]) { warning("For deb822 sources, 'release' must be specified as an array. Converting to array.") $_release = [$release] } else { @@ -328,7 +304,7 @@ } } - if (type($repos) =~ String) { + if (type($repos, 'generalized') !~ Type[Array]) { warning("For deb822 sources, 'repos' must be specified as an array. Converting to array.") $_repos = split($repos, /\s+/) } else { @@ -336,7 +312,7 @@ } if $architecture != undef { - if (type($architecture =~ String)) { + if (type($architecture, 'generalized') !~ Type[Array]) { warning("For deb822 sources, 'architecture' must be specified as an array. Converting to array.") $_architecture = split($architecture, '[,]') } @@ -358,9 +334,9 @@ 'enabled' => $enabled ? { true => 'yes', false => 'no' }, 'architectures' => $_architecture, 'allow_insecure' => $allow_insecure ? { true => 'yes', false => 'no', default => undef }, - 'repo_trusted' => $repo_trusted ? { true => 'yes', false => 'no', default => undef }, + 'repo_trusted' => $allow_unsigned ? { true => 'yes', false => 'no', default => undef }, 'check_valid_until' => $check_valid_until ? { true => 'yes', false => 'no', default => undef }, - 'signed_by' => $signed_by, + 'signed_by' => $keyring, } ) ) From 770d3f167ce25dfb6a5942f10d7e1d553dc7ed9a Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Tue, 30 Jul 2024 09:35:07 +0100 Subject: [PATCH 17/26] Update puppet-strings and logic Remove references to unused deb822 parameters Update parameter descriptions Update deb822 example Update warnings for $pin and $key usage with deb822. Currently unsupported Don't fail if $location is missing unless $ensure is 'present' --- REFERENCE.md | 78 ++++++++------------------------------------- manifests/source.pp | 23 ++++++++----- 2 files changed, 29 insertions(+), 72 deletions(-) diff --git a/REFERENCE.md b/REFERENCE.md index 899a007086..a305b1b9b8 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -13,6 +13,7 @@ #### Private Classes +* `apt::params`: Provides defaults for the Apt module parameters. * `apt::update`: Updates the list of available packages using apt-get update. ### Defined types @@ -1093,10 +1094,9 @@ apt::source { 'puppetlabs': ```puppet apt::source { 'puppetlabs': source_format => 'sources' - uris => ['http://apt.puppetlabs.com'], - suites => [$facts['os']['distro']['codename']], - components => ['puppet8'], - signed_by => '/etc/apt/keyrings/puppetlabs.gpg', + location => ['http://apt.puppetlabs.com'], + repos => ['puppet8'], + keyring => '/etc/apt/keyrings/puppetlabs.gpg', } ``` @@ -1107,23 +1107,17 @@ The following parameters are available in the `apt::source` defined type: * [`source_format`](#-apt--source--source_format) * [`location`](#-apt--source--location) * [`types`](#-apt--source--types) -* [`uris`](#-apt--source--uris) * [`enabled`](#-apt--source--enabled) * [`comment`](#-apt--source--comment) * [`ensure`](#-apt--source--ensure) * [`release`](#-apt--source--release) -* [`suites`](#-apt--source--suites) * [`repos`](#-apt--source--repos) -* [`components`](#-apt--source--components) * [`include`](#-apt--source--include) * [`key`](#-apt--source--key) * [`keyring`](#-apt--source--keyring) -* [`signed_by`](#-apt--source--signed_by) * [`pin`](#-apt--source--pin) * [`architecture`](#-apt--source--architecture) -* [`architectures`](#-apt--source--architectures) * [`allow_unsigned`](#-apt--source--allow_unsigned) -* [`repo_trusted`](#-apt--source--repo_trusted) * [`allow_insecure`](#-apt--source--allow_insecure) * [`notify_update`](#-apt--source--notify_update) * [`check_valid_until`](#-apt--source--check_valid_until) @@ -1138,9 +1132,10 @@ Default value: `'list'` ##### `location` -Data type: `Optional[String[1]]` +Data type: `Optional[Variant[String[1], Array[String[1]]]]` -Required, unless ensure is set to 'absent'. Specifies an Apt repository. +Required, unless ensure is set to 'absent'. Specifies an Apt repository. Valid options: a string containing a repository URL. +DEB822: Supports an array of URL values Default value: `undef` @@ -1152,14 +1147,6 @@ DEB822: The package types this source manages. Default value: `['deb']` -##### `uris` - -Data type: `Optional[Array[String]]` - -DEB822: A list of URIs for the APT source. - -Default value: `undef` - ##### `enabled` Data type: `Boolean` @@ -1186,36 +1173,22 @@ Default value: `present` ##### `release` -Data type: `Optional[String[0]]` +Data type: `Optional[Variant[String[0], Array[String[0]]]]` Specifies a distribution of the Apt repository. - -Default value: `undef` - -##### `suites` - -Data type: `Optional[Array[String]]` - -DEB822: A list of suites for the APT source ('jammy-updates', 'bookworm', 'stable', etc.). +DEB822: Supports an array of values Default value: `undef` ##### `repos` -Data type: `String[1]` +Data type: `Variant[String[1], Array[String[1]]]` Specifies a component of the Apt repository. +DEB822: Supports an array of values Default value: `'main'` -##### `components` - -Data type: `Optional[Array[String]]` - -DEB822: A list of components for the APT source ('main', 'contrib', 'non-free', etc.). - -Default value: `undef` - ##### `include` Data type: `Hash` @@ -1252,17 +1225,9 @@ See https://wiki.debian.org/DebianRepository/UseThirdParty for details. Default value: `undef` -##### `signed_by` - -Data type: `Optional[Variant[Stdlib::AbsolutePath,Array[String]]]` - -DEB822: Either an absolute path to a PGP keyring file used to sign this repository OR a list of key fingerprints to trust. - -Default value: `undef` - ##### `pin` -Data type: `Optional[Variant[Hash, Integer, String[1]]]` +Data type: `Optional[Variant[Hash, Numeric, String]]` Creates a declaration of the apt::pin defined type. Valid options: a number or string to be passed to the `priority` parameter of the `apt::pin` defined type, or a hash of `parameter => value` pairs to be passed to `apt::pin`'s corresponding parameters. @@ -1271,19 +1236,12 @@ Default value: `undef` ##### `architecture` -Data type: `Optional[String[1]]` +Data type: `Optional[Variant[String[1], Array[String[1]]]]` Tells Apt to only download information for specified architectures. Valid options: a string containing one or more architecture names, separated by commas (e.g., 'i386' or 'i386,alpha,powerpc'). (if unspecified, Apt downloads information for all architectures defined in the Apt::Architectures option) - -Default value: `undef` - -##### `architectures` - -Data type: `Optional[Array[String]]` - -DEB822: A list of supported architectures for the APT source ('amd64', 'i386', etc.). +DEB822: Supports an array of values Default value: `undef` @@ -1295,14 +1253,6 @@ Specifies whether to authenticate packages from this release, even if the Releas Default value: `undef` -##### `repo_trusted` - -Data type: `Optional[Boolean]` - -DEB822: Consider the APT source trusted, even if authentication checks fail. - -Default value: `undef` - ##### `allow_insecure` Data type: `Optional[Boolean]` diff --git a/manifests/source.pp b/manifests/source.pp index 804ab40dac..33501b28d6 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -24,10 +24,9 @@ # @example Install the puppetlabs apt source (deb822 format) # apt::source { 'puppetlabs': # source_format => 'sources' -# uris => ['http://apt.puppetlabs.com'], -# suites => [$facts['os']['distro']['codename']], -# components => ['puppet8'], -# signed_by => '/etc/apt/keyrings/puppetlabs.gpg', +# location => ['http://apt.puppetlabs.com'], +# repos => ['puppet8'], +# keyring => '/etc/apt/keyrings/puppetlabs.gpg', # } # # @param source_format @@ -35,6 +34,7 @@ # # @param location # Required, unless ensure is set to 'absent'. Specifies an Apt repository. Valid options: a string containing a repository URL. +# DEB822: Supports an array of URL values # # @param types # DEB822: The package types this source manages. @@ -50,9 +50,11 @@ # # @param release # Specifies a distribution of the Apt repository. +# DEB822: Supports an array of values # # @param repos # Specifies a component of the Apt repository. +# DEB822: Supports an array of values # # @param include # Configures include options. Valid options: a hash of available keys. @@ -84,6 +86,7 @@ # Tells Apt to only download information for specified architectures. Valid options: a string containing one or more architecture names, # separated by commas (e.g., 'i386' or 'i386,alpha,powerpc'). # (if unspecified, Apt downloads information for all architectures defined in the Apt::Architectures option) +# DEB822: Supports an array of values # # @param allow_unsigned # Specifies whether to authenticate packages from this release, even if the Release file is not signed or the signature can't be checked. @@ -275,11 +278,15 @@ $_file_suffix = $source_format if $pin { - warning('apt::source::pin parameter is not supported with deb822 format.') + warning("'pin' parameter is not supported with deb822 format.") } - - if !$location { - fail('You must specify a list of URIs for the apt::source resource') + if $key { + warning("'key' parameter is not supported with deb822 format.") + } + if $ensure == 'present' { + if ! $location { + fail('cannot create a source entry without specifying a location') + } } if (type($location, 'generalized') !~ Type[Array]) { warning('For deb822 sources, location must be specified as an array.') From f809e850e4272861ed95ec355bf581e777cb44e7 Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Tue, 30 Jul 2024 09:47:29 +0100 Subject: [PATCH 18/26] Remove unused spec test --- spec/defines/source_deb822_spec.rb | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 spec/defines/source_deb822_spec.rb diff --git a/spec/defines/source_deb822_spec.rb b/spec/defines/source_deb822_spec.rb deleted file mode 100644 index 87060ba406..0000000000 --- a/spec/defines/source_deb822_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe 'apt::source_deb822' do - let(:title) { 'namevar' } - let(:params) do - {} - end - - on_supported_os.each do |os, os_facts| - context "on #{os}" do - let(:facts) { os_facts } - - it { is_expected.to compile } - end - end -end From 9bdd389908384de4223ee1acc3d7141431123375 Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Tue, 30 Jul 2024 11:22:33 +0100 Subject: [PATCH 19/26] Add unit testing for deb822 sources --- spec/defines/source_spec.rb | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/spec/defines/source_spec.rb b/spec/defines/source_spec.rb index 5268c03a04..741e774e01 100644 --- a/spec/defines/source_spec.rb +++ b/spec/defines/source_spec.rb @@ -416,4 +416,63 @@ it { is_expected.to contain_apt__setting("list-#{title}").with_notify_update(false) } end end + + describe 'deb822 sources' do + let :params do + { + source_format: 'sources', + } + end + + context 'basic deb822 source' do + let :params do + super().merge({ + location: ['http://debian.mirror.iweb.ca/debian/'], + repos: ['main', 'contrib', 'non-free'] + }) + end + + it { is_expected.to contain_apt__setting("sources-#{title}").with_notify_update(true) } + end + + context 'complex deb822 source' do + let :params do + super().merge({ + types: ['deb', 'deb-src'], + location: ['http://fr.debian.org/debian', 'http://de.debian.org/debian'], + release: ['stable', 'stable-updates', 'stable-backports'], + repos: ['main', 'contrib', 'non-free'], + architecture: ['amd64', 'i386'], + allow_unsigned: true, + notify_update: false + }) + end + + it { is_expected.to contain_apt__setting("sources-#{title}").with_notify_update(false) } + it { is_expected.to contain_apt__setting("sources-#{title}").with_content(%r{Enabled: yes}) } + it { is_expected.to contain_apt__setting("sources-#{title}").with_content(%r{Types: deb deb-src}) } + it { is_expected.to contain_apt__setting("sources-#{title}").with_content(%r{URIs: http://fr.debian.org/debian http://de.debian.org/debian}) } + it { is_expected.to contain_apt__setting("sources-#{title}").with_content(%r{Suites: stable stable-updates stable-backports}) } + it { is_expected.to contain_apt__setting("sources-#{title}").with_content(%r{Components: main contrib non-free}) } + it { is_expected.to contain_apt__setting("sources-#{title}").with_content(%r{Architectures: amd64 i386}) } + it { is_expected.to contain_apt__setting("sources-#{title}").with_content(%r{Trusted: yes}) } + end + + context '.list backwards compatibility' do + let :params do + super().merge({ + location: 'http://debian.mirror.iweb.ca/debian/', + release: 'unstable', + repos: 'main contrib non-free', + key: { + id: 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', + server: 'keyserver.ubuntu.com', + }, + pin: '-10' + }) + end + + it { is_expected.to contain_apt__setting("sources-#{title}").with_notify_update(true) } + end + end end From fc39d2957f0982c6eb73fcc909e27011fb8d070b Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Tue, 30 Jul 2024 11:22:46 +0100 Subject: [PATCH 20/26] Update README.md with deb822 sources example --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 44cd89d05c..feb82889fe 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,27 @@ apt::source { 'puppetlabs': +### Generating a DEB822 .sources file + +You can also generate a DEB822 format .sources file. This example covers most of the available options. + +Use the `source_format` parameter to choose between 'list' and 'sources' (DEB822) formats. +```puppet +apt::source { 'debian': + source_format => 'sources' + comment => 'Official Debian Repository', + enabled => true, + types => ['deb', 'deb-src'], + location => ['http://fr.debian.org/debian', 'http://de.debian.org/debian'] + release => ['stable', 'stable-updates', 'stable-backports'], + repos => ['main', 'contrib', 'non-free'], + architecture => ['amd64', 'i386'], + allow_unsigned => true, + keyring => '/etc/apt/keyrings/debian.gpg' + notify_update => false +} +``` + ### Configure Apt from Hiera Instead of specifying your sources directly as resources, you can instead just include the `apt` class, which will pick up the values automatically from hiera. From 214eaa21680451002341a1fab594a173b85501b7 Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Tue, 30 Jul 2024 11:30:38 +0100 Subject: [PATCH 21/26] Fix unit test syntax --- spec/defines/source_spec.rb | 50 +++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/spec/defines/source_spec.rb b/spec/defines/source_spec.rb index 741e774e01..9c619439c0 100644 --- a/spec/defines/source_spec.rb +++ b/spec/defines/source_spec.rb @@ -426,10 +426,12 @@ context 'basic deb822 source' do let :params do - super().merge({ - location: ['http://debian.mirror.iweb.ca/debian/'], - repos: ['main', 'contrib', 'non-free'] - }) + super().merge( + { + location: ['http://debian.mirror.iweb.ca/debian/'], + repos: ['main', 'contrib', 'non-free'] + }, + ) end it { is_expected.to contain_apt__setting("sources-#{title}").with_notify_update(true) } @@ -437,15 +439,17 @@ context 'complex deb822 source' do let :params do - super().merge({ - types: ['deb', 'deb-src'], - location: ['http://fr.debian.org/debian', 'http://de.debian.org/debian'], - release: ['stable', 'stable-updates', 'stable-backports'], - repos: ['main', 'contrib', 'non-free'], - architecture: ['amd64', 'i386'], - allow_unsigned: true, - notify_update: false - }) + super().merge( + { + types: ['deb', 'deb-src'], + location: ['http://fr.debian.org/debian', 'http://de.debian.org/debian'], + release: ['stable', 'stable-updates', 'stable-backports'], + repos: ['main', 'contrib', 'non-free'], + architecture: ['amd64', 'i386'], + allow_unsigned: true, + notify_update: false + }, + ) end it { is_expected.to contain_apt__setting("sources-#{title}").with_notify_update(false) } @@ -460,16 +464,18 @@ context '.list backwards compatibility' do let :params do - super().merge({ - location: 'http://debian.mirror.iweb.ca/debian/', - release: 'unstable', - repos: 'main contrib non-free', - key: { - id: 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', - server: 'keyserver.ubuntu.com', + super().merge( + { + location: 'http://debian.mirror.iweb.ca/debian/', + release: 'unstable', + repos: 'main contrib non-free', + key: { + id: 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', + server: 'keyserver.ubuntu.com', + }, + pin: '-10' }, - pin: '-10' - }) + ) end it { is_expected.to contain_apt__setting("sources-#{title}").with_notify_update(true) } From 135da76cb092b8f99d7f264a1a3a2f36b49e8576 Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Thu, 1 Aug 2024 08:06:27 +0100 Subject: [PATCH 22/26] Re-apply commit 2faa817dcb05821bd9c27bbe8bf1955e6b2442f2 eliminate params.pp and create_resources() params.pp and create_resources() are obsolete. This module was converted to non-params.pp style #667, but was reverted in #680. Using Hiera in modules and no params.pp are the preferred styles these days. --- manifests/params.pp | 111 -------------------------------------------- 1 file changed, 111 deletions(-) delete mode 100644 manifests/params.pp diff --git a/manifests/params.pp b/manifests/params.pp deleted file mode 100644 index 22f2af4e29..0000000000 --- a/manifests/params.pp +++ /dev/null @@ -1,111 +0,0 @@ -# @summary Provides defaults for the Apt module parameters. -# -# @api private -# -class apt::params { - if $facts['os']['family'] != 'Debian' { - fail('This module only works on Debian or derivatives like Ubuntu') - } - - $root = '/etc/apt' - $provider = '/usr/bin/apt-get' - $sources_list = "${root}/sources.list" - $sources_list_force = false - $sources_list_d = "${root}/sources.list.d" - $trusted_gpg_d = "${root}/trusted.gpg.d" - $conf_d = "${root}/apt.conf.d" - $preferences = "${root}/preferences" - $preferences_d = "${root}/preferences.d" - $apt_conf_d = "${root}/apt.conf.d" - $keyserver = 'keyserver.ubuntu.com' - $key_options = undef - $confs = {} - $update = {} - $purge = {} - $proxy = {} - $sources = {} - $keys = {} - $ppas = {} - $pins = {} - $settings = {} - $manage_auth_conf = true - $auth_conf_entries = [] - - $config_files = { - 'conf' => { - 'path' => $conf_d, - 'ext' => '', - }, - 'pref' => { - 'path' => $preferences_d, - 'ext' => '.pref', - }, - 'list' => { - 'path' => $sources_list_d, - 'ext' => '.list', - }, - 'sources' => { - 'path' => $sources_list_d, - 'ext' => '.sources', - }, - } - - $update_defaults = { - 'frequency' => 'reluctantly', - 'loglevel' => undef, - 'timeout' => undef, - 'tries' => undef, - } - - $proxy_defaults = { - 'ensure' => undef, - 'host' => undef, - 'port' => 8080, - 'https' => false, - 'https_acng' => false, - 'direct' => false, - } - - $purge_defaults = { - 'sources.list' => false, - 'sources.list.d' => false, - 'preferences' => false, - 'preferences.d' => false, - 'apt.conf.d' => false, - } - - $include_defaults = { - 'deb' => true, - 'src' => false, - } - - case $facts['os']['name'] { - 'Debian': { - $backports = { - 'location' => 'http://deb.debian.org/debian', - 'repos' => 'main contrib non-free', - } - $ppa_options = undef - $ppa_package = undef - $auth_conf_owner = '_apt' - } - 'Ubuntu': { - $backports = { - 'location' => 'http://archive.ubuntu.com/ubuntu', - 'repos' => 'main universe multiverse restricted', - } - $ppa_options = ['-y'] - $ppa_package = 'software-properties-common' - $auth_conf_owner = '_apt' - } - undef: { - fail('Unable to determine value for fact os[\"name\"]') - } - default: { - $ppa_options = undef - $ppa_package = undef - $backports = undef - $auth_conf_owner = 'root' - } - } -} From 940e935d8a68b36c430fd2691012e89b5b6e38df Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Thu, 1 Aug 2024 09:12:17 +0100 Subject: [PATCH 23/26] Update apt::config_files hash Add support for deb822 .sources files --- manifests/init.pp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/manifests/init.pp b/manifests/init.pp index a1b06fbb81..55b38ed085 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -213,6 +213,10 @@ 'path' => $sources_list_d, 'ext' => '.list', }, + 'sources' => { + 'path' => $sources_list_d, + 'ext' => '.sources', + }, }, Boolean $sources_list_force = false, Hash $source_key_defaults = { From ae62548c9f06e7fdac511678059f41d1e413d7ad Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Mon, 18 Nov 2024 13:26:47 +0000 Subject: [PATCH 24/26] Update data types and documentation Re-apply data-type changes for apt::source::pin from 1e1baadf8158a878562b8aab1924a3db5b777a0c Regenerate puppet strings to match. --- REFERENCE.md | 7 +++++-- manifests/source.pp | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/REFERENCE.md b/REFERENCE.md index a305b1b9b8..08dd08a356 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -13,7 +13,6 @@ #### Private Classes -* `apt::params`: Provides defaults for the Apt module parameters. * `apt::update`: Updates the list of available packages using apt-get update. ### Defined types @@ -403,6 +402,10 @@ Default value: 'path' => $sources_list_d, 'ext' => '.list', }, + 'sources' => { + 'path' => $sources_list_d, + 'ext' => '.sources', + }, } ``` @@ -1227,7 +1230,7 @@ Default value: `undef` ##### `pin` -Data type: `Optional[Variant[Hash, Numeric, String]]` +Data type: `Optional[Variant[Hash, Integer, String[1]]]` Creates a declaration of the apt::pin defined type. Valid options: a number or string to be passed to the `priority` parameter of the `apt::pin` defined type, or a hash of `parameter => value` pairs to be passed to `apt::pin`'s corresponding parameters. diff --git a/manifests/source.pp b/manifests/source.pp index 33501b28d6..70191993f7 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -112,7 +112,7 @@ Hash $include = {}, Optional[Variant[String[1], Hash]] $key = undef, Optional[Stdlib::AbsolutePath] $keyring = undef, - Optional[Variant[Hash, Numeric, String]] $pin = undef, + Optional[Variant[Hash, Integer, String[1]]] $pin = undef, Optional[Variant[String[1], Array[String[1]]]] $architecture = undef, Optional[Boolean] $allow_unsigned = undef, Optional[Boolean] $allow_insecure = undef, From 6f66c981ff7848fd846a213bfad95c3f9eef1f37 Mon Sep 17 00:00:00 2001 From: James McKenzie Date: Mon, 18 Nov 2024 14:31:42 +0000 Subject: [PATCH 25/26] Update source_deb822.epp template Remove leading whitespace --- templates/source_deb822.epp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/source_deb822.epp b/templates/source_deb822.epp index c580d2c75b..10802b05d5 100644 --- a/templates/source_deb822.epp +++ b/templates/source_deb822.epp @@ -32,5 +32,5 @@ Check-Valid-Until: <%= $check_valid_until %> Signed-By: <% if type($signed_by) =~ Type[Array] { -%><%- $signed_by.each |String $keyring| { -%><%= $keyring %> <% } -%> <%- } -%> <%- elsif type($signed_by) =~ Type[String] { -%> - <%= $signed_by -%> +<%= $signed_by -%> <%- }} %> From 27b25a3218d573a79b5d9baad0009c1dd4957c9a Mon Sep 17 00:00:00 2001 From: James McKenzie <51116897+jps-help@users.noreply.github.com> Date: Tue, 19 Nov 2024 08:48:21 +0000 Subject: [PATCH 26/26] Update manifests/setting.pp Simplify apt::setting logic Co-authored-by: Tim Meusel --- manifests/setting.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifests/setting.pp b/manifests/setting.pp index 2308296a45..f057d1aa2a 100644 --- a/manifests/setting.pp +++ b/manifests/setting.pp @@ -51,7 +51,7 @@ } } - if ($setting_type == 'list') or ($setting_type == 'pref') or ($setting_type == 'sources') { + if $setting_type in ['list', 'pref', 'sources'] { $_priority = '' } else { $_priority = $priority