8145b7d4b6575c024c1435e803beb5ebda6ea334
[puppet-modules/puppetlabs-apt.git] / manifests / pin.pp
1 # @summary Manages Apt pins. Does not trigger an apt-get update run.
2 #
3 # @see http://linux.die.net/man/5/apt_preferences for context on these parameters
4 #
5 # @param ensure
6 #   Specifies whether the pin should exist. Valid options: 'file', 'present', and 'absent'.
7 #
8 # @param explanation
9 #   Supplies a comment to explain the pin. Default: "${caller_module_name}: ${name}".
10 #
11 # @param order
12 #   Determines the order in which Apt processes the pin file. Files with lower order numbers are loaded first.
13 #
14 # @param packages
15 #   Specifies which package(s) to pin.
16 #
17 # @param priority
18 #   Sets the priority of the package. If multiple versions of a given package are available, `apt-get` installs the one with the highest 
19 #   priority number (subject to dependency constraints). Valid options: an integer.
20 #
21 # @param release
22 #   Tells APT to prefer packages that support the specified release. Typical values include 'stable', 'testing', and 'unstable'.
23 #
24 # @param release_version
25 #   Tells APT to prefer packages that support the specified operating system release version (such as Debian release version 7).
26 #
27 # @param component
28 #   Names the licensing component associated with the packages in the directory tree of the Release file.
29 #
30 # @param originator
31 #   Names the originator of the packages in the directory tree of the Release file.
32 #
33 # @param label
34 #   Names the label of the packages in the directory tree of the Release file.
35 #
36 define apt::pin(
37   Optional[Enum['file', 'present', 'absent']] $ensure = present,
38   Optional[String] $explanation                       = undef,
39   Variant[Integer] $order                             = 50,
40   Variant[String, Array] $packages                    = '*',
41   Variant[Numeric, String] $priority                  = 0,
42   Optional[String] $release                           = '', # a=
43   Optional[String] $origin                            = '',
44   Optional[String] $version                           = '',
45   Optional[String] $codename                          = '', # n=
46   Optional[String] $release_version                   = '', # v=
47   Optional[String] $component                         = '', # c=
48   Optional[String] $originator                        = '', # o=
49   Optional[String] $label                             = '',  # l=
50 ) {
51
52   if $explanation {
53     $_explanation = $explanation
54   } else {
55     if defined('$caller_module_name') { # strict vars check
56       $_explanation = "${caller_module_name}: ${name}"
57     } else {
58       $_explanation = ": ${name}"
59     }
60   }
61
62   $pin_release_array = [
63     $release,
64     $codename,
65     $release_version,
66     $component,
67     $originator,
68     $label,
69   ]
70   $pin_release = join($pin_release_array, '')
71
72   # Read the manpage 'apt_preferences(5)', especially the chapter
73   # 'The Effect of APT Preferences' to understand the following logic
74   # and the difference between specific and general form
75   if $packages =~ Array {
76     $packages_string = join($packages, ' ')
77   } else {
78     $packages_string = $packages
79   }
80
81   if $packages_string != '*' { # specific form
82     if ( $pin_release != '' and ( $origin != '' or $version != '' )) or
83       ( $version != '' and ( $pin_release != '' or $origin != '' )) {
84       fail(translate('parameters release, origin, and version are mutually exclusive'))
85     }
86   } else { # general form
87     if $version != '' {
88       fail(translate('parameter version cannot be used in general form'))
89     }
90     if ( $pin_release != '' and $origin != '' ) {
91       fail(translate('parameters release and origin are mutually exclusive'))
92     }
93   }
94
95   # According to man 5 apt_preferences:
96   # The files have either no or "pref" as filename extension
97   # and only contain alphanumeric, hyphen (-), underscore (_) and period
98   # (.) characters. Otherwise APT will print a notice that it has ignored a
99   # file, unless that file matches a pattern in the
100   # Dir::Ignore-Files-Silently configuration list - in which case it will
101   # be silently ignored.
102   $file_name = regsubst($title, '[^0-9a-z\-_\.]', '_', 'IG')
103
104   $headertmp = epp('apt/_header.epp')
105
106   $pinpreftmp = epp('apt/pin.pref.epp', {
107       'name'            => $name,
108       'pin_release'     => $pin_release,
109       'release'         => $release,
110       'codename'        => $codename,
111       'release_version' => $release_version,
112       'component'       => $component,
113       'originator'      => $originator,
114       'label'           => $label,
115       'version'         => $version,
116       'origin'          => $origin,
117       'explanation'     => $_explanation,
118       'packages_string' => $packages_string,
119       'priority'        => $priority,
120   })
121
122   apt::setting { "pref-${file_name}":
123     ensure        => $ensure,
124     priority      => $order,
125     content       => "${headertmp}${pinpreftmp}",
126     notify_update => false,
127   }
128 }