"This change pins the puppetlabs-puppet_agent module to v4.12.1. Previosuly the fixut...
[puppet-modules/puppetlabs-apt.git] / manifests / source.pp
1 # @summary Manages the Apt sources in /etc/apt/sources.list.d/.
2 #
3 # @example Install the puppetlabs apt source
4 #   apt::source { 'puppetlabs':
5 #     location => 'http://apt.puppetlabs.com',
6 #     repos    => 'main',
7 #     key      => {
8 #       id     => '6F6B15509CF8E59E6E469F327F438280EF8D349F',
9 #       server => 'keyserver.ubuntu.com',
10 #     },
11 #   }
12 #
13 # @param location
14 #   Required, unless ensure is set to 'absent'. Specifies an Apt repository. Valid options: a string containing a repository URL.
15 #
16 # @param comment
17 #   Supplies a comment for adding to the Apt source file.
18 #
19 # @param ensure
20 #   Specifies whether the Apt source file should exist. Valid options: 'present' and 'absent'.
21 #
22 # @param release
23 #   Specifies a distribution of the Apt repository.
24 #
25 # @param repos
26 #   Specifies a component of the Apt repository.
27 #
28 # @param include
29 #   Configures include options. Valid options: a hash of available keys.
30 #
31 # @option include [Boolean] :deb
32 #   Specifies whether to request the distribution's compiled binaries. Default true.
33 #
34 # @option include [Boolean] :src
35 #   Specifies whether to request the distribution's uncompiled source code. Default false.
36 #
37 # @param key
38 #   Creates a declaration of the apt::key defined type. Valid options: a string to be passed to the `id` parameter of the `apt::key`
39 #   defined type, or a hash of `parameter => value` pairs to be passed to `apt::key`'s `id`, `server`, `content`, `source`, `weak_ssl`,
40 #   and/or `options` parameters.
41 #
42 # @param keyring
43 #   Absolute path to a file containing the PGP keyring used to sign this repository. Value is used to set signed-by on the source entry.
44 #   See https://wiki.debian.org/DebianRepository/UseThirdParty for details.
45 #
46 # @param pin
47 #   Creates a declaration of the apt::pin defined type. Valid options: a number or string to be passed to the `id` parameter of the
48 #   `apt::pin` defined type, or a hash of `parameter => value` pairs to be passed to `apt::pin`'s corresponding parameters.
49 #
50 # @param architecture
51 #   Tells Apt to only download information for specified architectures. Valid options: a string containing one or more architecture names,
52 #   separated by commas (e.g., 'i386' or 'i386,alpha,powerpc'). Default: undef (if unspecified, Apt downloads information for all architectures
53 #   defined in the Apt::Architectures option).
54 #
55 # @param allow_unsigned
56 #   Specifies whether to authenticate packages from this release, even if the Release file is not signed or the signature can't be checked.
57 #
58 # @param allow_insecure
59 #   Specifies whether to allow downloads from insecure repositories.
60 #
61 # @param notify_update
62 #   Specifies whether to trigger an `apt-get update` run.
63 #
64 # @param check_valid_until
65 #   Specifies whether to check if the package release date is valid. Defaults to `True`.
66 #
67 define apt::source (
68   Optional[String] $location                    = undef,
69   String $comment                               = $name,
70   String $ensure                                = present,
71   Optional[String] $release                     = undef,
72   String $repos                                 = 'main',
73   Variant[Hash] $include                        = {},
74   Optional[Variant[String, Hash]] $key          = undef,
75   Optional[Stdlib::AbsolutePath] $keyring       = undef,
76   Optional[Variant[Hash, Numeric, String]] $pin = undef,
77   Optional[String] $architecture                = undef,
78   Boolean $allow_unsigned                       = false,
79   Boolean $allow_insecure                       = false,
80   Boolean $notify_update                        = true,
81   Boolean $check_valid_until                    = true,
82 ) {
83   include apt
84
85   $_before = Apt::Setting["list-${title}"]
86
87   if !$release {
88     if fact('os.distro.codename') {
89       $_release = fact('os.distro.codename')
90     } else {
91       fail('os.distro.codename fact not available: release parameter required')
92     }
93   } else {
94     $_release = $release
95   }
96
97   if $ensure == 'present' {
98     if ! $location {
99       fail('cannot create a source entry without specifying a location')
100     }
101     elsif ($apt::proxy['https_acng']) and ($location =~ /(?i:^https:\/\/)/) {
102       $_location = regsubst($location, 'https://','http://HTTPS///')
103     }
104     else {
105       $_location = $location
106     }
107     # Newer oses, do not need the package for HTTPS transport.
108     $_transport_https_releases = ['9']
109     if (fact('os.release.major') in $_transport_https_releases) and $_location =~ /(?i:^https:\/\/)/ {
110       ensure_packages('apt-transport-https')
111       Package['apt-transport-https'] -> Class['apt::update']
112     }
113   } else {
114     $_location = undef
115   }
116
117   $includes = merge($apt::include_defaults, $include)
118
119   if $key and $keyring {
120     fail('parameters key and keyring are mutualy exclusive')
121   }
122
123   if $key {
124     if $key =~ Hash {
125       unless $key['id'] {
126         fail('key hash must contain at least an id entry')
127       }
128       $_key = merge($apt::source_key_defaults, $key)
129     } else {
130       $_key = { 'id' => assert_type(String[1], $key) }
131     }
132   }
133
134   $header = epp('apt/_header.epp')
135
136   if $architecture {
137     $_architecture = regsubst($architecture, '\baarch64\b', 'arm64')
138   } else {
139     $_architecture = undef
140   }
141
142   $sourcelist = epp('apt/source.list.epp', {
143       'comment'          => $comment,
144       'includes'         => $includes,
145       'options'          => delete_undef_values({
146           'arch'              => $_architecture,
147           'trusted'           => $allow_unsigned ? { true => 'yes', false => undef },
148           'allow-insecure'    => $allow_insecure ? { true => 'yes', false => undef },
149           'signed-by'         => $keyring,
150           'check-valid-until' => $check_valid_until? { true => undef, false => 'false' },
151         },
152       ),
153       'location'         => $_location,
154       'release'          => $_release,
155       'repos'            => $repos,
156     }
157   )
158
159   apt::setting { "list-${name}":
160     ensure        => $ensure,
161     content       => "${header}${sourcelist}",
162     notify_update => $notify_update,
163   }
164
165   if $pin {
166     if $pin =~ Hash {
167       $_pin = merge($pin, { 'ensure' => $ensure, 'before' => $_before })
168     } elsif ($pin =~ Numeric or $pin =~ String) {
169       $url_split = split($location, '[:\/]+')
170       $host      = $url_split[1]
171       $_pin = {
172         'ensure'   => $ensure,
173         'priority' => $pin,
174         'before'   => $_before,
175         'origin'   => $host,
176       }
177     } else {
178       fail('Received invalid value for pin parameter')
179     }
180     create_resources('apt::pin', { "${name}" => $_pin })
181   }
182
183   # We do not want to remove keys when the source is absent.
184   if $key and ($ensure == 'present') {
185     if $_key =~ Hash {
186       if $_key['ensure'] != undef {
187         $_ensure = $_key['ensure']
188       } else {
189         $_ensure = $ensure
190       }
191
192       apt::key { "Add key: ${$_key['id']} from Apt::Source ${title}":
193         ensure   => $_ensure,
194         id       => $_key['id'],
195         server   => $_key['server'],
196         content  => $_key['content'],
197         source   => $_key['source'],
198         options  => $_key['options'],
199         weak_ssl => $_key['weak_ssl'],
200         before   => $_before,
201       }
202     }
203   }
204 }