diff --git a/README.md b/README.md index 53f0228..c37101f 100644 --- a/README.md +++ b/README.md @@ -1,321 +1,337 @@ # apt #### Table of Contents - 1. [Module Description - What the module does and why it is useful](#module-description) 1. [Setup - The basics of getting started with apt](#setup) * [What apt affects](#what-apt-affects) * [Beginning with apt](#beginning-with-apt) 1. [Usage - Configuration options and additional functionality](#usage) * [Add GPG keys](#add-gpg-keys) * [Prioritize backports](#prioritize-backports) * [Update the list of packages](#update-the-list-of-packages) * [Pin a specific release](#pin-a-specific-release) * [Add a Personal Package Archive repository](#add-a-personal-package-archive-repository) * [Configure Apt from Hiera](#configure-apt-from-hiera) * [Replace the default sources.list file](#replace-the-default-sourceslist-file) 1. [Reference - An under-the-hood peek at what the module is doing and how](#reference) 1. [Limitations - OS compatibility, etc.](#limitations) 1. [Development - Guide for contributing to the module](#development) + ## Module Description The apt module lets you use Puppet to manage APT (Advanced Package Tool) sources, keys, and other configuration options. APT is a package manager available on Debian, Ubuntu, and several other operating systems. The apt module provides a series of classes, defines, types, and facts to help you automate APT package management. -**Note**: For this module to correctly autodetect which version of Debian/Ubuntu (or derivative) you're running, you need to make sure the 'lsb-release' package is installed. We highly recommend you either make this part of your provisioning layer, if you run many Debian or derivative systems, or ensure that you have Facter 2.2.0 or later installed, which will pull this dependency in for you. +**Note**: Prior to Puppet 7, for this module to correctly autodetect which version of +Debian/Ubuntu (or derivative) you're running, you need to make sure the `lsb-release` package is +installed. With Puppet 7 the `lsb-release` package is not needed. + ## Setup + ### What apt affects * Your system's `preferences` file and `preferences.d` directory * Your system's `sources.list` file and `sources.list.d` directory * Your system's `apt.conf.d` directory * System repositories * Authentication keys **Note:** This module offers `purge` parameters which, if set to `true`, **destroy** any configuration on the node's `sources.list(.d)`, `preferences(.d)` and `apt.conf.d` that you haven't declared through Puppet. The default for these parameters is `false`. + ### Beginning with apt To use the apt module with default parameters, declare the `apt` class. ```puppet include apt ``` **Note:** The main `apt` class is required by all other classes, types, and defined types in this module. You must declare it whenever you use the module. + ## Usage + ### Add GPG keys **Warning:** Using short key IDs presents a serious security issue, potentially leaving you open to collision attacks. We recommend you always use full fingerprints to identify your GPG keys. This module allows short keys, but issues a security warning if you use them. Declare the `apt::key` defined type: ```puppet apt::key { 'puppetlabs': id => '6F6B15509CF8E59E6E469F327F438280EF8D349F', server => 'pgp.mit.edu', options => 'http-proxy="http://proxyuser:proxypass@example.org:3128"', } ``` + ### Prioritize backports ```puppet class { 'apt::backports': pin => 500, } ``` By default, the `apt::backports` class drops a pin file for backports, pinning it to a priority of 200. This is lower than the normal default of 500, so packages with `ensure => latest` don't get upgraded from backports without your explicit permission. If you raise the priority through the `pin` parameter to 500, normal policy goes into effect and Apt installs or upgrades to the newest version. This means that if a package is available from backports, it and its dependencies are pulled in from backports unless you explicitly set the `ensure` attribute of the `package` resource to `installed`/`present` or a specific version. + ### Update the list of packages -By default, Puppet runs `apt-get update` on the first Puppet run after you include the `apt` class, and anytime `notify => Exec['apt_update']` occurs; i.e., whenever config files get updated or other relevant changes occur. If you set `update['frequency']` to 'always', the update runs on every Puppet run. You can also set `update['frequency']` to 'daily' or 'weekly': +By default, Puppet runs `apt-get update` on the first Puppet run after you include the `apt` class, and anytime `notify => Exec['apt_update']` occurs; i.e., whenever config files get updated or other relevant changes occur. If you set `update['frequency']` to 'always', the update runs on every Puppet run. You can also set `update['frequency']` to 'daily' or 'weekly': ```puppet class { 'apt': update => { frequency => 'daily', }, } ``` + When `Exec['apt_update']` is triggered, it generates a `notice`-level message. Because the default [logging level for agents](https://puppet.com/docs/puppet/latest/configuration.html#loglevel) is `notice`, this causes the repository update to appear in agent logs. To silence these updates from the default log output, set the [loglevel](https://puppet.com/docs/puppet/latest/metaparameter.html#loglevel) metaparameter for `Exec['apt_update']` above the agent logging level: ```puppet class { 'apt': update => { frequency => 'daily', loglevel => 'debug', }, } ``` > **NOTE:** Every `Exec['apt_update']` run will generate a corrective change, even if the apt caches are not updated. For example, setting an update frequency of `always` can result in every Puppet run resulting in a corrective change. This is a known issue. For details, see [MODULES-10763](https://tickets.puppetlabs.com/browse/MODULES-10763). + ### Pin a specific release ```puppet apt::pin { 'karmic': priority => 700 } apt::pin { 'karmic-updates': priority => 700 } apt::pin { 'karmic-security': priority => 700 } ``` You can also specify more complex pins using distribution properties: ```puppet apt::pin { 'stable': priority => -10, originator => 'Debian', release_version => '3.0', component => 'main', label => 'Debian' } ``` To pin multiple packages, pass them to the `packages` parameter as an array or a space-delimited string. + ### Add a Personal Package Archive (PPA) repository ```puppet apt::ppa { 'ppa:drizzle-developers/ppa': } ``` ### Add an Apt source to `/etc/apt/sources.list.d/` ```puppet apt::source { 'debian_unstable': comment => 'This is the iWeb Debian unstable mirror', location => 'http://debian.mirror.iweb.ca/debian/', release => 'unstable', repos => 'main contrib non-free', pin => '-10', key => { 'id' => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', 'server' => 'subkeys.pgp.net', }, include => { 'src' => true, 'deb' => true, }, } ``` To use the Puppet Apt repository as a source: ```puppet apt::source { 'puppetlabs': location => 'http://apt.puppetlabs.com', repos => 'main', key => { 'id' => '6F6B15509CF8E59E6E469F327F438280EF8D349F', 'server' => 'pgp.mit.edu', }, } ``` + ### 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. ```yaml apt::sources: 'debian_unstable': comment: 'This is the iWeb Debian unstable mirror' location: 'http://debian.mirror.iweb.ca/debian/' release: 'unstable' repos: 'main contrib non-free' pin: '-10' key: id: 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553' server: 'subkeys.pgp.net' include: src: true deb: true 'puppetlabs': location: 'http://apt.puppetlabs.com' repos: 'main' key: id: '6F6B15509CF8E59E6E469F327F438280EF8D349F' server: 'pgp.mit.edu' ``` + ### Replace the default `sources.list` file The following example replaces the default `/etc/apt/sources.list`. Along with this code, be sure to use the `purge` parameter, or you might get duplicate source warnings when running Apt. ```puppet -apt::source { "archive.ubuntu.com-${lsbdistcodename}": +apt::source { "archive.ubuntu.com-${facts['os']['distro']['codename']}": location => 'http://archive.ubuntu.com/ubuntu', key => '630239CC130E1A7FD81A27B140976EAF437D05B5', repos => 'main universe multiverse restricted', } -apt::source { "archive.ubuntu.com-${lsbdistcodename}-security": +apt::source { "archive.ubuntu.com-${facts['os']['distro']['codename']}-security": location => 'http://archive.ubuntu.com/ubuntu', key => '630239CC130E1A7FD81A27B140976EAF437D05B5', repos => 'main universe multiverse restricted', - release => "${lsbdistcodename}-security" + release => "${facts['os']['distro']['codename']}-security" } -apt::source { "archive.ubuntu.com-${lsbdistcodename}-updates": +apt::source { "archive.ubuntu.com-${facts['os']['distro']['codename']}-updates": location => 'http://archive.ubuntu.com/ubuntu', key => '630239CC130E1A7FD81A27B140976EAF437D05B5', repos => 'main universe multiverse restricted', - release => "${lsbdistcodename}-updates" + release => "${facts['os']['distro']['codename']}-updates" } -apt::source { "archive.ubuntu.com-${lsbdistcodename}-backports": +apt::source { "archive.ubuntu.com-${facts['os']['distro']['codename']}-backports": location => 'http://archive.ubuntu.com/ubuntu', key => '630239CC130E1A7FD81A27B140976EAF437D05B5', repos => 'main universe multiverse restricted', - release => "${lsbdistcodename}-backports" + release => "${facts['os']['distro']['codename']}-backports" } ``` ### Manage login configuration settings for an APT source or proxy in `/etc/apt/auth.conf` Starting with APT version 1.5, you can define login configuration settings, such as username and password, for APT sources or proxies that require authentication in the `/etc/apt/auth.conf` file. This is preferable to embedding login information directly in `source.list` entries, which are usually world-readable. The `/etc/apt/auth.conf` file follows the format of netrc (used by ftp or curl) and has restrictive file permissions. See [here](https://manpages.debian.org/testing/apt/apt_auth.conf.5.en.html) for details. Use the optional `apt::auth_conf_entries` parameter to specify an array of hashes containing login configuration settings. These hashes may only contain the `machine`, `login` and `password` keys. ```puppet class { 'apt': auth_conf_entries => [ { 'machine' => 'apt-proxy.example.net', 'login' => 'proxylogin', 'password' => 'proxypassword', }, { 'machine' => 'apt.example.com/ubuntu', 'login' => 'reader', 'password' => 'supersecret', }, ], } ``` + ## Reference ### Facts * `apt_updates`: The number of installed packages with available updates from `upgrade`. * `apt_dist_updates`: The number of installed packages with available updates from `dist-upgrade`. * `apt_security_updates`: The number of installed packages with available security updates from `upgrade`. * `apt_security_dist_updates`: The number of installed packages with available security updates from `dist-upgrade`. * `apt_package_updates`: The names of all installed packages with available updates from `upgrade`. In Facter 2.0 and later this data is formatted as an array; in earlier versions it is a comma-delimited string. * `apt_package_dist_updates`: The names of all installed packages with available updates from `dist-upgrade`. In Facter 2.0 and later this data is formatted as an array; in earlier versions it is a comma-delimited string. * `apt_update_last_success`: The date, in epochtime, of the most recent successful `apt-get update` run (based on the mtime of /var/lib/apt/periodic/update-success-stamp). * `apt_reboot_required`: Determines if a reboot is necessary after updates have been installed. ### More Information See [REFERENCE.md](https://github.com/puppetlabs/puppetlabs-apt/blob/main/REFERENCE.md) for all other reference documentation. - + + ## Limitations This module is not designed to be split across [run stages](https://docs.puppetlabs.com/puppet/latest/reference/lang_run_stages.html). For an extensive list of supported operating systems, see [metadata.json](https://github.com/puppetlabs/puppetlabs-apt/blob/main/metadata.json) ### Adding new sources or PPAs If you are adding a new source or PPA and trying to install packages from the new source or PPA on the same Puppet run, your `package` resource should depend on `Class['apt::update']`, as well as depending on the `Apt::Source` or the `Apt::Ppa`. You can also add [collectors](https://docs.puppetlabs.com/puppet/latest/reference/lang_collectors.html) to ensure that all packages happen after `apt::update`, but this can lead to dependency cycles and has implications for [virtual resources](https://docs.puppetlabs.com/puppet/latest/reference/lang_collectors.html#behavior). Before running the command below, ensure that all packages have the provider set to apt. ```puppet Class['apt::update'] -> Package <| provider == 'apt' |> ``` ## Development Acceptance tests for this module leverage [puppet_litmus](https://github.com/puppetlabs/puppet_litmus). -To run the acceptance tests follow the instructions [here](https://github.com/puppetlabs/puppet_litmus/wiki/Tutorial:-use-Litmus-to-execute-acceptance-tests-with-a-sample-module-(MoTD)#install-the-necessary-gems-for-the-module). +To run the acceptance tests follow the instructions [here](https://puppetlabs.github.io/litmus/Running-acceptance-tests.html). You can also find a tutorial and walkthrough of using Litmus and the PDK on [YouTube](https://www.youtube.com/watch?v=FYfR7ZEGHoE). If you run into an issue with this module, or if you would like to request a feature, please [file a ticket](https://tickets.puppetlabs.com/browse/MODULES/). Every Monday the Puppet IA Content Team has [office hours](https://puppet.com/community/office-hours) in the [Puppet Community Slack](http://slack.puppet.com/), alternating between an EMEA friendly time (1300 UTC) and an Americas friendly time (0900 Pacific, 1700 UTC). If you have problems getting this module up and running, please [contact Support](http://puppetlabs.com/services/customer-support). If you submit a change to this module, be sure to regenerate the reference documentation as follows: ```bash puppet strings generate --format markdown --out REFERENCE.md ``` diff --git a/REFERENCE.md b/REFERENCE.md index dc1e5ed..13f5f9a 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -1,1023 +1,1023 @@ # Reference ## Table of Contents ### Classes #### Public Classes * [`apt`](#apt): Main class, includes all other classes. * [`apt::backports`](#aptbackports): Manages backports. #### 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 * [`apt::conf`](#aptconf): Specifies a custom Apt configuration file. * [`apt::key`](#aptkey): Manages the GPG keys that Apt uses to authenticate packages. * [`apt::mark`](#aptmark): defined typeapt::mark * [`apt::pin`](#aptpin): Manages Apt pins. Does not trigger an apt-get update run. * [`apt::ppa`](#aptppa): Manages PPA repositories using `add-apt-repository`. Not supported on Debian. * [`apt::setting`](#aptsetting): Manages Apt configuration files. * [`apt::source`](#aptsource): Manages the Apt sources in /etc/apt/sources.list.d/. ### Resource types #### Public Resource types #### Private Resource types * `apt_key`: This type provides Puppet with the capabilities to manage GPG keys needed by apt to perform package validation. Apt has it's own GPG keyring that can be manipulated through the `apt-key` command. ### Data types * [`Apt::Auth_conf_entry`](#aptauth_conf_entry): Login configuration settings that are recorded in the file `/etc/apt/auth.conf`. * [`Apt::Proxy`](#aptproxy): Configures Apt to connect to a proxy server. ### Tasks * [`init`](#init): Allows you to perform apt functions ## Classes ### `apt` Main class, includes all other classes. * **See also** * https://docs.puppetlabs.com/references/latest/function.html#createresources * for the create resource function #### Parameters The following parameters are available in the `apt` class. ##### `provider` Data type: `String` Specifies the provider that should be used by apt::update. Default value: `$apt::params::provider` ##### `keyserver` Data type: `String` Specifies a keyserver to provide the GPG key. Valid options: a string containing a domain name or a full URL (http://, https://, or hkp://). Default value: `$apt::params::keyserver` ##### `key_options` Data type: `Optional[String]` Specifies the default options for apt::key resources. Default value: `$apt::params::key_options` ##### `ppa_options` Data type: `Optional[String]` Supplies options to be passed to the `add-apt-repository` command. Default value: `$apt::params::ppa_options` ##### `ppa_package` Data type: `Optional[String]` Names the package that provides the `apt-add-repository` command. Default value: `$apt::params::ppa_package` ##### `backports` Data type: `Optional[Hash]` Specifies some of the default parameters used by apt::backports. Valid options: a hash made up from the following keys: Options: * **:location** `String`: See apt::backports for documentation. * **:repos** `String`: See apt::backports for documentation. * **:key** `String`: See apt::backports for documentation. Default value: `$apt::params::backports` ##### `confs` Data type: `Hash` Creates new `apt::conf` resources. Valid options: a hash to be passed to the create_resources function linked above. Default value: `$apt::params::confs` ##### `update` Data type: `Hash` Configures various update settings. Valid options: a hash made up from the following keys: Options: * **:frequency** `String`: Specifies how often to run `apt-get update`. If the exec resource `apt_update` is notified, `apt-get update` runs regardless of this value. Valid options: 'always' (at every Puppet run); 'daily' (if the value of `apt_update_last_success` is less than current epoch time minus 86400); 'weekly' (if the value of `apt_update_last_success` is less than current epoch time minus 604800); and 'reluctantly' (only if the exec resource `apt_update` is notified). Default: 'reluctantly'. * **:loglevel** `Integer`: Specifies the log level of logs outputted to the console. Default: undef. * **:timeout** `Integer`: Specifies how long to wait for the update to complete before canceling it. Valid options: an integer, in seconds. Default: undef. * **:tries** `Integer`: Specifies how many times to retry the update after receiving a DNS or HTTP error. Default: undef. Default value: `$apt::params::update` ##### `purge` Data type: `Hash` Specifies whether to purge any existing settings that aren't managed by Puppet. Valid options: a hash made up from the following keys: Options: * **:sources.list** `Boolean`: Specifies whether to purge any unmanaged entries from sources.list. Default false. * **:sources.list.d** `Boolean`: Specifies whether to purge any unmanaged entries from sources.list.d. Default false. * **:preferences** `Boolean`: Specifies whether to purge any unmanaged entries from preferences. Default false. * **:preferences.d.** `Boolean`: Specifies whether to purge any unmanaged entries from preferences.d. Default false. Default value: `$apt::params::purge` ##### `proxy` Data type: `Apt::Proxy` Configures Apt to connect to a proxy server. Valid options: a hash matching the locally defined type apt::proxy. Default value: `$apt::params::proxy` ##### `sources` Data type: `Hash` Creates new `apt::source` resources. Valid options: a hash to be passed to the create_resources function linked above. Default value: `$apt::params::sources` ##### `keys` Data type: `Hash` Creates new `apt::key` resources. Valid options: a hash to be passed to the create_resources function linked above. Default value: `$apt::params::keys` ##### `ppas` Data type: `Hash` Creates new `apt::ppa` resources. Valid options: a hash to be passed to the create_resources function linked above. Default value: `$apt::params::ppas` ##### `pins` Data type: `Hash` Creates new `apt::pin` resources. Valid options: a hash to be passed to the create_resources function linked above. Default value: `$apt::params::pins` ##### `settings` Data type: `Hash` Creates new `apt::setting` resources. Valid options: a hash to be passed to the create_resources function linked above. Default value: `$apt::params::settings` ##### `manage_auth_conf` Data type: `Boolean` Specifies whether to manage the /etc/apt/auth.conf file. When true, the file will be overwritten with the entries specified in the auth_conf_entries parameter. When false, the file will be ignored (note that this does not set the file to absent. Default value: `$apt::params::manage_auth_conf` ##### `auth_conf_entries` Data type: `Array[Apt::Auth_conf_entry]` An optional array of login configuration settings (hashes) that are recorded in the file /etc/apt/auth.conf. This file has a netrc-like format (similar to what curl uses) and contains the login configuration for APT sources and proxies that require authentication. See https://manpages.debian.org/testing/apt/apt_auth.conf.5.en.html for details. If specified each hash must contain the keys machine, login and password and no others. Specifying manage_auth_conf and not specifying this parameter will set /etc/apt/auth.conf to absent. Default value: `$apt::params::auth_conf_entries` ##### `auth_conf_owner` Data type: `String` The owner of the file /etc/apt/auth.conf. Default: '_apt' or 'root' on old releases. Default value: `$apt::params::auth_conf_owner` ##### `root` Data type: `String` Specifies root directory of Apt executable. Default value: `$apt::params::root` ##### `sources_list` Data type: `String` Specifies the path of the sources_list file to use. Default value: `$apt::params::sources_list` ##### `sources_list_d` Data type: `String` Specifies the path of the sources_list.d file to use. Default value: `$apt::params::sources_list_d` ##### `conf_d` Data type: `String` Specifies the path of the conf.d file to use. Default value: `$apt::params::conf_d` ##### `preferences` Data type: `String` Specifies the path of the preferences file to use. Default value: `$apt::params::preferences` ##### `preferences_d` Data type: `String` Specifies the path of the preferences.d file to use. Default value: `$apt::params::preferences_d` ##### `config_files` Data type: `Hash` A hash made up of the various configuration files used by Apt. Default value: `$apt::params::config_files` ##### `sources_list_force` Data type: `Boolean` Specifies whether to perform force purge or delete. Default false. Default value: `$apt::params::sources_list_force` ##### `update_defaults` Data type: `Hash` Default value: `$apt::params::update_defaults` ##### `purge_defaults` Data type: `Hash` Default value: `$apt::params::purge_defaults` ##### `proxy_defaults` Data type: `Hash` Default value: `$apt::params::proxy_defaults` ##### `include_defaults` Data type: `Hash` Default value: `$apt::params::include_defaults` ##### `apt_conf_d` Data type: `String` Default value: `$apt::params::apt_conf_d` ##### `source_key_defaults` Data type: `Hash` Default value: `$apt::params::source_key_defaults` ### `apt::backports` Manages backports. #### Examples ##### Set up a backport source for Linux Mint qiana ```puppet class { 'apt::backports': location => 'http://us.archive.ubuntu.com/ubuntu', release => 'trusty-backports', repos => 'main universe multiverse restricted', key => { id => '630239CC130E1A7FD81A27B140976EAF437D05B5', server => 'hkps.pool.sks-keyservers.net', }, } ``` #### Parameters The following parameters are available in the `apt::backports` class. ##### `location` Data type: `Optional[String]` Specifies an Apt repository containing the backports to manage. Valid options: a string containing a URL. Default value for Debian and Ubuntu varies: - Debian: 'http://deb.debian.org/debian' - Ubuntu: 'http://archive.ubuntu.com/ubuntu' Default value: ``undef`` ##### `release` Data type: `Optional[String]` Specifies a distribution of the Apt repository containing the backports to manage. Used in populating the `source.list` configuration file. -Default: on Debian and Ubuntu, '${lsbdistcodename}-backports'. We recommend keeping this default, except on other operating +Default: on Debian and Ubuntu, `${facts['os']['distro']['codename']}-backports`. We recommend keeping this default, except on other operating systems. Default value: ``undef`` ##### `repos` Data type: `Optional[String]` Specifies a component of the Apt repository containing the backports to manage. Used in populating the `source.list` configuration file. Default value for Debian and Ubuntu varies: - Debian: 'main contrib non-free' - Ubuntu: 'main universe multiverse restricted' Default value: ``undef`` ##### `key` Data type: `Optional[Variant[String, Hash]]` Specifies a key to authenticate the backports. Valid options: a string to be passed to the id parameter of the apt::key defined type, or a hash of parameter => value pairs to be passed to apt::key's id, server, content, source, and/or options parameters. Default value for Debian and Ubuntu varies: - Debian: 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553' - Ubuntu: '630239CC130E1A7FD81A27B140976EAF437D05B5' Default value: ``undef`` ##### `pin` Data type: `Optional[Variant[Integer, String, Hash]]` Specifies a pin priority for the backports. Valid options: a number or string to be passed to the `id` parameter of the `apt::pin` defined type, or a hash of `parameter => value` pairs to be passed to `apt::pin`'s corresponding parameters. Default value: `200` ##### `include` Data type: `Optional[Variant[Hash]]` Specifies whether to include 'deb' or 'src', or both. Default value: `{}` ## Defined types ### `apt::conf` Specifies a custom Apt configuration file. #### Parameters The following parameters are available in the `apt::conf` defined type. ##### `content` Data type: `Optional[String]` Required unless `ensure` is set to 'absent'. Directly supplies content for the configuration file. Default value: ``undef`` ##### `ensure` Data type: `Enum['present', 'absent']` Specifies whether the configuration file should exist. Valid options: 'present' and 'absent'. Default value: `present` ##### `priority` Data type: `Variant[String, Integer]` Determines the order in which Apt processes the configuration file. Files with lower priority numbers are loaded first. Valid options: a string containing an integer or an integer. Default value: `50` ##### `notify_update` Data type: `Optional[Boolean]` Specifies whether to trigger an `apt-get update` run. Default value: ``undef`` ### `apt::key` Manages the GPG keys that Apt uses to authenticate packages. * **Note** The apt::key defined type makes use of the apt_key type, but includes extra functionality to help prevent duplicate keys. #### Examples ##### Declare Apt key for apt.puppetlabs.com source ```puppet apt::key { 'puppetlabs': id => '6F6B15509CF8E59E6E469F327F438280EF8D349F', server => 'hkps.pool.sks-keyservers.net', options => 'http-proxy="http://proxyuser:proxypass@example.org:3128"', } ``` #### Parameters The following parameters are available in the `apt::key` defined type. ##### `id` Data type: `Pattern[/\A(0x)?[0-9a-fA-F]{8}\Z/, /\A(0x)?[0-9a-fA-F]{16}\Z/, /\A(0x)?[0-9a-fA-F]{40}\Z/]` Specifies a GPG key to authenticate Apt package signatures. Valid options: a string containing a key ID (8 or 16 hexadecimal characters, optionally prefixed with "0x") or a full key fingerprint (40 hexadecimal characters). Default value: `$title` ##### `ensure` Data type: `Enum['present', 'absent', 'refreshed']` Specifies whether the key should exist. Valid options: 'present', 'absent' or 'refreshed'. Using 'refreshed' will make keys auto update when they have expired (assuming a new key exists on the key server). Default value: `present` ##### `content` Data type: `Optional[String]` Supplies the entire GPG key. Useful in case the key can't be fetched from a remote location and using a file resource is inconvenient. Default value: ``undef`` ##### `source` Data type: `Optional[Pattern[/\Ahttps?:\/\//, /\Aftp:\/\//, /\A\/\w+/]]` Specifies the location of an existing GPG key file to copy. Valid options: a string containing a URL (ftp://, http://, or https://) or an absolute path. Default value: ``undef`` ##### `server` Data type: `Pattern[/\A((hkp|hkps|http|https):\/\/)?([a-z\d])([a-z\d-]{0,61}\.)+[a-z\d]+(:\d{2,5})?(\/[a-zA-Z\d\-_.]+)*\/?$/]` Specifies a keyserver to provide the GPG key. Valid options: a string containing a domain name or a full URL (http://, https://, hkp:// or hkps://). The hkps:// protocol is currently only supported on Ubuntu 18.04. Default value: `$::apt::keyserver` ##### `weak_ssl` Data type: `Boolean` Specifies whether strict SSL verification on a https URL should be disabled. Valid options: true or false. Default value: ``false`` ##### `options` Data type: `Optional[String]` Passes additional options to `apt-key adv --keyserver-options`. Default value: `$::apt::key_options` ### `apt::mark` defined typeapt::mark #### Parameters The following parameters are available in the `apt::mark` defined type. ##### `setting` Data type: `Enum['auto','manual','hold','unhold']` auto, manual, hold, unhold specifies the behavior of apt in case of no more dependencies installed https://manpages.debian.org/sretch/apt/apt-mark.8.en.html ### `apt::pin` Manages Apt pins. Does not trigger an apt-get update run. * **See also** * http://linux.die.net/man/5/apt_preferences * for context on these parameters #### Parameters The following parameters are available in the `apt::pin` defined type. ##### `ensure` Data type: `Optional[Enum['file', 'present', 'absent']]` Specifies whether the pin should exist. Valid options: 'file', 'present', and 'absent'. Default value: `present` ##### `explanation` Data type: `Optional[String]` Supplies a comment to explain the pin. Default: "${caller_module_name}: ${name}". Default value: ``undef`` ##### `order` Data type: `Variant[Integer]` Determines the order in which Apt processes the pin file. Files with lower order numbers are loaded first. Default value: `50` ##### `packages` Data type: `Variant[String, Array]` Specifies which package(s) to pin. Default value: `'*'` ##### `priority` Data type: `Variant[Numeric, String]` Sets the priority of the package. If multiple versions of a given package are available, `apt-get` installs the one with the highest priority number (subject to dependency constraints). Valid options: an integer. Default value: `0` ##### `release` Data type: `Optional[String]` Tells APT to prefer packages that support the specified release. Typical values include 'stable', 'testing', and 'unstable'. Default value: `''` ##### `release_version` Data type: `Optional[String]` Tells APT to prefer packages that support the specified operating system release version (such as Debian release version 7). Default value: `''` ##### `component` Data type: `Optional[String]` Names the licensing component associated with the packages in the directory tree of the Release file. Default value: `''` ##### `originator` Data type: `Optional[String]` Names the originator of the packages in the directory tree of the Release file. Default value: `''` ##### `label` Data type: `Optional[String]` Names the label of the packages in the directory tree of the Release file. Default value: `''` ##### `origin` Data type: `Optional[String]` Default value: `''` ##### `version` Data type: `Optional[String]` Default value: `''` ##### `codename` Data type: `Optional[String]` Default value: `''` ### `apt::ppa` Manages PPA repositories using `add-apt-repository`. Not supported on Debian. #### Examples ##### Example declaration of an Apt PPA ```puppet apt::ppa{ 'ppa:openstack-ppa/bleeding-edge': } ``` #### Parameters The following parameters are available in the `apt::ppa` defined type. ##### `ensure` Data type: `String` Specifies whether the PPA should exist. Valid options: 'present' and 'absent'. Default value: `'present'` ##### `options` Data type: `Optional[String]` Supplies options to be passed to the `add-apt-repository` command. Default: '-y'. Default value: `$::apt::ppa_options` ##### `release` Data type: `Optional[String]` -Optional if lsb-release is installed (unless you're using a different release than indicated by lsb-release, e.g., Linux Mint). Specifies the operating system of your node. Valid options: a string containing a valid LSB distribution codename. +Optional if `puppet facts show os.distro.codename` returns your correct distribution release codename. -Default value: `$facts['lsbdistcodename']` +Default value: `$facts['os']['distro']['codename']` ##### `dist` Data type: `Optional[String]` -Optional if lsb-release is installed (unless you're using a different release than indicated by lsb-release, e.g., Linux Mint). Specifies the distribution of your node. Valid options: a string containing a valid distribution codename. +Optional if `puppet facts show os.name` returns your correct distribution name. -Default value: `$facts['lsbdistid']` +Default value: `$facts['os']['name']` ##### `package_name` Data type: `Optional[String]` Names the package that provides the `apt-add-repository` command. Default: 'software-properties-common'. Default value: `$::apt::ppa_package` ##### `package_manage` Data type: `Boolean` Specifies whether Puppet should manage the package that provides `apt-add-repository`. Default value: ``false`` ### `apt::setting` Manages Apt configuration files. * **See also** * https://docs.puppetlabs.com/references/latest/type.html#file-attributes * for more information on source and content parameters #### Parameters The following parameters are available in the `apt::setting` defined type. ##### `priority` Data type: `Variant[String, Integer, Array]` Determines the order in which Apt processes the configuration file. Files with higher priority numbers are loaded first. Default value: `50` ##### `ensure` Data type: `Optional[Enum['file', 'present', 'absent']]` Specifies whether the file should exist. Valid options: 'present', 'absent', and 'file'. Default value: `file` ##### `source` Data type: `Optional[String]` Required, unless `content` is set. Specifies a source file to supply the content of the configuration file. Cannot be used in combination with `content`. Valid options: see link above for Puppet's native file type source attribute. Default value: ``undef`` ##### `content` Data type: `Optional[String]` Required, unless `source` is set. Directly supplies content for the configuration file. Cannot be used in combination with `source`. Valid options: see link above for Puppet's native file type content attribute. Default value: ``undef`` ##### `notify_update` Data type: `Boolean` Specifies whether to trigger an `apt-get update` run. Default value: ``true`` ### `apt::source` Manages the Apt sources in /etc/apt/sources.list.d/. #### Examples ##### Install the puppetlabs apt source ```puppet apt::source { 'puppetlabs': location => 'http://apt.puppetlabs.com', repos => 'main', key => { id => '6F6B15509CF8E59E6E469F327F438280EF8D349F', server => 'hkps.pool.sks-keyservers.net', }, } ``` #### Parameters The following parameters are available in the `apt::source` defined type. ##### `location` Data type: `Optional[String]` Required, unless ensure is set to 'absent'. Specifies an Apt repository. Valid options: a string containing a repository URL. Default value: ``undef`` ##### `comment` Data type: `String` Supplies a comment for adding to the Apt source file. Default value: `$name` ##### `ensure` Data type: `String` Specifies whether the Apt source file should exist. Valid options: 'present' and 'absent'. Default value: `present` ##### `release` Data type: `Optional[String]` Specifies a distribution of the Apt repository. Default value: ``undef`` ##### `repos` Data type: `String` Specifies a component of the Apt repository. Default value: `'main'` ##### `include` Data type: `Optional[Variant[Hash]]` Configures include options. Valid options: a hash of available keys. Options: * **:deb** `Boolean`: Specifies whether to request the distribution's compiled binaries. Default true. * **:src** `Boolean`: Specifies whether to request the distribution's uncompiled source code. Default false. Default value: `{}` ##### `key` Data type: `Optional[Variant[String, Hash]]` Creates a declaration of the apt::key defined type. Valid options: a string to be passed to the `id` parameter of the `apt::key` defined type, or a hash of `parameter => value` pairs to be passed to `apt::key`'s `id`, `server`, `content`, `source`, and/or `options` parameters. Default value: ``undef`` ##### `pin` 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 `id` parameter of the `apt::pin` defined type, or a hash of `parameter => value` pairs to be passed to `apt::pin`'s corresponding parameters. Default value: ``undef`` ##### `architecture` Data type: `Optional[String]` 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'). Default: undef (if unspecified, Apt downloads information for all architectures defined in the Apt::Architectures option). 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`` ##### `notify_update` Data type: `Boolean` Specifies whether to trigger an `apt-get update` run. Default value: ``true`` ## Resource types ## Data types ### `Apt::Auth_conf_entry` Login configuration settings that are recorded in the file `/etc/apt/auth.conf`. * **See also** * https://manpages.debian.org/testing/apt/apt_auth.conf.5.en.html * for more information Alias of `Struct[{ machine => String[1], login => String, password => String }]` #### Parameters The following parameters are available in the `Apt::Auth_conf_entry` data type. ##### `machine` Hostname of machine to connect to. ##### `login` Specifies the username to connect with. ##### `password` Specifies the password to connect with. ### `Apt::Proxy` Configures Apt to connect to a proxy server. Alias of `Struct[{ ensure => Optional[Enum['file', 'present', 'absent']], host => Optional[String], port => Optional[Integer[0, 65535]], https => Optional[Boolean], https_acng => Optional[Boolean], direct => Optional[Boolean], }]` #### Parameters The following parameters are available in the `Apt::Proxy` data type. ##### `ensure` Specifies whether the proxy should exist. Valid options: 'file', 'present', and 'absent'. Prefer 'file' over 'present'. ##### `host` Specifies a proxy host to be stored in `/etc/apt/apt.conf.d/01proxy`. Valid options: a string containing a hostname. ##### `port` Specifies a proxy port to be stored in `/etc/apt/apt.conf.d/01proxy`. Valid options: an integer containing a port number. ##### `https` Specifies whether to enable https proxies. ##### `direct` Specifies whether or not to use a `DIRECT` https proxy if http proxy is used but https is not. ## Tasks ### `init` Allows you to perform apt functions **Supports noop?** false #### Parameters ##### `action` Data type: `Enum[update, upgrade, dist-upgrade, autoremove]` Action to perform diff --git a/examples/backports.pp b/examples/backports.pp index 5f1f1ee..66e08e3 100644 --- a/examples/backports.pp +++ b/examples/backports.pp @@ -1,11 +1,11 @@ -# Set up a backport for linuxmint qiana +# Set up a backport for Linux Mint qiana class { 'apt': } -apt::backports { 'qiana': +class { 'apt::backports': location => 'http://us.archive.ubuntu.com/ubuntu', release => 'trusty-backports', repos => 'main universe multiverse restricted', key => { id => '630239CC130E1A7FD81A27B140976EAF437D05B5', server => 'hkps.pool.sks-keyservers.net', }, } diff --git a/examples/source.pp b/examples/source.pp index a3648c3..3e38126 100644 --- a/examples/source.pp +++ b/examples/source.pp @@ -1,35 +1,35 @@ # Declare the apt class to manage /etc/apt/sources.list and /etc/sources.list.d class { 'apt': } # Install the puppetlabs apt source -# Release is automatically obtained from lsbdistcodename fact if available. +# Release is automatically obtained from facts. apt::source { 'puppetlabs': location => 'http://apt.puppetlabs.com', repos => 'main', key => { id => '6F6B15509CF8E59E6E469F327F438280EF8D349F', server => 'hkps.pool.sks-keyservers.net', }, } # test two sources with the same key apt::source { 'debian_testing': location => 'http://debian.mirror.iweb.ca/debian/', release => 'testing', repos => 'main contrib non-free', key => { id => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', server => 'hkps.pool.sks-keyservers.net', }, pin => '-10', } apt::source { 'debian_unstable': location => 'http://debian.mirror.iweb.ca/debian/', release => 'unstable', repos => 'main contrib non-free', key => { id => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', server => 'hkps.pool.sks-keyservers.net', }, pin => '-10', } diff --git a/locales/ja/puppetlabs-apt.po b/locales/ja/puppetlabs-apt.po index b5f4765..1fe9d1d 100644 --- a/locales/ja/puppetlabs-apt.po +++ b/locales/ja/puppetlabs-apt.po @@ -1,155 +1,155 @@ # #-#-#-#-# puppetlabs-apt.pot (puppetlabs-apt 6.0.0-27-gbb0f842) #-#-#-#-# # SOME DESCRIPTIVE TITLE. # Copyright (C) 2018 Puppet, Inc. # This file is distributed under the same license as the puppetlabs-apt package. # FIRST AUTHOR , 2018. -# +# # #-#-#-#-# puppetlabs-apt_metadata.pot (PACKAGE VERSION) #-#-#-#-# -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-09-21T09:17:39+01:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Eriko Kashiwagi , 2018\n" "Language-Team: Japanese (Japan) (https://www.transifex.com/puppet/teams/41915/ja_JP/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ja_JP\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Translate Toolkit 2.0.0\n" #. ./manifests/backports.pp:69 msgid "" "If not on Debian or Ubuntu, you must explicitly pass location, release, " "repos, and key" msgstr "DebianまたはUbuntu以外の場合、場所、リリース、リポジトリ、およびキーを明示的に渡す必要があります。" #. ./manifests/backports.pp:95 msgid "pin must be either a string, number or hash" msgstr "pinは、文字列、数値またはハッシュのいずれかである必要があります。" #. ./manifests/conf.pp:25 msgid "Need to pass in content parameter" msgstr "contentパラメータを渡す必要があります。" #. ./manifests/init.pp:143 ./manifests/params.pp:8 msgid "This module only works on Debian or derivatives like Ubuntu" msgstr "本モジュールは、DebianまたはUbuntuなどの派生OSでのみ動作します。" #. ./manifests/key.pp:47 msgid "key with id %{_id} already ensured as absent" msgstr "id %{_id}のキーは、存在しないことが既に確認されています。" #. ./manifests/key.pp:81 msgid "key with id %{_id} already ensured as present" msgstr "id %{_id}のキーは、存在することが既に確認されています。" #. ./manifests/key.pp:97 msgid "Invalid 'ensure' value '%{_ensure}' for apt::key" msgstr "apt::keyの'%{_ensure}'の'ensure'の値が無効です。" #. ./manifests/params.pp:100 msgid "Unable to determine value for fact os[\"name\"]" msgstr "fact os[\"name\"]の値を特定できません。" #. ./manifests/pin.pp:84 msgid "parameters release, origin, and version are mutually exclusive" msgstr "パラメータrelease、origin、versionは相互に排他的です。" #. ./manifests/pin.pp:88 msgid "parameter version cannot be used in general form" msgstr "パラメータのバージョンは、一般的な形式では使用できません" #. ./manifests/pin.pp:91 msgid "parameters release and origin are mutually exclusive" msgstr "パラメータreleaseとoriginは相互に排他的です。" #. ./manifests/ppa.pp:30 ./manifests/source.pp:79 -msgid "lsbdistcodename fact not available: release parameter required" -msgstr "lsbdistcodenameのfactが使用できません。releaseパラメータが必要です。" +msgid "os.distro.codename fact not available: release parameter required" +msgstr "os.distro.codenameのfactが使用できません。releaseパラメータが必要です。" #. ./manifests/ppa.pp:34 msgid "apt::ppa is not currently supported on Debian." msgstr "apt::ppaは、現在Debianではサポートされていません。" #. ./manifests/setting.pp:31 msgid "apt::setting cannot have both content and source" msgstr "apt::settingがcontentとsourceの両方を持つことはできません。" #. ./manifests/setting.pp:35 msgid "apt::setting needs either of content or source" msgstr "apt::settingには、contentまたはsourceのいずれかが必要です。" #. ./manifests/setting.pp:43 msgid "" "apt::setting resource name/title must start with either 'conf-', 'pref-' or " "'list-'" msgstr "apt::settingのリソース名/タイトルの先頭は、'conf-'、'pref-'、'list-'にする必要があります。" #. ./manifests/setting.pp:49 msgid "apt::setting priority must be an integer or a zero-padded integer" msgstr "apt::settingのpriorityは、整数またはゼロパディングされた整数にする必要があります。" #. ./manifests/source.pp:87 msgid "cannot create a source entry without specifying a location" msgstr "場所を指定せずにソースエントリを作成することはできません。" #. ./manifests/source.pp:101 msgid "key hash must contain at least an id entry" msgstr "キーハッシュには、少なくともidエントリを含める必要があります。" #. ./manifests/source.pp:140 msgid "Received invalid value for pin parameter" msgstr "pinパラメータに無効な値を受信しました。" #: ../lib/puppet/provider/apt_key/apt_key.rb:124 msgid "The file %{_value} does not exist" msgstr "ファイル%{_value}が存在しません。" #: ../lib/puppet/provider/apt_key/apt_key.rb:144 msgid "%{_e} for %{_resource}" msgstr "%{_resource}の%{_e}" #: ../lib/puppet/provider/apt_key/apt_key.rb:146 msgid "could not resolve %{_resource}" msgstr "%{_resource}を解決できませんでした。" #: ../lib/puppet/provider/apt_key/apt_key.rb:173 msgid "" "The id in your manifest %{_resource} and the fingerprint from content/source" " don't match. Check for an error in the id and content/source is legitimate." msgstr "" "マニフェスト%{_resource}に含まれるidと、content/sourceのフィンガープリントが一致しません。idに間違いがないか、content/sourceが正当であるかを確認してください。" #: ../lib/puppet/provider/apt_key/apt_key.rb:191 #: ../lib/puppet/provider/apt_key/apt_key.rb:227 msgid "" "an unexpected condition occurred while trying to add the key: %{_resource}" msgstr "キー%{_resource}の追加中に、予期しない状況が発生しました。" #: ../lib/puppet/provider/apt_key/apt_key.rb:243 msgid "This is a read-only property." msgstr "これは、読み込み専用のプロパティです。" #: ../lib/puppet/type/apt_key.rb:27 msgid "ensure => absent and refresh => true are mutually exclusive" msgstr "ensure => absentとrefresh => trueは相互に排他的です。" #: ../lib/puppet/type/apt_key.rb:30 msgid "The properties content and source are mutually exclusive." msgstr "プロパティcontentとsourceは相互に排他的です。 are mutually exclusive." #: ../lib/puppet/type/apt_key.rb:33 msgid "The id should be a full fingerprint (40 characters), see README." msgstr "idは完全なフィンガープリント(40文字)である必要があります。READMEを参照してください。" #. metadata.json #: .summary msgid "" "Provides an interface for managing Apt source, key, and definitions with " "Puppet" msgstr "Aptソース、キー、および定義をPuppetで管理するためのインターフェースを提供します。" diff --git a/locales/puppetlabs-apt.pot b/locales/puppetlabs-apt.pot index 5701be9..5fa70e2 100644 --- a/locales/puppetlabs-apt.pot +++ b/locales/puppetlabs-apt.pot @@ -1,177 +1,177 @@ # #-#-#-#-# puppetlabs-apt.pot (puppetlabs-apt 6.0.0-27-gbb0f842) #-#-#-#-# # SOME DESCRIPTIVE TITLE. # Copyright (C) 2018 Puppet, Inc. # This file is distributed under the same license as the puppetlabs-apt package. # FIRST AUTHOR , 2018. # # #-#-#-#-# puppetlabs-apt_metadata.pot (PACKAGE VERSION) #-#-#-#-# # #, fuzzy msgid "" msgstr "" "#-#-#-#-# puppet.pot (PACKAGE VERSION) #-#-#-#-#\n" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-09-21 09:17:33 +0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Translate Toolkit 2.0.0\n" "#-#-#-#-# puppetlabs-apt.pot (puppetlabs-apt 6.0.0-27-gbb0f842) #-#-#-#-#\n" "Project-Id-Version: puppetlabs-apt 6.0.0-27-gbb0f842\n" "\n" "Report-Msgid-Bugs-To: docs@puppet.com\n" "POT-Creation-Date: 2018-09-21 09:27+0100\n" "PO-Revision-Date: 2018-09-21 09:27+0100\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" "#-#-#-#-# puppetlabs-apt_metadata.pot (PACKAGE VERSION) #-#-#-#-#\n" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To:\n" "POT-Creation-Date: 2018-09-21T09:17:39+01:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Translate Toolkit 2.0.0\n" #. ./manifests/backports.pp:69 msgid "" "If not on Debian or Ubuntu, you must explicitly pass location, release, " "repos, and key" msgstr "" #. ./manifests/backports.pp:95 msgid "pin must be either a string, number or hash" msgstr "" #. ./manifests/conf.pp:25 msgid "Need to pass in content parameter" msgstr "" #. ./manifests/init.pp:143 ./manifests/params.pp:8 msgid "This module only works on Debian or derivatives like Ubuntu" msgstr "" #. ./manifests/key.pp:47 msgid "key with id %{_id} already ensured as absent" msgstr "" #. ./manifests/key.pp:81 msgid "key with id %{_id} already ensured as present" msgstr "" #. ./manifests/key.pp:97 msgid "Invalid 'ensure' value '%{_ensure}' for apt::key" msgstr "" #. ./manifests/params.pp:100 msgid "Unable to determine value for fact os[\"name\"]" msgstr "" #. ./manifests/pin.pp:84 msgid "parameters release, origin, and version are mutually exclusive" msgstr "" #. ./manifests/pin.pp:88 msgid "parameter version cannot be used in general form" msgstr "" #. ./manifests/pin.pp:91 msgid "parameters release and origin are mutually exclusive" msgstr "" #. ./manifests/ppa.pp:30 ./manifests/source.pp:79 -msgid "lsbdistcodename fact not available: release parameter required" +msgid "os.distro.codename fact not available: release parameter required" msgstr "" #. ./manifests/ppa.pp:34 msgid "apt::ppa is not currently supported on Debian." msgstr "" #. ./manifests/setting.pp:31 msgid "apt::setting cannot have both content and source" msgstr "" #. ./manifests/setting.pp:35 msgid "apt::setting needs either of content or source" msgstr "" #. ./manifests/setting.pp:43 msgid "" "apt::setting resource name/title must start with either 'conf-', 'pref-' or " "'list-'" msgstr "" #. ./manifests/setting.pp:49 msgid "apt::setting priority must be an integer or a zero-padded integer" msgstr "" #. ./manifests/source.pp:87 msgid "cannot create a source entry without specifying a location" msgstr "" #. ./manifests/source.pp:101 msgid "key hash must contain at least an id entry" msgstr "" #. ./manifests/source.pp:140 msgid "Received invalid value for pin parameter" msgstr "" #: ../lib/puppet/provider/apt_key/apt_key.rb:124 msgid "The file %{_value} does not exist" msgstr "" #: ../lib/puppet/provider/apt_key/apt_key.rb:144 msgid "%{_e} for %{_resource}" msgstr "" #: ../lib/puppet/provider/apt_key/apt_key.rb:146 msgid "could not resolve %{_resource}" msgstr "" #: ../lib/puppet/provider/apt_key/apt_key.rb:173 msgid "" "The id in your manifest %{_resource} and the fingerprint from content/source " "don't match. Check for an error in the id and content/source is legitimate." msgstr "" #: ../lib/puppet/provider/apt_key/apt_key.rb:191 #: ../lib/puppet/provider/apt_key/apt_key.rb:227 msgid "" "an unexpected condition occurred while trying to add the key: %{_resource}" msgstr "" #: ../lib/puppet/provider/apt_key/apt_key.rb:243 msgid "This is a read-only property." msgstr "" #: ../lib/puppet/type/apt_key.rb:27 msgid "ensure => absent and refresh => true are mutually exclusive" msgstr "" #: ../lib/puppet/type/apt_key.rb:30 msgid "The properties content and source are mutually exclusive." msgstr "" #: ../lib/puppet/type/apt_key.rb:33 msgid "The id should be a full fingerprint (40 characters), see README." msgstr "" #. metadata.json #: .summary msgid "" "Provides an interface for managing Apt source, key, and definitions with " "Puppet" msgstr "" diff --git a/manifests/backports.pp b/manifests/backports.pp index 21f1251..5949905 100644 --- a/manifests/backports.pp +++ b/manifests/backports.pp @@ -1,113 +1,112 @@ # @summary Manages backports. # # @example Set up a backport source for Linux Mint qiana # class { 'apt::backports': # location => 'http://us.archive.ubuntu.com/ubuntu', # release => 'trusty-backports', # repos => 'main universe multiverse restricted', # key => { # id => '630239CC130E1A7FD81A27B140976EAF437D05B5', # server => 'hkps.pool.sks-keyservers.net', # }, # } # # @param location -# Specifies an Apt repository containing the backports to manage. Valid options: a string containing a URL. Default value for Debian and +# Specifies an Apt repository containing the backports to manage. Valid options: a string containing a URL. Default value for Debian and # Ubuntu varies: # # - Debian: 'http://deb.debian.org/debian' # # - Ubuntu: 'http://archive.ubuntu.com/ubuntu' # # @param release -# Specifies a distribution of the Apt repository containing the backports to manage. Used in populating the `source.list` configuration file. -# Default: on Debian and Ubuntu, '${lsbdistcodename}-backports'. We recommend keeping this default, except on other operating +# Specifies a distribution of the Apt repository containing the backports to manage. Used in populating the `source.list` configuration file. +# Default: on Debian and Ubuntu, `${facts['os']['distro']['codename']}-backports`. We recommend keeping this default, except on other operating # systems. # # @param repos -# Specifies a component of the Apt repository containing the backports to manage. Used in populating the `source.list` configuration file. +# Specifies a component of the Apt repository containing the backports to manage. Used in populating the `source.list` configuration file. # Default value for Debian and Ubuntu varies: -# +# # - Debian: 'main contrib non-free' # # - Ubuntu: 'main universe multiverse restricted' # # @param key -# Specifies a key to authenticate the backports. Valid options: a string to be passed to the id parameter of the apt::key defined type, or a +# Specifies a key to authenticate the backports. Valid options: a string to be passed to the id parameter of the apt::key defined type, or a # hash of parameter => value pairs to be passed to apt::key's id, server, content, source, and/or options parameters. Default value # for Debian and Ubuntu varies: # # - Debian: 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553' # # - Ubuntu: '630239CC130E1A7FD81A27B140976EAF437D05B5' # # @param pin -# Specifies a pin priority for the backports. Valid options: a number or string to be passed to the `id` parameter of the `apt::pin` defined +# Specifies a pin priority for the backports. Valid options: a number or string to be passed to the `id` parameter of the `apt::pin` defined # type, or a hash of `parameter => value` pairs to be passed to `apt::pin`'s corresponding parameters. # # @param include # Specifies whether to include 'deb' or 'src', or both. # class apt::backports ( Optional[String] $location = undef, Optional[String] $release = undef, Optional[String] $repos = undef, Optional[Variant[String, Hash]] $key = undef, Optional[Variant[Integer, String, Hash]] $pin = 200, Optional[Variant[Hash]] $include = {}, -){ - +) { include apt if $location { $_location = $location } if $release { $_release = $release } if $repos { $_repos = $repos } if $key { $_key = $key } - if (!($facts['lsbdistid'] == 'Debian' or $facts['lsbdistid'] == 'Ubuntu')) { + if (!($facts['os']['name'] == 'Debian' or $facts['os']['name'] == 'Ubuntu')) { unless $location and $release and $repos and $key { fail(translate('If not on Debian or Ubuntu, you must explicitly pass location, release, repos, and key')) } } unless $location { $_location = $::apt::backports['location'] } unless $release { - $_release = "${facts['lsbdistcodename']}-backports" + $_release = "${facts['os']['distro']['codename']}-backports" } unless $repos { $_repos = $::apt::backports['repos'] } unless $key { $_key = $::apt::backports['key'] } if $pin =~ Hash { $_pin = $pin } elsif $pin =~ Numeric or $pin =~ String { # apt::source defaults to pinning to origin, but we should pin to release # for backports $_pin = { 'priority' => $pin, 'release' => $_release, } } else { fail(translate('pin must be either a string, number or hash')) } apt::source { 'backports': location => $_location, release => $_release, repos => $_repos, include => $include, key => $_key, pin => $_pin, } } diff --git a/manifests/init.pp b/manifests/init.pp index ea4e828..a20748f 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,344 +1,344 @@ # @summary Main class, includes all other classes. # # @see https://docs.puppetlabs.com/references/latest/function.html#createresources for the create resource function # # @param provider # Specifies the provider that should be used by apt::update. # # @param keyserver # Specifies a keyserver to provide the GPG key. Valid options: a string containing a domain name or a full URL (http://, https://, or # hkp://). # # @param key_options # Specifies the default options for apt::key resources. # # @param ppa_options # Supplies options to be passed to the `add-apt-repository` command. # # @param ppa_package # Names the package that provides the `apt-add-repository` command. # # @param backports # Specifies some of the default parameters used by apt::backports. Valid options: a hash made up from the following keys: # # @option backports [String] :location # See apt::backports for documentation. # # @option backports [String] :repos # See apt::backports for documentation. # # @option backports [String] :key # See apt::backports for documentation. # # @param confs # Creates new `apt::conf` resources. Valid options: a hash to be passed to the create_resources function linked above. # # @param update # Configures various update settings. Valid options: a hash made up from the following keys: # # @option update [String] :frequency # Specifies how often to run `apt-get update`. If the exec resource `apt_update` is notified, `apt-get update` runs regardless of this value. # Valid options: 'always' (at every Puppet run); 'daily' (if the value of `apt_update_last_success` is less than current epoch time minus 86400); # 'weekly' (if the value of `apt_update_last_success` is less than current epoch time minus 604800); and 'reluctantly' (only if the exec resource # `apt_update` is notified). Default: 'reluctantly'. # # @option update [Integer] :loglevel # Specifies the log level of logs outputted to the console. Default: undef. # # @option update [Integer] :timeout # Specifies how long to wait for the update to complete before canceling it. Valid options: an integer, in seconds. Default: undef. # # @option update [Integer] :tries # Specifies how many times to retry the update after receiving a DNS or HTTP error. Default: undef. # # @param purge # Specifies whether to purge any existing settings that aren't managed by Puppet. Valid options: a hash made up from the following keys: # # @option purge [Boolean] :sources.list # Specifies whether to purge any unmanaged entries from sources.list. Default false. # # @option purge [Boolean] :sources.list.d # Specifies whether to purge any unmanaged entries from sources.list.d. Default false. # # @option purge [Boolean] :preferences # Specifies whether to purge any unmanaged entries from preferences. Default false. # # @option purge [Boolean] :preferences.d. # Specifies whether to purge any unmanaged entries from preferences.d. Default false. # # @param proxy # Configures Apt to connect to a proxy server. Valid options: a hash matching the locally defined type apt::proxy. # # @param sources # Creates new `apt::source` resources. Valid options: a hash to be passed to the create_resources function linked above. # # @param keys # Creates new `apt::key` resources. Valid options: a hash to be passed to the create_resources function linked above. # # @param ppas # Creates new `apt::ppa` resources. Valid options: a hash to be passed to the create_resources function linked above. # # @param pins # Creates new `apt::pin` resources. Valid options: a hash to be passed to the create_resources function linked above. # # @param settings # Creates new `apt::setting` resources. Valid options: a hash to be passed to the create_resources function linked above. # # @param manage_auth_conf # Specifies whether to manage the /etc/apt/auth.conf file. When true, the file will be overwritten with the entries specified in # the auth_conf_entries parameter. When false, the file will be ignored (note that this does not set the file to absent. # # @param auth_conf_entries # An optional array of login configuration settings (hashes) that are recorded in the file /etc/apt/auth.conf. This file has a netrc-like # format (similar to what curl uses) and contains the login configuration for APT sources and proxies that require authentication. See # https://manpages.debian.org/testing/apt/apt_auth.conf.5.en.html for details. If specified each hash must contain the keys machine, login and # password and no others. Specifying manage_auth_conf and not specifying this parameter will set /etc/apt/auth.conf to absent. # # @param auth_conf_owner # The owner of the file /etc/apt/auth.conf. Default: '_apt' or 'root' on old releases. # # @param root # Specifies root directory of Apt executable. # # @param sources_list # Specifies the path of the sources_list file to use. # # @param sources_list_d # Specifies the path of the sources_list.d file to use. # # @param conf_d # Specifies the path of the conf.d file to use. # # @param preferences # Specifies the path of the preferences file to use. # # @param preferences_d # Specifies the path of the preferences.d file to use. # # @param config_files # A hash made up of the various configuration files used by Apt. # # @param sources_list_force # Specifies whether to perform force purge or delete. Default false. # class apt ( Hash $update_defaults = $apt::params::update_defaults, Hash $purge_defaults = $apt::params::purge_defaults, Hash $proxy_defaults = $apt::params::proxy_defaults, Hash $include_defaults = $apt::params::include_defaults, String $provider = $apt::params::provider, String $keyserver = $apt::params::keyserver, Optional[String] $key_options = $apt::params::key_options, Optional[String] $ppa_options = $apt::params::ppa_options, Optional[String] $ppa_package = $apt::params::ppa_package, Optional[Hash] $backports = $apt::params::backports, Hash $confs = $apt::params::confs, Hash $update = $apt::params::update, Hash $purge = $apt::params::purge, Apt::Proxy $proxy = $apt::params::proxy, Hash $sources = $apt::params::sources, Hash $keys = $apt::params::keys, Hash $ppas = $apt::params::ppas, Hash $pins = $apt::params::pins, Hash $settings = $apt::params::settings, Boolean $manage_auth_conf = $apt::params::manage_auth_conf, Array[Apt::Auth_conf_entry] $auth_conf_entries = $apt::params::auth_conf_entries, String $auth_conf_owner = $apt::params::auth_conf_owner, String $root = $apt::params::root, String $sources_list = $apt::params::sources_list, String $sources_list_d = $apt::params::sources_list_d, String $conf_d = $apt::params::conf_d, String $preferences = $apt::params::preferences, String $preferences_d = $apt::params::preferences_d, String $apt_conf_d = $apt::params::apt_conf_d, Hash $config_files = $apt::params::config_files, Hash $source_key_defaults = $apt::params::source_key_defaults, Boolean $sources_list_force = $apt::params::sources_list_force, ) inherits apt::params { - if $facts['osfamily'] != 'Debian' { + if $facts['os']['family'] != 'Debian' { fail(translate('This module only works on Debian or derivatives like Ubuntu')) } if $update['frequency'] { assert_type( Enum['always','daily','weekly','reluctantly'], $update['frequency'], ) } if $update['timeout'] { assert_type(Integer, $update['timeout']) } if $update['tries'] { assert_type(Integer, $update['tries']) } $_update = merge($::apt::update_defaults, $update) include ::apt::update if $purge['sources.list'] { assert_type(Boolean, $purge['sources.list']) } if $purge['sources.list.d'] { assert_type(Boolean, $purge['sources.list.d']) } if $purge['preferences'] { assert_type(Boolean, $purge['preferences']) } if $purge['preferences.d'] { assert_type(Boolean, $purge['preferences.d']) } if $sources_list_force { assert_type(Boolean, $sources_list_force) } if $purge['apt.conf.d'] { assert_type(Boolean, $purge['apt.conf.d']) } $_purge = merge($::apt::purge_defaults, $purge) $_proxy = merge($apt::proxy_defaults, $proxy) $confheadertmp = epp('apt/_conf_header.epp') $proxytmp = epp('apt/proxy.epp', {'proxies' => $_proxy}) $updatestamptmp = epp('apt/15update-stamp.epp') if $_proxy['ensure'] == 'absent' or $_proxy['host'] { apt::setting { 'conf-proxy': ensure => $_proxy['ensure'], priority => '01', content => "${confheadertmp}${proxytmp}", } } if $sources_list_force { $sources_list_ensure = $_purge['sources.list'] ? { true => absent, default => file, } $sources_list_content = $_purge['sources.list'] ? { true => nil, default => undef, } } else { $sources_list_ensure = $_purge['sources.list'] ? { true => file, default => file, } $sources_list_content = $_purge['sources.list'] ? { true => "# Repos managed by puppet.\n", default => undef, } } $preferences_ensure = $_purge['preferences'] ? { true => absent, default => file, } if $_update['frequency'] == 'always' { Exec <| title=='apt_update' |> { refreshonly => false, } } apt::setting { 'conf-update-stamp': priority => 15, content => "${confheadertmp}${updatestamptmp}", } file { 'sources.list': ensure => $sources_list_ensure, path => $::apt::sources_list, owner => root, group => root, content => $sources_list_content, notify => Class['apt::update'], } file { 'sources.list.d': ensure => directory, path => $::apt::sources_list_d, owner => root, group => root, purge => $_purge['sources.list.d'], recurse => $_purge['sources.list.d'], notify => Class['apt::update'], } file { 'preferences': ensure => $preferences_ensure, path => $::apt::preferences, owner => root, group => root, notify => Class['apt::update'], } file { 'preferences.d': ensure => directory, path => $::apt::preferences_d, owner => root, group => root, purge => $_purge['preferences.d'], recurse => $_purge['preferences.d'], notify => Class['apt::update'], } file { 'apt.conf.d': ensure => directory, path => $::apt::apt_conf_d, owner => root, group => root, purge => $_purge['apt.conf.d'], recurse => $_purge['apt.conf.d'], notify => Class['apt::update'], } if $confs { create_resources('apt::conf', $confs) } # manage sources if present if $sources { create_resources('apt::source', $sources) } # manage keys if present if $keys { create_resources('apt::key', $keys) } # manage ppas if present if $ppas { create_resources('apt::ppa', $ppas) } # manage settings if present if $settings { create_resources('apt::setting', $settings) } if $manage_auth_conf { $auth_conf_ensure = $auth_conf_entries ? { [] => 'absent', default => 'present', } $auth_conf_tmp = epp('apt/auth_conf.epp') file { '/etc/apt/auth.conf': ensure => $auth_conf_ensure, owner => $auth_conf_owner, group => 'root', mode => '0600', content => Sensitive("${confheadertmp}${auth_conf_tmp}"), notify => Class['apt::update'], } } # manage pins if present if $pins { create_resources('apt::pin', $pins) } # required for adding GPG keys on Debian 9 (and derivatives) ensure_packages(['gnupg']) } diff --git a/manifests/params.pp b/manifests/params.pp index c648c4e..9a92577 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -1,124 +1,124 @@ # @summary Provides defaults for the Apt module parameters. -# +# # @api private # class apt::params { - if $::osfamily != 'Debian' { + if $facts['os']['family'] != 'Debian' { fail(translate('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', } } $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, } $source_key_defaults = { 'server' => $keyserver, 'options' => undef, 'content' => undef, 'source' => undef, } $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 if versioncmp($facts['os']['release']['major'], '9') >= 0 { $auth_conf_owner = '_apt' } else { $auth_conf_owner = 'root' } } 'Ubuntu': { $backports = { 'location' => 'http://archive.ubuntu.com/ubuntu', 'key' => '630239CC130E1A7FD81A27B140976EAF437D05B5', 'repos' => 'main universe multiverse restricted', } $ppa_options = '-y' $ppa_package = 'software-properties-common' if versioncmp($facts['os']['release']['full'], '16.04') >= 0 { $auth_conf_owner = '_apt' } else { $auth_conf_owner = 'root' } } undef: { fail(translate('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/ppa.pp b/manifests/ppa.pp index ba05485..6a874ce 100644 --- a/manifests/ppa.pp +++ b/manifests/ppa.pp @@ -1,104 +1,104 @@ # @summary Manages PPA repositories using `add-apt-repository`. Not supported on Debian. # # @example Example declaration of an Apt PPA # apt::ppa{ 'ppa:openstack-ppa/bleeding-edge': } # # @param ensure -# Specifies whether the PPA should exist. Valid options: 'present' and 'absent'. +# Specifies whether the PPA should exist. Valid options: 'present' and 'absent'. # # @param options # Supplies options to be passed to the `add-apt-repository` command. Default: '-y'. # # @param release -# Optional if lsb-release is installed (unless you're using a different release than indicated by lsb-release, e.g., Linux Mint). # Specifies the operating system of your node. Valid options: a string containing a valid LSB distribution codename. +# Optional if `puppet facts show os.distro.codename` returns your correct distribution release codename. # # @param dist -# Optional if lsb-release is installed (unless you're using a different release than indicated by lsb-release, e.g., Linux Mint). # Specifies the distribution of your node. Valid options: a string containing a valid distribution codename. +# Optional if `puppet facts show os.name` returns your correct distribution name. # # @param package_name # Names the package that provides the `apt-add-repository` command. Default: 'software-properties-common'. # # @param package_manage # Specifies whether Puppet should manage the package that provides `apt-add-repository`. # define apt::ppa( String $ensure = 'present', Optional[String] $options = $::apt::ppa_options, - Optional[String] $release = $facts['lsbdistcodename'], - Optional[String] $dist = $facts['lsbdistid'], + Optional[String] $release = $facts['os']['distro']['codename'], + Optional[String] $dist = $facts['os']['name'], Optional[String] $package_name = $::apt::ppa_package, Boolean $package_manage = false, ) { unless $release { - fail(translate('lsbdistcodename fact not available: release parameter required')) + fail(translate('os.distro.codename fact not available: release parameter required')) } if $dist == 'Debian' { fail(translate('apt::ppa is not currently supported on Debian.')) } - if versioncmp($facts['lsbdistrelease'], '14.10') >= 0 { + if versioncmp($facts['os']['release']['full'], '14.10') >= 0 { $distid = downcase($dist) $dash_filename = regsubst($name, '^ppa:([^/]+)/(.+)$', "\\1-${distid}-\\2") $underscore_filename = regsubst($name, '^ppa:([^/]+)/(.+)$', "\\1_${distid}_\\2") } else { $dash_filename = regsubst($name, '^ppa:([^/]+)/(.+)$', "\\1-\\2") $underscore_filename = regsubst($name, '^ppa:([^/]+)/(.+)$', "\\1_\\2") } $dash_filename_no_slashes = regsubst($dash_filename, '/', '-', 'G') $dash_filename_no_specialchars = regsubst($dash_filename_no_slashes, '[\.\+]', '_', 'G') $underscore_filename_no_slashes = regsubst($underscore_filename, '/', '-', 'G') $underscore_filename_no_specialchars = regsubst($underscore_filename_no_slashes, '[\.\+]', '_', 'G') $sources_list_d_filename = "${dash_filename_no_specialchars}-${release}.list" - if versioncmp($facts['lsbdistrelease'], '15.10') >= 0 { + if versioncmp($facts['os']['release']['full'], '15.10') >= 0 { $trusted_gpg_d_filename = "${underscore_filename_no_specialchars}.gpg" } else { $trusted_gpg_d_filename = "${dash_filename_no_specialchars}.gpg" } if $ensure == 'present' { if $package_manage { ensure_packages($package_name) $_require = [File['sources.list.d'], Package[$package_name]] } else { $_require = File['sources.list.d'] } $_proxy = $::apt::_proxy if $_proxy['host'] { if $_proxy['https'] { $_proxy_env = ["http_proxy=http://${$_proxy['host']}:${$_proxy['port']}", "https_proxy=https://${$_proxy['host']}:${$_proxy['port']}"] } else { $_proxy_env = ["http_proxy=http://${$_proxy['host']}:${$_proxy['port']}"] } } else { $_proxy_env = [] } exec { "add-apt-repository-${name}": environment => $_proxy_env, command => "/usr/bin/add-apt-repository ${options} ${name} || (rm ${::apt::sources_list_d}/${sources_list_d_filename} && false)", unless => "/usr/bin/test -f ${::apt::sources_list_d}/${sources_list_d_filename} && /usr/bin/test -f ${::apt::trusted_gpg_d}/${trusted_gpg_d_filename}", user => 'root', logoutput => 'on_failure', notify => Class['apt::update'], require => $_require, } file { "${::apt::sources_list_d}/${sources_list_d_filename}": ensure => file, require => Exec["add-apt-repository-${name}"], } } else { file { "${::apt::sources_list_d}/${sources_list_d_filename}": ensure => 'absent', notify => Class['apt::update'], } } } diff --git a/manifests/source.pp b/manifests/source.pp index 365ba13..2c3d4b8 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -1,173 +1,173 @@ # @summary Manages the Apt sources in /etc/apt/sources.list.d/. # # @example Install the puppetlabs apt source # apt::source { 'puppetlabs': # location => 'http://apt.puppetlabs.com', # repos => 'main', # key => { # id => '6F6B15509CF8E59E6E469F327F438280EF8D349F', # server => 'hkps.pool.sks-keyservers.net', # }, # } # # @param location # Required, unless ensure is set to 'absent'. Specifies an Apt repository. Valid options: a string containing a repository URL. # # @param comment # Supplies a comment for adding to the Apt source file. # # @param ensure # Specifies whether the Apt source file should exist. Valid options: 'present' and 'absent'. # # @param release # Specifies a distribution of the Apt repository. # # @param repos # Specifies a component of the Apt repository. # # @param include # Configures include options. Valid options: a hash of available keys. -# +# # @option include [Boolean] :deb # Specifies whether to request the distribution's compiled binaries. Default true. # # @option include [Boolean] :src # Specifies whether to request the distribution's uncompiled source code. Default false. # # @param key -# Creates a declaration of the apt::key defined type. Valid options: a string to be passed to the `id` parameter of the `apt::key` -# defined type, or a hash of `parameter => value` pairs to be passed to `apt::key`'s `id`, `server`, `content`, `source`, and/or +# Creates a declaration of the apt::key defined type. Valid options: a string to be passed to the `id` parameter of the `apt::key` +# defined type, or a hash of `parameter => value` pairs to be passed to `apt::key`'s `id`, `server`, `content`, `source`, and/or # `options` parameters. # # @param pin -# Creates a declaration of the apt::pin defined type. Valid options: a number or string to be passed to the `id` parameter of the +# Creates a declaration of the apt::pin defined type. Valid options: a number or string to be passed to the `id` parameter of the # `apt::pin` defined type, or a hash of `parameter => value` pairs to be passed to `apt::pin`'s corresponding parameters. # # @param architecture -# 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'). Default: undef (if unspecified, Apt downloads information for all architectures +# 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'). Default: undef (if unspecified, Apt downloads information for all architectures # defined in the Apt::Architectures option). # # @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 notify_update # Specifies whether to trigger an `apt-get update` run. # define apt::source( Optional[String] $location = undef, String $comment = $name, String $ensure = present, Optional[String] $release = undef, String $repos = 'main', Optional[Variant[Hash]] $include = {}, Optional[Variant[String, Hash]] $key = undef, Optional[Variant[Hash, Numeric, String]] $pin = undef, Optional[String] $architecture = undef, Boolean $allow_unsigned = false, Boolean $notify_update = true, ) { include ::apt $_before = Apt::Setting["list-${title}"] if !$release { - if $facts['lsbdistcodename'] { - $_release = $facts['lsbdistcodename'] + if $facts['os']['distro']['codename'] { + $_release = $facts['os']['distro']['codename'] } else { - fail(translate('lsbdistcodename fact not available: release parameter required')) + fail(translate('os.distro.codename fact not available: release parameter required')) } } else { $_release = $release } if $ensure == 'present' { if ! $location { fail(translate('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 } # Newer oses, do not need the package for HTTPS transport. $_transport_https_releases = [ 'wheezy', 'jessie', 'stretch', 'trusty', 'xenial' ] - if ($facts['lsbdistcodename'] in $_transport_https_releases) and $_location =~ /(?i:^https:\/\/)/ { + if ($facts['os']['distro']['codename'] in $_transport_https_releases) and $_location =~ /(?i:^https:\/\/)/ { ensure_packages('apt-transport-https') } } else { $_location = undef } $includes = merge($::apt::include_defaults, $include) if $key { if $key =~ Hash { unless $key['id'] { fail(translate('key hash must contain at least an id entry')) } $_key = merge($::apt::source_key_defaults, $key) } else { $_key = { 'id' => assert_type(String[1], $key) } } } $header = epp('apt/_header.epp') $sourcelist = epp('apt/source.list.epp', { 'comment' => $comment, 'includes' => $includes, 'opt_architecture' => $architecture, 'allow_unsigned' => $allow_unsigned, 'location' => $_location, 'release' => $_release, 'repos' => $repos, }) apt::setting { "list-${name}": ensure => $ensure, content => "${header}${sourcelist}", notify_update => $notify_update, } if $pin { if $pin =~ Hash { $_pin = merge($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(translate('Received invalid value for pin parameter')) } create_resources('apt::pin', { "${name}" => $_pin }) } # We do not want to remove keys when the source is absent. if $key and ($ensure == 'present') { if $_key =~ Hash { if $_key['ensure'] != undef { $_ensure = $_key['ensure'] } else { $_ensure = $ensure } apt::key { "Add key: ${$_key['id']} from Apt::Source ${title}": ensure => $_ensure, id => $_key['id'], server => $_key['server'], content => $_key['content'], source => $_key['source'], options => $_key['options'], before => $_before, } } } } diff --git a/readmes/README_ja_JP.md b/readmes/README_ja_JP.md index eb0803c..be8ac75 100644 --- a/readmes/README_ja_JP.md +++ b/readmes/README_ja_JP.md @@ -1,291 +1,292 @@ # apt #### 目次 - 1. [説明 - モジュールの機能とその有益性](#module-description) 1. [セットアップ - apt導入の基本](#setup) * [aptが影響を与えるもの](#what-apt-affects) * [aptの使用を開始する](#beginning-with-apt) 1. [使用 - 設定オプションと追加機能](#usage) * [GPGキーの追加](#add-gpg-keys) * [バックポートの優先度を上げる](#prioritize-backports) * [パッケージリストの更新](#update-the-list-of-packages) * [特定のリリースのピン止め](#pin-a-specific-release) * [PPA (Personal Package Archive)レポジトリの追加](#add-a-personal-package-archive-repository) * [HieraからのAptの構成](#configure-apt-from-hiera) * [デフォルトのsources.listファイルの置き換え](#replace-the-default-sourceslist-file) 1. [参考 - モジュールの機能と動作について](#reference) 1. [制約 - OS互換性など](#limitations) 1. [開発 - モジュール貢献についてのガイド](#development) ## モジュールの概要 aptモジュールを導入すると、Puppetを使用してAPT (Advanced Package Tool)のソース、キー、その他の構成オプションを管理できます。 APTとは、Debian、Ubuntu、およびその他いくつかのオペレーティングシステムで利用可能なパッケージマネージャです。aptモジュールは、APTのパッケージ管理を自動化するのに役立つ一連のクラス、定義型、およびfactsを提供します。 -**注意**: このモジュールが実行中のDebian/Ubuntu (もしくは派生OS)のバージョンを正しく自動検出するためには、'lsb-release'パッケージがインストールされていることを確認する必要があります。これをプロビジョニングレイヤの一部にするか(多くのDebianシステムまたは派生OSシステムを実行する場合はこちらを推奨)、この依存関係を自動的に取得する機能をもつFacter 2.2.0以降をインストールしておくことを強くお勧めします。 +**注**:Puppet 7 より前は、このモジュールがどのバージョンのを正しく自動検出するか +実行している Debian / Ubuntu(または派生物)、 `lsb-release`パッケージが +インストールされています。 Puppet 7 では、 `lsb-release`パッケージは必要ありません。 ## セットアップ ### aptが影響を与えるもの * システムの`preferences`ファイルと`preferences.d`ディレクトリ * システムの `sources.list`ファイルと`sources.list.d`ディレクトリ * システムレポジトリ * 認証キー **注意:** このモジュールには`purge`パラメータがあります。このパラメータを`true`に設定すると、 ノードの `sources.list(.d)`および`preferences(.d)`の構成のうち、Puppetを通して宣言されていないものがすべて**破棄**されます。このパラメータのデフォルトは`false`です。 ### aptの使用を開始する デフォルトのパラメータでaptモジュールを使用するには、`apt`クラスを宣言します。 ```puppet include apt ``` **注意:** メインの`apt`クラスは、このモジュールに含まれるその他すべてのクラス、型、定義型によって要求されます。このモジュールを使用する際は、このクラスを必ず宣言する必要があります。 ## 使用 ### GPGキーの追加 **警告:** 短いキーIDを使用すると、衝突攻撃が有効になる可能性があり、セキュリティに深刻な問題が生じます。常に、完全なフィンガープリントを使用してGPGキーを識別することを推奨します。このモジュールでは短いキーの使用が許可されていますが、それを使用した場合、セキュリティ警告が発行されます。 `apt::key`の定義型を宣言するには、次のように記述します。 ```puppet apt::key { 'puppetlabs': id => '6F6B15509CF8E59E6E469F327F438280EF8D349F', server => 'pgp.mit.edu', options => 'http-proxy="http://proxyuser:proxypass@example.org:3128"', } ``` ### バックポートの優先度を上げる ```puppet class { 'apt::backports': pin => 500, } ``` デフォルトでは、`apt::backports`クラスはバックポート用のピンファイルをドロップし、優先度200にピン止めします。これは、通常のデフォルト値である500よりも低いため、`ensure => latest`に設定されているパッケージは、明示的な許可がない限り、バックポートからアップグレードされることはありません。 `pin`パラメータを使用して優先度を500に上げると、通常のポリシーが有効になり、Aptは最新のバージョンをインストールするか、最新のバージョンにアップグレードします。これはつまり、`package`リソースの`ensure`属性を明示的に`installed`/`present`もしくは特定のバージョンに設定していない限り、あるパッケージがバックポートから利用できる場合は、そのパッケージと依存関係がバックポートから取得されるということです。 ### パッケージリストの更新 デフォルトでは、`apt`クラスをインクルードした後の最初のPuppet実行時と、`notify => Exec['apt_update']`が発生するたびに(別の言い方をすれば、構成ファイルが更新されるか、関連するその他の変更が行われるたびに)、Puppetは`apt-get update`を実行します。`update['frequency']`を'always'に設定すると、Puppet実行時に毎回更新が行われます。`update['frequency']`は'daily'や'weekly'に設定することも可能です。 ```puppet class { 'apt': update => { frequency => 'daily', }, } ``` `Exec['apt_update']`がトリガされると、`Notice`メッセージが生成されます。デフォルトの[agentロギングレベル](https://docs.puppet.com/puppet/latest/configuration.html#loglevel)は`notice`であるため、このレポジトリの更新は、ログおよびagentレポートに記録されます。[Foreman](https://www.theforeman.org)など、一部のツールでは、このような更新通知が重要な変更としてレポートされます。これらの更新がレポートに記録されないようにするには、`Exec['apt_update']`の[loglevel](https://docs.puppet.com/puppet/latest/metaparameter.html#loglevel)メタパラメータをagentロギングレベルよりも高い値に設定します。 ```puppet class { 'apt': update => { frequency => 'daily', loglevel => 'debug', }, } ``` ### 特定のリリースのピン止め ```puppet apt::pin { 'karmic': priority => 700 } apt::pin { 'karmic-updates': priority => 700 } apt::pin { 'karmic-security': priority => 700 } ``` ディストリビューションのプロパティを使用して、より複雑なピンを指定することもできます。 ```puppet apt::pin { 'stable': priority => -10, originator => 'Debian', release_version => '3.0', component => 'main', label => 'Debian' } ``` 複数のパッケージをピン止めするには、配列またはスペース区切りの文字列としてその情報を`packages`パラメータに渡します。 ### PPA (Personal Package Archive)レポジトリの追加 ```puppet apt::ppa { 'ppa:drizzle-developers/ppa': } ``` ### `/etc/apt/sources.list.d/`へのAptソースの追加 ```puppet apt::source { 'debian_unstable': comment => 'This is the iWeb Debian unstable mirror', location => 'http://debian.mirror.iweb.ca/debian/', release => 'unstable', repos => 'main contrib non-free', pin => '-10', key => { 'id' => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', 'server' => 'subkeys.pgp.net', }, include => { 'src' => true, 'deb' => true, }, } ``` Puppet Aptレポジトリをソースとして使用するには、次のように記述します。 ```puppet apt::source { 'puppetlabs': location => 'http://apt.puppetlabs.com', repos => 'main', key => { 'id' => '6F6B15509CF8E59E6E469F327F438280EF8D349F', 'server' => 'pgp.mit.edu', }, } ``` ### HieraからのAptの構成 ソースをリソースとして直接指定するかわりに、単純に`apt`クラスをインクルードして、値をHieraから自動的に取得するように構成できます。 ```yaml apt::sources: 'debian_unstable': comment: 'This is the iWeb Debian unstable mirror' location: 'http://debian.mirror.iweb.ca/debian/' release: 'unstable' repos: 'main contrib non-free' pin: '-10' key: id: 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553' server: 'subkeys.pgp.net' include: src: true deb: true 'puppetlabs': location: 'http://apt.puppetlabs.com' repos: 'main' key: id: '6F6B15509CF8E59E6E469F327F438280EF8D349F' server: 'pgp.mit.edu' ``` ### デフォルトの`sources.list`ファイルの置き換え デフォルトの`/etc/apt/sources.list`を置き換える例を以下に示します。以下のコードと合わせて、`purge`パラメータを必ず使用してください。使用しない場合、Apt実行時にソース重複の警告が出ます。 ```puppet -apt::source { "archive.ubuntu.com-${lsbdistcodename}": +apt::source { "archive.ubuntu.com-${facts['os']['distro']['codename']}": location => 'http://archive.ubuntu.com/ubuntu', key => '630239CC130E1A7FD81A27B140976EAF437D05B5', repos => 'main universe multiverse restricted', } -apt::source { "archive.ubuntu.com-${lsbdistcodename}-security": +apt::source { "archive.ubuntu.com-${facts['os']['distro']['codename']}-security": location => 'http://archive.ubuntu.com/ubuntu', key => '630239CC130E1A7FD81A27B140976EAF437D05B5', repos => 'main universe multiverse restricted', - release => "${lsbdistcodename}-security" + release => "${facts['os']['distro']['codename']}-security" } -apt::source { "archive.ubuntu.com-${lsbdistcodename}-updates": +apt::source { "archive.ubuntu.com-${facts['os']['distro']['codename']}-updates": location => 'http://archive.ubuntu.com/ubuntu', key => '630239CC130E1A7FD81A27B140976EAF437D05B5', repos => 'main universe multiverse restricted', - release => "${lsbdistcodename}-updates" + release => "${facts['os']['distro']['codename']}-updates" } -apt::source { "archive.ubuntu.com-${lsbdistcodename}-backports": +apt::source { "archive.ubuntu.com-${facts['os']['distro']['codename']}-backports": location => 'http://archive.ubuntu.com/ubuntu', key => '630239CC130E1A7FD81A27B140976EAF437D05B5', repos => 'main universe multiverse restricted', - release => "${lsbdistcodename}-backports" + release => "${facts['os']['distro']['codename']}-backports" } ``` ### APTソースやプロキシのログイン設定を`/etc/apt/auth.conf`で管理する APTバージョン1.5以降、認証が必要なAPTソースやプロキシについて、ユーザ名やパスワードなどのログイン設定を`/etc/apt/auth.conf`ファイルに定義できるようになりました。この方法は、`source.list`内にログイン情報を直接記述するよりも推奨されます。直接記述した場合、通常、あらゆるユーザから読み取り可能になるためです。 `/etc/apt/auth.confファイルのフォーマットは、(ftpやcurlによって使用される) netrcに従い、ファイルパーミッションが制限されています。詳しくは、[こちら](https://manpages.debian.org/testing/apt/apt_auth.conf.5.en.html)を参照してください。 オプションの`apt::auth_conf_entries`パラメータを使用して、ログイン設定を含むハッシュの配列を指定します。このハッシュに含めることができるのは、`machine`、`login`、および`password`キーのみです。 ```puppet class { 'apt': auth_conf_entries => [ { 'machine' => 'apt-proxy.example.net', 'login' => 'proxylogin', 'password' => 'proxypassword', }, { 'machine' => 'apt.example.com/ubuntu', 'login' => 'reader', 'password' => 'supersecret', }, ], } ``` ## リファレンス ### Facts * `apt_updates`: `upgrade`で入手可能な更新がある、インストール済みパッケージの数。 * `apt_dist_updates`: `dist-upgrade`で入手可能な更新がある、インストール済みパッケージの数。 * `apt_security_updates`: `upgrade`で入手可能なセキュリティ更新がある、インストール済みパッケージの数。 * `apt_security_dist_updates`: `dist-upgrade`で入手可能なセキュリティ更新がある、インストール済みパッケージの数。 * `apt_package_updates`: `upgrade`で入手可能な更新がある、すべてのインストール済みパッケージの名前。Facter 2.0以降では、このデータのフォーマットは配列で、それ以前のバージョンでは、コンマ区切りの文字列です。 * `apt_package_dist_updates`: `dist-upgrade`で入手可能な更新がある、すべてのインストール済みパッケージの名前。Facter 2.0以降では、このデータのフォーマットは配列で、それ以前のバージョンでは、コンマ区切りの文字列です。 * `apt_update_last_success`: 直近で成功した`apt-get update`実行のエポックタイムによる日付(/var/lib/apt/periodic/update-success-stampのmtimeに基づく)。 * `apt_reboot_required`: 更新がインストールされた後に再起動が必要かどうかを決定します。 ### 詳細情報 その他すべてのリファレンスマニュアルについては、[REFERENCE.md](https://github.com/puppetlabs/puppetlabs-apt/blob/main/REFERENCE.md)を参照してください。 ## 制約 このモジュールは、[実行ステージ](https://docs.puppetlabs.com/puppet/latest/reference/lang_run_stages.html)に分割するようには設計されていません。 サポート対象のオペレーティングシステムの全リストについては、[metadata.json](https://github.com/puppetlabs/puppetlabs-apt/blob/main/metadata.json)を参照してください。 ### 新しいソースまたはPPAの追加 新しいソースまたはPPAを追加し、同一のPuppet実行において、その新しいソースまたはPPAからパッケージをインストールするには、`package`リソースが`Apt::Source`または`Apt::Ppa`に従属し、かつ`Class['apt::update']に従属する必要があります。[コレクタ](https://docs.puppetlabs.com/puppet/latest/reference/lang_collectors.html)を追加することによって、すべてのパッケージが`apt::update`の後に来るように制御することもできますが、その場合、循環依存が発生したり、[仮想リソース](https://docs.puppetlabs.com/puppet/latest/reference/lang_collectors.html#behavior)と関係したりすることがあります。以下のコマンドを実行する前に、すべてのパッケージのプロバイダがaptに設定されていることを確認してください。 ```puppet Class['apt::update'] -> Package <| provider == 'apt' |> ``` ## 開発 Puppet ForgeのPuppet Labsモジュールはオープンプロジェクトで、良い状態に保つためには、コミュニティの貢献が必要不可欠です。Puppetが役に立つはずでありながら、私たちがアクセスできないプラットフォームやハードウェア、ソフトウェア、デプロイ構成は無数にあります。私たちの目標は、できる限り簡単に変更に貢献し、みなさまの環境で私たちのモジュールが機能できるようにすることにあります。最高の状態を維持できるようにするために、コントリビュータが従う必要のあるいくつかのガイドラインが存在します。 詳細については、[モジュール貢献ガイド](https://docs.puppetlabs.com/forge/contributing.html)を参照してください。 すでにご協力いただいている方のリストについては、[コントリビュータのリスト](https://github.com/puppetlabs/puppetlabs-apt/graphs/contributors)をご覧ください。 diff --git a/spec/acceptance/apt_backports_spec.rb b/spec/acceptance/apt_backports_spec.rb new file mode 100644 index 0000000..5c4dcce --- /dev/null +++ b/spec/acceptance/apt_backports_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'spec_helper_acceptance' + +describe 'apt::backports' do + context 'when using defaults' do + let(:pp) do + <<-MANIFEST + include apt::backports + MANIFEST + end + + it 'applies idempotently' do + idempotent_apply(pp) + end + + it 'provides backports apt sources' do + run_shell('apt policy | grep --quiet backports') + end + end +end diff --git a/spec/classes/apt_backports_spec.rb b/spec/classes/apt_backports_spec.rb index 57e8a06..2f3865b 100644 --- a/spec/classes/apt_backports_spec.rb +++ b/spec/classes/apt_backports_spec.rb @@ -1,248 +1,292 @@ # frozen_string_literal: true require 'spec_helper' describe 'apt::backports', type: :class do let(:pre_condition) { "class{ '::apt': }" } describe 'debian/ubuntu tests' do context 'with defaults on deb' do let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'jessie', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, } end it { is_expected.to contain_apt__source('backports').with(location: 'http://deb.debian.org/debian', repos: 'main contrib non-free', release: 'jessie-backports', pin: { 'priority' => 200, 'release' => 'jessie-backports' }) } end context 'with defaults on ubuntu' do let(:facts) do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, - lsbdistid: 'Ubuntu', - osfamily: 'Debian', - lsbdistcodename: 'xenial', - lsbdistrelease: '16.04', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '16', + full: '16.04', + }, + distro: { + codename: 'xenial', + id: 'Ubuntu', + }, + }, } end it { is_expected.to contain_apt__source('backports').with(location: 'http://archive.ubuntu.com/ubuntu', key: '630239CC130E1A7FD81A27B140976EAF437D05B5', repos: 'main universe multiverse restricted', release: 'xenial-backports', pin: { 'priority' => 200, 'release' => 'xenial-backports' }) } end context 'with everything set' do let(:facts) do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, - lsbdistid: 'Ubuntu', - osfamily: 'Debian', - lsbdistcodename: 'xenial', - lsbdistrelease: '16.04', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '16', + full: '16.04', + }, + distro: { + codename: 'xenial', + id: 'Ubuntu', + }, + }, } end let(:params) do { location: 'http://archive.ubuntu.com/ubuntu-test', release: 'vivid', repos: 'main', key: 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', pin: '90', } end it { is_expected.to contain_apt__source('backports').with(location: 'http://archive.ubuntu.com/ubuntu-test', key: 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', repos: 'main', release: 'vivid', pin: { 'priority' => 90, 'release' => 'vivid' }) } end context 'when set things with hashes' do let(:facts) do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, - lsbdistid: 'Ubuntu', - osfamily: 'Debian', - lsbdistcodename: 'xenial', - lsbdistrelease: '16.04', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '16', + full: '16.04', + }, + distro: { + codename: 'xenial', + id: 'Ubuntu', + }, + }, } end let(:params) do { key: { 'id' => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', }, pin: { 'priority' => '90', }, } end it { is_expected.to contain_apt__source('backports').with(key: { 'id' => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553' }, pin: { 'priority' => '90' }) } end end describe 'mint tests' do let(:facts) do { - os: { family: 'Debian', name: 'Linuxmint', release: { major: '17', full: '17' } }, - lsbdistid: 'linuxmint', - osfamily: 'Debian', - lsbdistcodename: 'qiana', + os: { + family: 'Debian', + name: 'LinuxMint', + release: { + major: '17', + full: '17', + }, + distro: { + codename: 'qiana', + id: 'LinuxMint', + }, + }, } end context 'with all the needed things set' do let(:params) do { location: 'http://archive.ubuntu.com/ubuntu', release: 'trusty-backports', repos: 'main universe multiverse restricted', key: '630239CC130E1A7FD81A27B140976EAF437D05B5', } end it { is_expected.to contain_apt__source('backports').with(location: 'http://archive.ubuntu.com/ubuntu', key: '630239CC130E1A7FD81A27B140976EAF437D05B5', repos: 'main universe multiverse restricted', release: 'trusty-backports', pin: { 'priority' => 200, 'release' => 'trusty-backports' }) } end context 'with missing location' do let(:params) do { release: 'trusty-backports', repos: 'main universe multiverse restricted', key: '630239CC130E1A7FD81A27B140976EAF437D05B5', } end it do is_expected.to raise_error(Puppet::Error, %r{If not on Debian or Ubuntu, you must explicitly pass location, release, repos, and key}) end end context 'with missing release' do let(:params) do { location: 'http://archive.ubuntu.com/ubuntu', repos: 'main universe multiverse restricted', key: '630239CC130E1A7FD81A27B140976EAF437D05B5', } end it do is_expected.to raise_error(Puppet::Error, %r{If not on Debian or Ubuntu, you must explicitly pass location, release, repos, and key}) end end context 'with missing repos' do let(:params) do { location: 'http://archive.ubuntu.com/ubuntu', release: 'trusty-backports', key: '630239CC130E1A7FD81A27B140976EAF437D05B5', } end it do is_expected.to raise_error(Puppet::Error, %r{If not on Debian or Ubuntu, you must explicitly pass location, release, repos, and key}) end end context 'with missing key' do let(:params) do { location: 'http://archive.ubuntu.com/ubuntu', release: 'trusty-backports', repos: 'main universe multiverse restricted', } end it do is_expected.to raise_error(Puppet::Error, %r{If not on Debian or Ubuntu, you must explicitly pass location, release, repos, and key}) end end end describe 'validation' do let(:facts) do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, - lsbdistid: 'Ubuntu', - osfamily: 'Debian', - lsbdistcodename: 'xenial', - lsbdistrelease: '16.04', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '16', + full: '16.04', + }, + distro: { + codename: 'xenial', + id: 'Ubuntu', + }, + }, } end context 'with invalid location' do let(:params) do { location: true, } end it do is_expected.to raise_error(Puppet::Error, %r{expects a}) end end context 'with invalid release' do let(:params) do { release: true, } end it do is_expected.to raise_error(Puppet::Error, %r{expects a}) end end context 'with invalid repos' do let(:params) do { repos: true, } end it do is_expected.to raise_error(Puppet::Error, %r{expects a}) end end context 'with invalid key' do let(:params) do { key: true, } end it do is_expected.to raise_error(Puppet::Error, %r{expects a}) end end context 'with invalid pin' do let(:params) do { pin: true, } end it do is_expected.to raise_error(Puppet::Error, %r{expects a}) end end end end diff --git a/spec/classes/apt_spec.rb b/spec/classes/apt_spec.rb index f7ab7bc..ca23563 100644 --- a/spec/classes/apt_spec.rb +++ b/spec/classes/apt_spec.rb @@ -1,610 +1,717 @@ # frozen_string_literal: true require 'spec_helper' sources_list = { ensure: 'file', path: '/etc/apt/sources.list', owner: 'root', group: 'root', notify: 'Class[Apt::Update]' } sources_list_d = { ensure: 'directory', path: '/etc/apt/sources.list.d', owner: 'root', group: 'root', purge: false, recurse: false, notify: 'Class[Apt::Update]' } preferences = { ensure: 'file', path: '/etc/apt/preferences', owner: 'root', group: 'root', notify: 'Class[Apt::Update]' } preferences_d = { ensure: 'directory', path: '/etc/apt/preferences.d', owner: 'root', group: 'root', purge: false, recurse: false, notify: 'Class[Apt::Update]' } apt_conf_d = { ensure: 'directory', path: '/etc/apt/apt.conf.d', owner: 'root', group: 'root', purge: false, recurse: false, notify: 'Class[Apt::Update]' } describe 'apt' do let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'jessie', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, } end context 'with defaults' do it { is_expected.to contain_file('sources.list').that_notifies('Class[Apt::Update]').only_with(sources_list) } it { is_expected.to contain_file('sources.list.d').that_notifies('Class[Apt::Update]').only_with(sources_list_d) } it { is_expected.to contain_file('preferences').that_notifies('Class[Apt::Update]').only_with(preferences) } it { is_expected.to contain_file('preferences.d').that_notifies('Class[Apt::Update]').only_with(preferences_d) } it { is_expected.to contain_file('apt.conf.d').that_notifies('Class[Apt::Update]').only_with(apt_conf_d) } it { is_expected.to contain_file('/etc/apt/auth.conf').with_ensure('absent') } it 'lays down /etc/apt/apt.conf.d/15update-stamp' do is_expected.to contain_file('/etc/apt/apt.conf.d/15update-stamp').with(group: 'root', owner: 'root').with_content( %r{APT::Update::Post-Invoke-Success {"touch /var/lib/apt/periodic/update-success-stamp 2>/dev/null || true";};}, ) end it { is_expected.to contain_exec('apt_update').with(refreshonly: 'true') } it { is_expected.not_to contain_apt__setting('conf-proxy') } end describe 'proxy=' do context 'when host=localhost' do let(:params) { { proxy: { 'host' => 'localhost' } } } it { is_expected.to contain_apt__setting('conf-proxy').with(priority: '01').with_content( %r{Acquire::http::proxy "http://localhost:8080/";}, ).without_content( %r{Acquire::https::proxy}, ) } end context 'when host=localhost and port=8180' do let(:params) { { proxy: { 'host' => 'localhost', 'port' => 8180 } } } it { is_expected.to contain_apt__setting('conf-proxy').with(priority: '01').with_content( %r{Acquire::http::proxy "http://localhost:8180/";}, ).without_content( %r{Acquire::https::proxy}, ) } end context 'when host=localhost and https=true' do let(:params) { { proxy: { 'host' => 'localhost', 'https' => true } } } it { is_expected.to contain_apt__setting('conf-proxy').with(priority: '01').with_content( %r{Acquire::http::proxy "http://localhost:8080/";}, ).with_content( %r{Acquire::https::proxy "https://localhost:8080/";}, ) } end context 'when host=localhost and direct=true' do let(:params) { { proxy: { 'host' => 'localhost', 'direct' => true } } } it { is_expected.to contain_apt__setting('conf-proxy').with(priority: '01').with_content( %r{Acquire::http::proxy "http://localhost:8080/";}, ).with_content( %r{Acquire::https::proxy "DIRECT";}, ) } end context 'when host=localhost and https=true and direct=true' do let(:params) { { proxy: { 'host' => 'localhost', 'https' => true, 'direct' => true } } } it { is_expected.to contain_apt__setting('conf-proxy').with(priority: '01').with_content( %r{Acquire::http::proxy "http://localhost:8080/";}, ).with_content( %r{Acquire::https::proxy "https://localhost:8080/";}, ) } it { is_expected.to contain_apt__setting('conf-proxy').with(priority: '01').with_content( %r{Acquire::http::proxy "http://localhost:8080/";}, ).without_content( %r{Acquire::https::proxy "DIRECT";}, ) } end context 'when ensure=absent' do let(:params) { { proxy: { 'ensure' => 'absent' } } } it { is_expected.to contain_apt__setting('conf-proxy').with(ensure: 'absent', priority: '01') } end end context 'with lots of non-defaults' do let :params do { update: { 'frequency' => 'always', 'timeout' => 1, 'tries' => 3 }, purge: { 'sources.list' => false, 'sources.list.d' => false, 'preferences' => false, 'preferences.d' => false, 'apt.conf.d' => false }, } end it { is_expected.to contain_file('sources.list').with(content: nil) } it { is_expected.to contain_file('sources.list.d').with(purge: false, recurse: false) } it { is_expected.to contain_file('preferences').with(ensure: 'file') } it { is_expected.to contain_file('preferences.d').with(purge: false, recurse: false) } it { is_expected.to contain_file('apt.conf.d').with(purge: false, recurse: false) } it { is_expected.to contain_exec('apt_update').with(refreshonly: false, timeout: 1, tries: 3) } end context 'with lots of non-defaults' do let :params do { update: { 'frequency' => 'always', 'timeout' => 1, 'tries' => 3 }, purge: { 'sources.list' => true, 'sources.list.d' => true, 'preferences' => true, 'preferences.d' => true, 'apt.conf.d' => true }, } end it { is_expected.to contain_file('sources.list').with(content: "# Repos managed by puppet.\n") } it { is_expected.to contain_file('sources.list.d').with(purge: true, recurse: true) } it { is_expected.to contain_file('preferences').with(ensure: 'absent') } it { is_expected.to contain_file('preferences.d').with(purge: true, recurse: true) } it { is_expected.to contain_file('apt.conf.d').with(purge: true, recurse: true) } it { is_expected.to contain_exec('apt_update').with(refreshonly: false, timeout: 1, tries: 3) } end context 'with defaults for sources_list_force' do let :params do { update: { 'frequency' => 'always', 'timeout' => 1, 'tries' => 3 }, purge: { 'sources.list' => true }, sources_list_force: false, } end it { is_expected.to contain_file('sources.list').with(content: "# Repos managed by puppet.\n") } end context 'with non defaults for sources_list_force' do let :params do { update: { 'frequency' => 'always', 'timeout' => 1, 'tries' => 3 }, purge: { 'sources.list' => true }, sources_list_force: true, } end it { is_expected.to contain_file('sources.list').with(ensure: 'absent') } end context 'with entries for /etc/apt/auth.conf' do facts_hash = { 'Ubuntu 14.04' => { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '14', full: '14.04' } }, - osfamily: 'Debian', - lsbdistcodename: 'trusty', - lsbdistid: 'Ubuntu', - lsbdistrelease: '14.04', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '14', + full: '14.04', + }, + distro: { + codename: 'trusty', + id: 'Ubuntu', + }, + }, }, 'Ubuntu 16.04' => { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, - osfamily: 'Debian', - lsbdistcodename: 'xenial', - lsbdistid: 'Ubuntu', - lsbdistrelease: '16.04', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '16', + full: '16.04', + }, + distro: { + codename: 'xenial', + id: 'Ubuntu', + }, + }, }, 'Ubuntu 18.04' => { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '18', full: '18.04' } }, - osfamily: 'Debian', - lsbdistcodename: 'bionic', - lsbdistid: 'Ubuntu', - lsbdistrelease: '18.04', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '18', + full: '18.04', + }, + distro: { + codename: 'bionic', + id: 'Ubuntu', + }, + }, }, 'Debian 7.0' => { - os: { family: 'Debian', name: 'Debian', release: { major: '7', full: '7.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'wheezy', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '7', + full: '7.0', + }, + distro: { + codename: 'wheezy', + id: 'Debian', + }, + }, }, 'Debian 8.0' => { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'jessie', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, }, 'Debian 9.0' => { - os: { family: 'Debian', name: 'Debian', release: { major: '9', full: '9.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'stretch', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '9', + full: '9.0', + }, + distro: { + codename: 'stretch', + id: 'Debian', + }, + }, }, 'Debian 10.0' => { - os: { family: 'Debian', name: 'Debian', release: { major: '10', full: '10.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'buster', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '10', + full: '10.0', + }, + distro: { + codename: 'buster', + id: 'Debian', + }, + }, }, } facts_hash.each do |os, facts| context "on #{os}" do let(:facts) do facts end let(:params) do { auth_conf_entries: [ { machine: 'deb.example.net', login: 'foologin', password: 'secret', }, { machine: 'apt.example.com', login: 'aptlogin', password: 'supersecret', }, ], } end context 'with manage_auth_conf => true' do let(:params) do super().merge(manage_auth_conf: true) end # Going forward starting with Ubuntu 16.04 and Debian 9.0 # /etc/apt/auth.conf is owned by _apt. In previous versions it is # root. auth_conf_owner = case os when 'Ubuntu 14.04', 'Debian 7.0', 'Debian 8.0' 'root' else '_apt' end auth_conf_content = "// This file is managed by Puppet. DO NOT EDIT. machine deb.example.net login foologin password secret machine apt.example.com login aptlogin password supersecret " it { is_expected.to contain_file('/etc/apt/auth.conf').with(ensure: 'present', owner: auth_conf_owner, group: 'root', mode: '0600', notify: 'Class[Apt::Update]', content: sensitive(auth_conf_content)) } end context 'with manage_auth_conf => false' do let(:params) do super().merge(manage_auth_conf: false) end it { is_expected.not_to contain_file('/etc/apt/auth.conf') } end end context 'with improperly specified entries for /etc/apt/auth.conf' do let(:params) do { auth_conf_entries: [ { machinn: 'deb.example.net', username: 'foologin', password: 'secret', }, { machine: 'apt.example.com', login: 'aptlogin', password: 'supersecret', }, ], } end it { is_expected.to raise_error(Puppet::Error) } end end end - context 'with sources defined on valid osfamily' do + context 'with sources defined on valid os.family' do let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, - osfamily: 'Debian', - lsbdistcodename: 'xenial', - lsbdistid: 'Ubuntu', - lsbdistrelease: '16.04', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '16', + full: '16.04', + }, + distro: { + codename: 'xenial', + id: 'Ubuntu', + }, + }, } end let(:params) do { sources: { 'debian_unstable' => { 'location' => 'http://debian.mirror.iweb.ca/debian/', 'release' => 'unstable', 'repos' => 'main contrib non-free', 'key' => { 'id' => '150C8614919D8446E01E83AF9AA38DCD55BE302B', 'server' => 'subkeys.pgp.net' }, 'pin' => '-10', 'include' => { 'src' => true }, }, 'puppetlabs' => { 'location' => 'http://apt.puppetlabs.com', 'repos' => 'main', 'key' => { 'id' => '6F6B15509CF8E59E6E469F327F438280EF8D349F', 'server' => 'pgp.mit.edu' }, }, } } end it { is_expected.to contain_apt__setting('list-debian_unstable').with(ensure: 'present') } it { is_expected.to contain_file('/etc/apt/sources.list.d/debian_unstable.list').with_content(%r{^deb http://debian.mirror.iweb.ca/debian/ unstable main contrib non-free$}) } it { is_expected.to contain_file('/etc/apt/sources.list.d/debian_unstable.list').with_content(%r{^deb-src http://debian.mirror.iweb.ca/debian/ unstable main contrib non-free$}) } it { is_expected.to contain_apt__setting('list-puppetlabs').with(ensure: 'present') } it { is_expected.to contain_file('/etc/apt/sources.list.d/puppetlabs.list').with_content(%r{^deb http://apt.puppetlabs.com xenial main$}) } end - context 'with confs defined on valid osfamily' do + context 'with confs defined on valid os.family' do let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, - osfamily: 'Debian', - lsbdistcodename: 'xenial', - lsbdistid: 'Ubuntu', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '16', + full: '16.04', + }, + distro: { + codename: 'xenial', + id: 'Ubuntu', + }, + }, } end let(:params) do { confs: { 'foo' => { 'content' => 'foo', }, 'bar' => { 'content' => 'bar', }, } } end it { is_expected.to contain_apt__conf('foo').with(content: 'foo') } it { is_expected.to contain_apt__conf('bar').with(content: 'bar') } end - context 'with keys defined on valid osfamily' do + context 'with keys defined on valid os.family' do let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, - osfamily: 'Debian', - lsbdistcodename: 'xenial', - lsbdistid: 'Ubuntu', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '16', + full: '16.04', + }, + distro: { + codename: 'xenial', + id: 'Ubuntu', + }, + }, } end let(:params) do { keys: { '55BE302B' => { 'server' => 'subkeys.pgp.net', }, 'EF8D349F' => { 'server' => 'pgp.mit.edu', }, } } end it { is_expected.to contain_apt__key('55BE302B').with(server: 'subkeys.pgp.net') } it { is_expected.to contain_apt__key('EF8D349F').with(server: 'pgp.mit.edu') } end - context 'with ppas defined on valid osfamily' do + context 'with ppas defined on valid os.family' do let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, - osfamily: 'Debian', - lsbdistcodename: 'xenial', - lsbdistid: 'Ubuntu', - lsbdistrelease: '16.04', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '16', + full: '16.04', + }, + distro: { + codename: 'xenial', + id: 'Ubuntu', + }, + }, } end let(:params) do { ppas: { 'ppa:drizzle-developers/ppa' => {}, 'ppa:nginx/stable' => {}, } } end it { is_expected.to contain_apt__ppa('ppa:drizzle-developers/ppa') } it { is_expected.to contain_apt__ppa('ppa:nginx/stable') } end - context 'with settings defined on valid osfamily' do + context 'with settings defined on valid os.family' do let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, - osfamily: 'Debian', - lsbdistcodename: 'xenial', - lsbdistid: 'Ubuntu', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '16', + full: '16.04', + }, + distro: { + codename: 'xenial', + id: 'Ubuntu', + }, + }, } end let(:params) do { settings: { 'conf-banana' => { 'content' => 'banana' }, 'pref-banana' => { 'content' => 'banana' }, } } end it { is_expected.to contain_apt__setting('conf-banana') } it { is_expected.to contain_apt__setting('pref-banana') } end - context 'with pins defined on valid osfamily' do + context 'with pins defined on valid os.family' do let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, - osfamily: 'Debian', - lsbdistcodename: 'xenial', - lsbdistid: 'Ubuntu', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '16', + full: '16.04', + }, + distro: { + codename: 'xenial', + id: 'Ubuntu', + }, + }, } end let(:params) do { pins: { 'stable' => { 'priority' => 600, 'order' => 50 }, 'testing' => { 'priority' => 700, 'order' => 100 }, } } end it { is_expected.to contain_apt__pin('stable') } it { is_expected.to contain_apt__pin('testing') } end describe 'failing tests' do context "with purge['sources.list']=>'banana'" do let(:params) { { purge: { 'sources.list' => 'banana' } } } it do is_expected.to raise_error(Puppet::Error) end end context "with purge['sources.list.d']=>'banana'" do let(:params) { { purge: { 'sources.list.d' => 'banana' } } } it do is_expected.to raise_error(Puppet::Error) end end context "with purge['preferences']=>'banana'" do let(:params) { { purge: { 'preferences' => 'banana' } } } it do is_expected.to raise_error(Puppet::Error) end end context "with purge['preferences.d']=>'banana'" do let(:params) { { purge: { 'preferences.d' => 'banana' } } } it do is_expected.to raise_error(Puppet::Error) end end context "with purge['apt.conf.d']=>'banana'" do let(:params) { { purge: { 'apt.conf.d' => 'banana' } } } it do is_expected.to raise_error(Puppet::Error) end end end end diff --git a/spec/classes/apt_update_spec.rb b/spec/classes/apt_update_spec.rb index 463566b..c6336a9 100644 --- a/spec/classes/apt_update_spec.rb +++ b/spec/classes/apt_update_spec.rb @@ -1,147 +1,203 @@ # frozen_string_literal: true require 'spec_helper' describe 'apt::update', type: :class do context "when apt::update['frequency']='always'" do { 'a recent run' => Time.now.to_i, 'we are due for a run' => 1_406_660_561, 'the update-success-stamp file does not exist' => -1, }.each_pair do |desc, factval| context "when $::apt_update_last_success indicates #{desc}" do let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, apt_update_last_success: factval, - lsbdistcodename: 'jessie', } end let(:pre_condition) do "class{'::apt': update => {'frequency' => 'always' },}" end it 'triggers an apt-get update run' do # set the apt_update exec's refreshonly attribute to false is_expected.to contain_exec('apt_update').with('refreshonly' => false) end end end context 'when $::apt_update_last_success is nil' do let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'jessie', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, } end let(:pre_condition) { "class{ '::apt': update => {'frequency' => 'always' },}" } it 'triggers an apt-get update run' do # set the apt_update exec\'s refreshonly attribute to false is_expected.to contain_exec('apt_update').with('refreshonly' => false) end end end context "when apt::update['frequency']='reluctantly'" do { 'a recent run' => Time.now.to_i, 'we are due for a run' => 1_406_660_561, 'the update-success-stamp file does not exist' => -1, }.each_pair do |desc, factval| context "when $::apt_update_last_success indicates #{desc}" do let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, apt_update_last_success: factval, - lsbdistcodename: 'jessie', } end let(:pre_condition) { "class{ '::apt': update => {'frequency' => 'reluctantly' },}" } it 'does not trigger an apt-get update run' do # don't change the apt_update exec's refreshonly attribute. (it should be true) is_expected.to contain_exec('apt_update').with('refreshonly' => true) end end end context 'when $::apt_update_last_success is nil' do let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'jessie', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, } end let(:pre_condition) { "class{ '::apt': update => {'frequency' => 'reluctantly' },}" } it 'does not trigger an apt-get update run' do # don't change the apt_update exec's refreshonly attribute. (it should be true) is_expected.to contain_exec('apt_update').with('refreshonly' => true) end end end ['daily', 'weekly'].each do |update_frequency| context "when apt::update['frequency'] has the value of #{update_frequency}" do { 'we are due for a run' => 1_406_660_561, 'the update-success-stamp file does not exist' => -1 }.each_pair do |desc, factval| context "when $::apt_update_last_success indicates #{desc}" do let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, apt_update_last_success: factval, - lsbdistcodename: 'jessie', } end let(:pre_condition) { "class{ '::apt': update => {'frequency' => '#{update_frequency}',} }" } it 'triggers an apt-get update run' do # set the apt_update exec\'s refreshonly attribute to false is_expected.to contain_exec('apt_update').with('refreshonly' => false) end end end context 'when the $::apt_update_last_success fact has a recent value' do let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'jessie', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, apt_update_last_success: Time.now.to_i, } end let(:pre_condition) { "class{ '::apt': update => {'frequency' => '#{update_frequency}',} }" } it 'does not trigger an apt-get update run' do # don't change the apt_update exec\'s refreshonly attribute. (it should be true) is_expected.to contain_exec('apt_update').with('refreshonly' => true) end end context 'when $::apt_update_last_success is nil' do let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'jessie', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, apt_update_last_success: nil, } end let(:pre_condition) { "class{ '::apt': update => {'frequency' => '#{update_frequency}',} }" } it 'triggers an apt-get update run' do # set the apt_update exec\'s refreshonly attribute to false is_expected.to contain_exec('apt_update').with('refreshonly' => false) end end end end end diff --git a/spec/defines/conf_spec.rb b/spec/defines/conf_spec.rb index 3158c16..310e15a 100644 --- a/spec/defines/conf_spec.rb +++ b/spec/defines/conf_spec.rb @@ -1,89 +1,97 @@ # frozen_string_literal: true require 'spec_helper' describe 'apt::conf', type: :define do let :pre_condition do 'class { "apt": }' end let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'jessie', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, } end let :title do 'norecommends' end describe 'when creating an apt preference' do let :default_params do { priority: '00', content: "Apt::Install-Recommends 0;\nApt::AutoRemove::InstallRecommends 1;\n", } end let :params do default_params end let :filename do '/etc/apt/apt.conf.d/00norecommends' end it { is_expected.to contain_file(filename).with('ensure' => 'present', 'content' => %r{Apt::Install-Recommends 0;\nApt::AutoRemove::InstallRecommends 1;}, 'owner' => 'root', 'group' => 'root') } context 'with notify_update = true (default)' do let :params do default_params end it { is_expected.to contain_apt__setting("conf-#{title}").with_notify_update(true) } end context 'with notify_update = false' do let :params do default_params.merge(notify_update: false) end it { is_expected.to contain_apt__setting("conf-#{title}").with_notify_update(false) } end end describe 'when creating a preference without content' do let :params do { priority: '00', } end it 'fails' do is_expected.to raise_error(%r{pass in content}) end end describe 'when removing an apt preference' do let :params do { ensure: 'absent', priority: '00', } end let :filename do '/etc/apt/apt.conf.d/00norecommends' end it { is_expected.to contain_file(filename).with('ensure' => 'absent', 'owner' => 'root', 'group' => 'root') } end end diff --git a/spec/defines/key_compat_spec.rb b/spec/defines/key_compat_spec.rb index fc401ba..e2a76e0 100644 --- a/spec/defines/key_compat_spec.rb +++ b/spec/defines/key_compat_spec.rb @@ -1,361 +1,370 @@ # frozen_string_literal: true require 'spec_helper' def contains_apt_key_example(title) { id: title, ensure: 'present', source: 'http://apt.puppetlabs.com/pubkey.gpg', server: 'pgp.mit.edu', content: params[:content], options: 'debug' } end def apt_key_example(title) { id: title, ensure: 'present', source: nil, server: 'keyserver.ubuntu.com', content: nil, keyserver_options: nil } end describe 'apt::key', type: :define do GPG_KEY_ID = '6F6B15509CF8E59E6E469F327F438280EF8D349F' let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, } end let :title do GPG_KEY_ID end let :pre_condition do 'include apt' end describe 'normal operation' do describe 'default options' do it { is_expected.to contain_apt_key(title).with(id: title, ensure: 'present', source: nil, server: 'keyserver.ubuntu.com', content: nil) } it 'contains the apt_key present anchor' do is_expected.to contain_anchor("apt_key #{title} present") end end describe 'title and key =>' do let :title do 'puppetlabs' end let :params do { id: GPG_KEY_ID, } end it 'contains the apt_key' do is_expected.to contain_apt_key(title).with(id: GPG_KEY_ID, ensure: 'present', source: nil, server: 'keyserver.ubuntu.com', content: nil) end it 'contains the apt_key present anchor' do is_expected.to contain_anchor("apt_key #{GPG_KEY_ID} present") end end describe 'ensure => absent' do let :params do { ensure: 'absent', } end it 'contains the apt_key' do is_expected.to contain_apt_key(title).with(id: title, ensure: 'absent', source: nil, server: 'keyserver.ubuntu.com', content: nil) end it 'contains the apt_key absent anchor' do is_expected.to contain_anchor("apt_key #{title} absent") end end describe 'set a bunch of things!' do let :params do { content: 'GPG key content', source: 'http://apt.puppetlabs.com/pubkey.gpg', server: 'pgp.mit.edu', options: 'debug', } end it 'contains the apt_key' do is_expected.to contain_apt_key(title).with(contains_apt_key_example(title)) end it 'contains the apt_key present anchor' do is_expected.to contain_anchor("apt_key #{title} present") end end context 'when domain has dash' do let(:params) do { server: 'p-gp.m-it.edu', } end it 'contains the apt_key' do is_expected.to contain_apt_key(title).with(id: title, server: 'p-gp.m-it.edu') end end context 'with url' do let :params do { server: 'hkp://pgp.mit.edu', } end it 'contains the apt_key' do is_expected.to contain_apt_key(title).with(id: title, server: 'hkp://pgp.mit.edu') end end context 'with url and port number' do let :params do { server: 'hkp://pgp.mit.edu:80', } end it 'contains the apt_key' do is_expected.to contain_apt_key(title).with(id: title, server: 'hkp://pgp.mit.edu:80') end end end describe 'validation' do context 'when domain begins with a dash' do let(:params) do { server: '-pgp.mit.edu', } end it 'fails' do is_expected .to raise_error(%r{expects a match}) end end context 'when domain begins with dot' do let(:params) do { server: '.pgp.mit.edu', } end it 'fails' do is_expected .to raise_error(%r{expects a match}) end end context 'when domain ends with dot' do let(:params) do { server: 'pgp.mit.edu.', } end it 'fails' do is_expected .to raise_error(%r{expects a match}) end end context 'when url character limit is exceeded' do let :params do { server: 'hkp://pgpiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.mit.edu', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with incorrect port number url' do let :params do { server: 'hkp://pgp.mit.edu:8008080', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with incorrect protocol for url' do let :params do { server: 'abc://pgp.mit.edu:80', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with missing port number url' do let :params do { server: 'hkp://pgp.mit.edu:', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with url ending with a dot' do let :params do { server: 'hkp://pgp.mit.edu.', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with url begin with a dash' do let(:params) do { server: 'hkp://-pgp.mit.edu', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with invalid key' do let :title do 'Out of rum. Why? Why are we out of rum?' end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with invalid source' do let :params do { source: 'afp://puppetlabs.com/key.gpg', } end it 'fails' do is_expected.to raise_error(%r{evaluating a Resource}) end end context 'with invalid content' do let :params do { content: [], } end it 'fails' do is_expected.to raise_error(%r{expects a}) end end context 'with invalid server' do let :params do { server: 'two bottles of rum', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with invalid keyserver_options' do let :params do { options: {}, } end it 'fails' do is_expected.to raise_error(%r{expects a}) end end context 'with invalid ensure' do let :params do { ensure: 'foo', } end it 'fails' do is_expected.to raise_error(%r{Enum\['absent', 'present', 'refreshed'\]}) end end describe 'duplication - two apt::key resources for same key, different titles' do let :pre_condition do "#{super()}\napt::key { 'duplicate': id => '#{title}', }" end it 'contains the duplicate apt::key resource' do is_expected.to contain_apt__key('duplicate').with(id: title, ensure: 'present') end it 'contains the original apt::key resource' do is_expected.to contain_apt__key(title).with(id: title, ensure: 'present') end it 'contains the native apt_key' do is_expected.to contain_apt_key('duplicate').with(apt_key_example(title)) end it 'does not contain the original apt_key' do is_expected.not_to contain_apt_key(title) end end describe 'duplication - two apt::key resources, different ensure' do let :pre_condition do "#{super()}\napt::key { 'duplicate': id => '#{title}', ensure => 'absent', }" end it 'informs the user of the impossibility' do is_expected.to raise_error(%r{already ensured as absent}) end end end end diff --git a/spec/defines/key_spec.rb b/spec/defines/key_spec.rb index 6ad0978..fc40a86 100644 --- a/spec/defines/key_spec.rb +++ b/spec/defines/key_spec.rb @@ -1,410 +1,418 @@ # frozen_string_literal: true require 'spec_helper' GPG_KEY_ID = '6F6B15509CF8E59E6E469F327F438280EF8D349F' title_key_example = { id: GPG_KEY_ID, ensure: 'present', source: nil, server: 'keyserver.ubuntu.com', content: nil, options: nil } def default_apt_key_example(title) { id: title, ensure: 'present', source: nil, server: 'keyserver.ubuntu.com', content: nil, options: nil, refresh: false } end def bunch_things_apt_key_example(title, params) { id: title, ensure: 'present', source: 'http://apt.puppetlabs.com/pubkey.gpg', server: 'pgp.mit.edu', content: params[:content], options: 'debug' } end def absent_apt_key(title) { id: title, ensure: 'absent', source: nil, server: 'keyserver.ubuntu.com', content: nil, keyserver: nil } end describe 'apt::key' do let :pre_condition do 'class { "apt": }' end let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'jessie', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, } end let :title do GPG_KEY_ID end describe 'normal operation' do describe 'default options' do it 'contains the apt_key' do is_expected.to contain_apt_key(title).with(default_apt_key_example(title)) end it 'contains the apt_key present anchor' do is_expected.to contain_anchor("apt_key #{title} present") end end describe 'title and key =>' do let :title do 'puppetlabs' end let :params do { id: GPG_KEY_ID, } end it 'contains the apt_key' do is_expected.to contain_apt_key(title).with(title_key_example) end it 'contains the apt_key present anchor' do is_expected.to contain_anchor("apt_key #{GPG_KEY_ID} present") end end describe 'ensure => absent' do let :params do { ensure: 'absent', } end it 'contains the apt_key' do is_expected.to contain_apt_key(title).with(absent_apt_key(title)) end it 'contains the apt_key absent anchor' do is_expected.to contain_anchor("apt_key #{title} absent") end end describe 'ensure => refreshed' do let :params do { ensure: 'refreshed', } end it 'contains the apt_key with refresh => true' do is_expected.to contain_apt_key(title).with( ensure: 'present', refresh: true, ) end end describe 'set a bunch of things!' do let :params do { content: 'GPG key content', source: 'http://apt.puppetlabs.com/pubkey.gpg', server: 'pgp.mit.edu', options: 'debug', } end it 'contains the apt_key' do is_expected.to contain_apt_key(title).with(bunch_things_apt_key_example(title, params)) end it 'contains the apt_key present anchor' do is_expected.to contain_anchor("apt_key #{title} present") end end context 'when domain with dash' do let(:params) do { server: 'p-gp.m-it.edu', } end it 'contains the apt_key' do is_expected.to contain_apt_key(title).with(id: title, server: 'p-gp.m-it.edu') end end context 'with url' do let :params do { server: 'hkp://pgp.mit.edu', } end it 'contains the apt_key' do is_expected.to contain_apt_key(title).with(id: title, server: 'hkp://pgp.mit.edu') end end context 'when url with port number' do let :params do { server: 'hkp://pgp.mit.edu:80', } end it 'contains the apt_key' do is_expected.to contain_apt_key(title).with(id: title, server: 'hkp://pgp.mit.edu:80') end end end describe 'validation' do context 'when domain begin with dash' do let(:params) do { server: '-pgp.mit.edu', } end it 'fails' do is_expected .to raise_error(%r{expects a match}) end end context 'when domain begin with dot' do let(:params) do { server: '.pgp.mit.edu', } end it 'fails' do is_expected .to raise_error(%r{expects a match}) end end context 'when domain end with dot' do let(:params) do { server: 'pgp.mit.edu.', } end it 'fails' do is_expected .to raise_error(%r{expects a match}) end end context 'when character url exceeded' do let :params do { server: 'hkp://pgpiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.mit.edu', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with incorrect port number url' do let :params do { server: 'hkp://pgp.mit.edu:8008080', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with incorrect protocol for url' do let :params do { server: 'abc://pgp.mit.edu:80', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with missing port number url' do let :params do { server: 'hkp://pgp.mit.edu:', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with url ending with a dot' do let :params do { server: 'hkp://pgp.mit.edu.', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'when url begins with a dash' do let(:params) do { server: 'hkp://-pgp.mit.edu', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with invalid key' do let :title do 'Out of rum. Why? Why are we out of rum?' end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with invalid source' do let :params do { source: 'afp://puppetlabs.com/key.gpg', } end it 'fails' do is_expected.to raise_error(%r{evaluating a Resource}) end end context 'with invalid content' do let :params do { content: [], } end it 'fails' do is_expected.to raise_error(%r{expects a}) end end context 'with invalid server' do let :params do { server: 'two bottles of rum', } end it 'fails' do is_expected.to raise_error(%r{expects a match}) end end context 'with invalid options' do let :params do { options: {}, } end it 'fails' do is_expected.to raise_error(%r{expects a}) end end context 'with invalid ensure' do ['foo', 'aabsent', 'absenta', 'apresent', 'presenta', 'refresh', 'arefreshed', 'refresheda'].each do |param| let :params do { ensure: param, } end it 'fails' do is_expected.to raise_error(%r{for Enum\['absent', 'present', 'refreshed'\], got}) end end end describe 'duplication - two apt::key resources for same key, different titles' do let :pre_condition do "class { 'apt': } apt::key { 'duplicate': id => '#{title}', }" end it 'contains two apt::key resource - duplicate' do is_expected.to contain_apt__key('duplicate').with(id: title, ensure: 'present') end it 'contains two apt::key resource - title' do is_expected.to contain_apt__key(title).with(id: title, ensure: 'present') end it 'contains only a single apt_key - duplicate' do is_expected.to contain_apt_key('duplicate').with(default_apt_key_example(title)) end it 'contains only a single apt_key - no title' do is_expected.not_to contain_apt_key(title) end end describe 'duplication - two apt::key resources, different ensure' do let :pre_condition do "class { 'apt': } apt::key { 'duplicate': id => '#{title}', ensure => 'absent', }" end it 'informs the user of the impossibility' do is_expected.to raise_error(%r{already ensured as absent}) end end end describe 'defaults' do context 'when setting keyserver on the apt class' do let :pre_condition do 'class { "apt": keyserver => "keyserver.example.com", }' end it 'uses default keyserver' do is_expected.to contain_apt_key(title).with_server('keyserver.example.com') end end context 'when setting key_options on the apt class' do let :pre_condition do 'class { "apt": key_options => "http-proxy=http://proxy.example.com:8080", }' end it 'uses default keyserver' do is_expected.to contain_apt_key(title).with_options('http-proxy=http://proxy.example.com:8080') end end end end diff --git a/spec/defines/mark_spec.rb b/spec/defines/mark_spec.rb index 9228510..0d059a5 100644 --- a/spec/defines/mark_spec.rb +++ b/spec/defines/mark_spec.rb @@ -1,42 +1,50 @@ # frozen_string_literal: true require 'spec_helper' describe 'apt::mark', type: :define do let :title do 'my_source' end let :facts do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - lsbdistcodename: 'jessie', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, } end context 'with correct seting' do let :params do { 'setting' => 'manual', } end it { is_expected.to contain_exec('/usr/bin/apt-mark manual my_source') } end describe 'with wrong setting' do let :params do { 'setting' => 'foobar', } end it do is_expected.to raise_error(Puppet::PreformattedError, %r{expects a match for Enum\['auto', 'hold', 'manual', 'unhold'\], got 'foobar'}) end end end diff --git a/spec/defines/pin_spec.rb b/spec/defines/pin_spec.rb index fd56dbf..1b6ac33 100644 --- a/spec/defines/pin_spec.rb +++ b/spec/defines/pin_spec.rb @@ -1,149 +1,157 @@ # frozen_string_literal: true require 'spec_helper' describe 'apt::pin', type: :define do let :pre_condition do 'class { "apt": }' end let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'jessie', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, } end let(:title) { 'my_pin' } context 'with defaults' do it { is_expected.to contain_apt__setting('pref-my_pin').with_content(%r{Explanation: : my_pin\nPackage: \*\nPin: release a=my_pin\nPin-Priority: 0\n}) } end context 'with set version' do let :params do { 'packages' => 'vim', 'version' => '1', } end it { is_expected.to contain_apt__setting('pref-my_pin').with_content(%r{Explanation: : my_pin\nPackage: vim\nPin: version 1\nPin-Priority: 0\n}) } end context 'with set origin' do let :params do { 'packages' => 'vim', 'origin' => 'test', } end it { is_expected.to contain_apt__setting('pref-my_pin').with_content(%r{Explanation: : my_pin\nPackage: vim\nPin: origin test\nPin-Priority: 0\n}) } end context 'without defaults' do let :params do { 'explanation' => 'foo', 'order' => 99, 'release' => '1', 'codename' => 'bar', 'release_version' => '2', 'component' => 'baz', 'originator' => 'foobar', 'label' => 'foobaz', 'priority' => 10, } end it { is_expected.to contain_apt__setting('pref-my_pin').with_content(%r{Explanation: foo\nPackage: \*\nPin: release a=1, n=bar, v=2, c=baz, o=foobar, l=foobaz\nPin-Priority: 10\n}) } it { is_expected.to contain_apt__setting('pref-my_pin').with('priority' => 99) } end context 'with ensure absent' do let :params do { 'ensure' => 'absent', } end it { is_expected.to contain_apt__setting('pref-my_pin').with('ensure' => 'absent') } end context 'with bad characters' do let(:title) { 'such bad && wow!' } it { is_expected.to contain_apt__setting('pref-such__bad____wow_') } end describe 'validation' do context 'with invalid order' do let :params do { 'order' => 'foo', } end it do is_expected.to raise_error(Puppet::Error, %r{expects an Integer value, got String}) end end context 'with packages == * and version' do let :params do { 'version' => '1', } end it do is_expected.to raise_error(Puppet::Error, %r{parameter version cannot be used in general form}) end end context 'with packages == * and release and origin' do let :params do { 'origin' => 'test', 'release' => 'foo', } end it do is_expected.to raise_error(Puppet::Error, %r{parameters release and origin are mutually exclusive}) end end context 'with specific release and origin' do let :params do { 'release' => 'foo', 'origin' => 'test', 'packages' => 'vim', } end it do is_expected.to raise_error(Puppet::Error, %r{parameters release, origin, and version are mutually exclusive}) end end context 'with specific version and origin' do let :params do { 'version' => '1', 'origin' => 'test', 'packages' => 'vim', } end it do is_expected.to raise_error(Puppet::Error, %r{parameters release, origin, and version are mutually exclusive}) end end end end diff --git a/spec/defines/ppa_spec.rb b/spec/defines/ppa_spec.rb index b0e689e..43ee754 100644 --- a/spec/defines/ppa_spec.rb +++ b/spec/defines/ppa_spec.rb @@ -1,330 +1,396 @@ # frozen_string_literal: true require 'spec_helper' describe 'apt::ppa' do let :pre_condition do 'class { "apt": }' end describe 'defaults' do let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '14', full: '41.04' } }, - lsbdistrelease: '14.04', - lsbdistcodename: 'trusty', - operatingsystem: 'Ubuntu', - osfamily: 'Debian', - lsbdistid: 'Ubuntu', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '14', + full: '14.04', + }, + distro: { + codename: 'trusty', + id: 'Ubuntu', + }, + }, } end let(:title) { 'ppa:needs/such.substitution/wow+type' } it { is_expected.not_to contain_package('python-software-properties') } it { is_expected.to contain_exec('add-apt-repository-ppa:needs/such.substitution/wow+type').that_notifies('Class[Apt::Update]').with(environment: [], command: '/usr/bin/add-apt-repository -y ppa:needs/such.substitution/wow+type || (rm /etc/apt/sources.list.d/needs-such_substitution-wow_type-trusty.list && false)', # rubocop:disable Layout/LineLength unless: '/usr/bin/test -f /etc/apt/sources.list.d/needs-such_substitution-wow_type-trusty.list && /usr/bin/test -f /etc/apt/trusted.gpg.d/needs-such_substitution-wow_type.gpg', # rubocop:disable Layout/LineLength user: 'root', logoutput: 'on_failure') } end describe 'Ubuntu 15.10 sources.list filename' do let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '15', full: '15.10' } }, - lsbdistrelease: '15.10', - lsbdistcodename: 'wily', - operatingsystem: 'Ubuntu', - osfamily: 'Debian', - lsbdistid: 'Ubuntu', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '15', + full: '15.10', + }, + distro: { + codename: 'wily', + id: 'Ubuntu', + }, + }, } end let(:title) { 'ppa:user/foo' } it { is_expected.to contain_exec('add-apt-repository-ppa:user/foo').that_notifies('Class[Apt::Update]').with(environment: [], command: '/usr/bin/add-apt-repository -y ppa:user/foo || (rm /etc/apt/sources.list.d/user-ubuntu-foo-wily.list && false)', # rubocop:disable Layout/LineLength unless: '/usr/bin/test -f /etc/apt/sources.list.d/user-ubuntu-foo-wily.list && /usr/bin/test -f /etc/apt/trusted.gpg.d/user_ubuntu_foo.gpg', # rubocop:disable Layout/LineLength user: 'root', logoutput: 'on_failure') } end describe 'package_name => software-properties-common' do let :pre_condition do 'class { "apt": }' end let :params do { package_name: 'software-properties-common', package_manage: true, } end let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '14', full: '14.04' } }, - lsbdistrelease: '14.04', - lsbdistcodename: 'trusty', - operatingsystem: 'Ubuntu', - osfamily: 'Debian', - lsbdistid: 'Ubuntu', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '14', + full: '14.04', + }, + distro: { + codename: 'trusty', + id: 'Ubuntu', + }, + }, } end let(:title) { 'ppa:needs/such.substitution/wow' } it { is_expected.to contain_package('software-properties-common') } it { is_expected.to contain_exec('add-apt-repository-ppa:needs/such.substitution/wow').that_notifies('Class[Apt::Update]').with('environment' => [], 'command' => '/usr/bin/add-apt-repository -y ppa:needs/such.substitution/wow || (rm /etc/apt/sources.list.d/needs-such_substitution-wow-trusty.list && false)', # rubocop:disable Layout/LineLength 'unless' => '/usr/bin/test -f /etc/apt/sources.list.d/needs-such_substitution-wow-trusty.list && /usr/bin/test -f /etc/apt/trusted.gpg.d/needs-such_substitution-wow.gpg', # rubocop:disable Layout/LineLength 'user' => 'root', 'logoutput' => 'on_failure') } it { is_expected.to contain_file('/etc/apt/sources.list.d/needs-such_substitution-wow-trusty.list').that_requires('Exec[add-apt-repository-ppa:needs/such.substitution/wow]').with('ensure' => 'file') } end describe 'package_manage => false' do let :pre_condition do 'class { "apt": }' end let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '14', full: '14.04' } }, - lsbdistrelease: '14.04', - lsbdistcodename: 'trusty', - operatingsystem: 'Ubuntu', - osfamily: 'Debian', - lsbdistid: 'Ubuntu', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '14', + full: '14.04', + }, + distro: { + codename: 'trusty', + id: 'Ubuntu', + }, + }, } end let :params do { package_manage: false, } end let(:title) { 'ppa:needs/such.substitution/wow' } it { is_expected.not_to contain_package('python-software-properties') } it { is_expected.to contain_exec('add-apt-repository-ppa:needs/such.substitution/wow').that_notifies('Class[Apt::Update]').with('environment' => [], 'command' => '/usr/bin/add-apt-repository -y ppa:needs/such.substitution/wow || (rm /etc/apt/sources.list.d/needs-such_substitution-wow-trusty.list && false)', # rubocop:disable Layout/LineLength 'unless' => '/usr/bin/test -f /etc/apt/sources.list.d/needs-such_substitution-wow-trusty.list && /usr/bin/test -f /etc/apt/trusted.gpg.d/needs-such_substitution-wow.gpg', # rubocop:disable Layout/LineLength 'user' => 'root', 'logoutput' => 'on_failure') } it { is_expected.to contain_file('/etc/apt/sources.list.d/needs-such_substitution-wow-trusty.list').that_requires('Exec[add-apt-repository-ppa:needs/such.substitution/wow]').with('ensure' => 'file') } end describe 'apt included, no proxy' do let :pre_condition do 'class { "apt": } apt::ppa { "ppa:user/foo2": } ' end let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '14', full: '14.04' } }, - lsbdistrelease: '14.04', - lsbdistcodename: 'trusty', - operatingsystem: 'Ubuntu', - lsbdistid: 'Ubuntu', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '14', + full: '14.04', + }, + distro: { + codename: 'trusty', + id: 'Ubuntu', + }, + }, } end let :params do { options: '', package_manage: true, require: 'Apt::Ppa[ppa:user/foo2]', } end let(:title) { 'ppa:user/foo' } it { is_expected.to compile.with_all_deps } it { is_expected.to contain_package('software-properties-common') } it { is_expected.to contain_exec('add-apt-repository-ppa:user/foo').that_notifies('Class[Apt::Update]').with(environment: [], command: '/usr/bin/add-apt-repository ppa:user/foo || (rm /etc/apt/sources.list.d/user-foo-trusty.list && false)', # rubocop:disable Layout/LineLength unless: '/usr/bin/test -f /etc/apt/sources.list.d/user-foo-trusty.list && /usr/bin/test -f /etc/apt/trusted.gpg.d/user-foo.gpg', # rubocop:disable Layout/LineLength user: 'root', logoutput: 'on_failure') } end describe 'apt included, proxy host' do let :pre_condition do 'class { "apt": proxy => { "host" => "localhost" }, }' end let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '14', full: '14.04' } }, - lsbdistrelease: '14.04', - lsbdistcodename: 'trusty', - operatingsystem: 'Ubuntu', - lsbdistid: 'Ubuntu', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '14', + full: '14.04', + }, + distro: { + codename: 'trusty', + id: 'Ubuntu', + }, + }, } end let :params do { 'options' => '', 'package_manage' => true, } end let(:title) { 'ppa:user/foo' } it { is_expected.to contain_package('software-properties-common') } it { is_expected.to contain_exec('add-apt-repository-ppa:user/foo').that_notifies('Class[Apt::Update]').with(environment: ['http_proxy=http://localhost:8080'], command: '/usr/bin/add-apt-repository ppa:user/foo || (rm /etc/apt/sources.list.d/user-foo-trusty.list && false)', # rubocop:disable Layout/LineLength unless: '/usr/bin/test -f /etc/apt/sources.list.d/user-foo-trusty.list && /usr/bin/test -f /etc/apt/trusted.gpg.d/user-foo.gpg', # rubocop:disable Layout/LineLength user: 'root', logoutput: 'on_failure') } end describe 'apt included, proxy host and port' do let :pre_condition do 'class { "apt": proxy => { "host" => "localhost", "port" => 8180 }, }' end let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '14', full: '14.04' } }, - lsbdistrelease: '14.04', - lsbdistcodename: 'trusty', - operatingsystem: 'Ubuntu', - lsbdistid: 'Ubuntu', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '14', + full: '14.04', + }, + distro: { + codename: 'trusty', + id: 'Ubuntu', + }, + }, } end let :params do { options: '', package_manage: true, } end let(:title) { 'ppa:user/foo' } it { is_expected.to contain_package('software-properties-common') } it { is_expected.to contain_exec('add-apt-repository-ppa:user/foo').that_notifies('Class[Apt::Update]').with(environment: ['http_proxy=http://localhost:8180'], command: '/usr/bin/add-apt-repository ppa:user/foo || (rm /etc/apt/sources.list.d/user-foo-trusty.list && false)', # rubocop:disable Layout/LineLength unless: '/usr/bin/test -f /etc/apt/sources.list.d/user-foo-trusty.list && /usr/bin/test -f /etc/apt/trusted.gpg.d/user-foo.gpg', # rubocop:disable Layout/LineLength user: 'root', logoutput: 'on_failure') } end describe 'apt included, proxy host and port and https' do let :pre_condition do 'class { "apt": proxy => { "host" => "localhost", "port" => 8180, "https" => true }, }' end let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '14', full: '14.04' } }, - lsbdistrelease: '14.04', - lsbdistcodename: 'trusty', - operatingsystem: 'Ubuntu', - lsbdistid: 'Ubuntu', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '14', + full: '14.04', + }, + distro: { + codename: 'trusty', + id: 'Ubuntu', + }, + }, } end let :params do { options: '', package_manage: true, } end let(:title) { 'ppa:user/foo' } it { is_expected.to contain_package('software-properties-common') } it { is_expected.to contain_exec('add-apt-repository-ppa:user/foo').that_notifies('Class[Apt::Update]').with(environment: ['http_proxy=http://localhost:8180', 'https_proxy=https://localhost:8180'], command: '/usr/bin/add-apt-repository ppa:user/foo || (rm /etc/apt/sources.list.d/user-foo-trusty.list && false)', # rubocop:disable Layout/LineLength unless: '/usr/bin/test -f /etc/apt/sources.list.d/user-foo-trusty.list && /usr/bin/test -f /etc/apt/trusted.gpg.d/user-foo.gpg', # rubocop:disable Layout/LineLength user: 'root', logoutput: 'on_failure') } end describe 'ensure absent' do let :pre_condition do 'class { "apt": }' end let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '14', full: '14.04' } }, - lsbdistrelease: '14.04', - lsbdistcodename: 'trusty', - operatingsystem: 'Ubuntu', - lsbdistid: 'Ubuntu', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '14', + full: '14.04', + }, + distro: { + codename: 'trusty', + id: 'Ubuntu', + }, + }, } end let(:title) { 'ppa:user/foo' } let :params do { ensure: 'absent', } end it { is_expected.to contain_file('/etc/apt/sources.list.d/user-foo-trusty.list').that_notifies('Class[Apt::Update]').with(ensure: 'absent') } end context 'with validation' do describe 'no release' do let :facts do { - os: { family: 'Debian', name: 'Ubuntu', release: { major: '14', full: '14.04' } }, - lsbdistrelease: '14.04', - operatingsystem: 'Ubuntu', - lsbdistid: 'Ubuntu', - osfamily: 'Debian', - lsbdistcodeanme: nil, + os: { + family: 'Debian', + name: 'Ubuntu', + release: { + major: '14', + full: '14.04', + }, + distro: { + codename: nil, + id: 'Ubuntu', + }, + }, } end let(:title) { 'ppa:user/foo' } it do - is_expected.to raise_error(Puppet::Error, %r{lsbdistcodename fact not available: release parameter required}) + is_expected.to raise_error(Puppet::Error, %r{os.distro.codename fact not available: release parameter required}) end end describe 'not ubuntu' do let :facts do { - os: { family: 'Debian', name: 'Debian', release: { major: '6', full: '6.0.7' } }, - lsbdistrelease: '6.0.7', - lsbdistcodename: 'wheezy', - operatingsystem: 'Debian', - lsbdistid: 'debian', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '6', + full: '6.0.7', + }, + distro: { + codename: 'wheezy', + id: 'Debian', + }, + }, } end let(:title) { 'ppa:user/foo' } it do is_expected.to raise_error(Puppet::Error, %r{not currently supported on Debian}) end end end end diff --git a/spec/defines/setting_spec.rb b/spec/defines/setting_spec.rb index 09cb922..a2fef2e 100644 --- a/spec/defines/setting_spec.rb +++ b/spec/defines/setting_spec.rb @@ -1,139 +1,153 @@ # frozen_string_literal: true require 'spec_helper' describe 'apt::setting' do let(:pre_condition) { 'class { "apt": }' } let :facts do { - os: { distro: { codename: 'jessie' }, family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistrelease: '8.0', - lsbdistcodename: 'jessie', - operatingsystem: 'Debian', - osfamily: 'Debian', - lsbdistid: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, } end let(:title) { 'conf-teddybear' } let(:default_params) { { content: 'di' } } describe 'when using the defaults' do context 'without source or content' do it do is_expected.to raise_error(Puppet::Error, %r{needs either of }) end end context 'with title=conf-teddybear ' do let(:params) { default_params } it { is_expected.to contain_file('/etc/apt/apt.conf.d/50teddybear').that_notifies('Class[Apt::Update]') } end context 'with title=pref-teddybear' do let(:title) { 'pref-teddybear' } let(:params) { default_params } it { is_expected.to contain_file('/etc/apt/preferences.d/teddybear.pref').that_notifies('Class[Apt::Update]') } end context 'with title=list-teddybear' do let(:title) { 'list-teddybear' } let(:params) { default_params } it { is_expected.to contain_file('/etc/apt/sources.list.d/teddybear.list').that_notifies('Class[Apt::Update]') } end context 'with source' do let(:params) { { source: 'puppet:///la/die/dah' } } it { is_expected.to contain_file('/etc/apt/apt.conf.d/50teddybear').that_notifies('Class[Apt::Update]').with(ensure: 'file', owner: 'root', group: 'root', source: params[:source].to_s) } end context 'with content' do let(:params) { default_params } it { is_expected.to contain_file('/etc/apt/apt.conf.d/50teddybear').that_notifies('Class[Apt::Update]').with(ensure: 'file', owner: 'root', group: 'root', content: params[:content].to_s) } end end describe 'settings requiring settings, MODULES-769' do let(:pre_condition) do 'class { "apt": } apt::setting { "list-teddybear": content => "foo" } ' end let(:facts) do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - osfamily: 'Debian', - lsbdistcodename: 'jessie', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, } end let(:title) { 'conf-teddybear' } let(:default_params) { { content: 'di' } } let(:params) { default_params.merge(require: 'Apt::Setting[list-teddybear]') } it { is_expected.to compile.with_all_deps } end describe 'when trying to pull one over' do context 'with source and content' do let(:params) { default_params.merge(source: 'la') } it do is_expected.to raise_error(Puppet::Error, %r{cannot have both }) end end context 'with title=ext-teddybear' do let(:title) { 'ext-teddybear' } let(:params) { default_params } it do is_expected.to raise_error(Puppet::Error, %r{must start with either}) end end context 'with ensure=banana' do let(:params) { default_params.merge(ensure: 'banana') } it do is_expected.to raise_error(Puppet::Error, %r{Enum\['absent', 'file', 'present'\]}) end end context 'with priority=1.2' do let(:params) { default_params.merge(priority: 1.2) } it { is_expected.to compile.and_raise_error(%r{expects a value of type}) } end end describe 'with priority=100' do let(:params) { default_params.merge(priority: 100) } it { is_expected.to contain_file('/etc/apt/apt.conf.d/100teddybear').that_notifies('Class[Apt::Update]') } end describe 'with ensure=absent' do let(:params) { default_params.merge(ensure: 'absent') } it { is_expected.to contain_file('/etc/apt/apt.conf.d/50teddybear').that_notifies('Class[Apt::Update]').with(ensure: 'absent') } end end diff --git a/spec/defines/source_compat_spec.rb b/spec/defines/source_compat_spec.rb index 0c42ef1..c35b630 100644 --- a/spec/defines/source_compat_spec.rb +++ b/spec/defines/source_compat_spec.rb @@ -1,117 +1,134 @@ # frozen_string_literal: true require 'spec_helper' describe 'apt::source', type: :define do GPG_KEY_ID = '6F6B15509CF8E59E6E469F327F438280EF8D349F' let :title do 'my_source' end let :facts do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - lsbdistcodename: 'jessie', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, } end context 'with mostly defaults' do let :params do { 'include' => { 'deb' => false, 'src' => true }, 'location' => 'http://debian.mirror.iweb.ca/debian/', } end it { is_expected.to contain_apt__setting('list-my_source').with_content(%r{# my_source\ndeb-src http://debian.mirror.iweb.ca/debian/ jessie main\n}) } end context 'with no defaults' do let :params do { 'comment' => 'foo', 'location' => 'http://debian.mirror.iweb.ca/debian/', 'release' => 'sid', 'repos' => 'testing', 'include' => { 'src' => false }, 'key' => GPG_KEY_ID, 'pin' => '10', 'architecture' => 'x86_64', 'allow_unsigned' => true, } end it { is_expected.to contain_apt__setting('list-my_source').with_content(%r{# foo\ndeb \[arch=x86_64 trusted=yes\] http://debian.mirror.iweb.ca/debian/ sid testing\n}) .without_content(%r{deb-src}) } it { is_expected.to contain_apt__pin('my_source').that_comes_before('Apt::Setting[list-my_source]').with('ensure' => 'present', 'priority' => '10', 'origin' => 'debian.mirror.iweb.ca') } it { is_expected.to contain_apt__key("Add key: #{GPG_KEY_ID} from Apt::Source my_source").that_comes_before('Apt::Setting[list-my_source]').with('ensure' => 'present', 'id' => GPG_KEY_ID) } end context 'when allow_unsigned true' do let :params do { 'include' => { 'src' => false }, 'location' => 'http://debian.mirror.iweb.ca/debian/', 'allow_unsigned' => true, } end it { is_expected.to contain_apt__setting('list-my_source').with_content(%r{# my_source\ndeb \[trusted=yes\] http://debian.mirror.iweb.ca/debian/ jessie main\n}) } end context 'with architecture equals x86_64' do let :params do { 'location' => 'http://debian.mirror.iweb.ca/debian/', 'architecture' => 'x86_64', } end it { is_expected.to contain_apt__setting('list-my_source').with_content(%r{# my_source\ndeb \[arch=x86_64\] http://debian.mirror.iweb.ca/debian/ jessie main\n}) } end context 'with ensure => absent' do let :params do { 'ensure' => 'absent', } end it { is_expected.to contain_apt__setting('list-my_source').with('ensure' => 'absent') } end describe 'validation' do context 'with no release' do let :facts do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + id: 'Debian', + }, + }, } end it do - is_expected.to raise_error(Puppet::Error, %r{lsbdistcodename fact not available: release parameter required}) + is_expected.to raise_error(Puppet::Error, %r{os.distro.codename fact not available: release parameter required}) end end end end diff --git a/spec/defines/source_spec.rb b/spec/defines/source_spec.rb index 0adcaad..94446bf 100644 --- a/spec/defines/source_spec.rb +++ b/spec/defines/source_spec.rb @@ -1,364 +1,404 @@ # frozen_string_literal: true require 'spec_helper' describe 'apt::source' do GPG_KEY_ID = '6F6B15509CF8E59E6E469F327F438280EF8D349F' let :pre_condition do 'class { "apt": }' end let :title do 'my_source' end let :facts do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - lsbdistcodename: 'jessie', - operatingsystem: 'Debian', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, } end context 'with defaults' do context 'without location' do it do is_expected.to raise_error(Puppet::Error, %r{source entry without specifying a location}) end end context 'with location' do let(:params) { { location: 'hello.there' } } it { is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').without_content(%r{# my_source\ndeb-src hello.there wheezy main\n}) is_expected.not_to contain_package('apt-transport-https') } end end describe 'no defaults' do context 'with complex pin' do let :params do { location: 'hello.there', pin: { 'release' => 'wishwash', 'explanation' => 'wishwash', 'priority' => 1001 }, } end it { is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{hello.there jessie main\n}) } it { is_expected.to contain_file('/etc/apt/sources.list.d/my_source.list').that_notifies('Class[Apt::Update]') } it { is_expected.to contain_apt__pin('my_source').that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'present', priority: 1001, explanation: 'wishwash', release: 'wishwash') } end context 'with simple key' do let :params do { comment: 'foo', location: 'http://debian.mirror.iweb.ca/debian/', release: 'sid', repos: 'testing', key: GPG_KEY_ID, pin: '10', architecture: 'x86_64', allow_unsigned: true, } end it { is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# foo\ndeb \[arch=x86_64 trusted=yes\] http://debian.mirror.iweb.ca/debian/ sid testing\n}) .without_content(%r{deb-src}) } it { is_expected.to contain_apt__pin('my_source').that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'present', priority: '10', origin: 'debian.mirror.iweb.ca') } it { is_expected.to contain_apt__key("Add key: #{GPG_KEY_ID} from Apt::Source my_source").that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'present', id: GPG_KEY_ID) } end context 'with complex key' do let :params do { comment: 'foo', location: 'http://debian.mirror.iweb.ca/debian/', release: 'sid', repos: 'testing', key: { 'ensure' => 'refreshed', 'id' => GPG_KEY_ID, 'server' => 'pgp.mit.edu', 'content' => 'GPG key content', 'source' => 'http://apt.puppetlabs.com/pubkey.gpg' }, pin: '10', architecture: 'x86_64', allow_unsigned: true, } end it { is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# foo\ndeb \[arch=x86_64 trusted=yes\] http://debian.mirror.iweb.ca/debian/ sid testing\n}) .without_content(%r{deb-src}) } it { is_expected.to contain_apt__pin('my_source').that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'present', priority: '10', origin: 'debian.mirror.iweb.ca') } it { is_expected.to contain_apt__key("Add key: #{GPG_KEY_ID} from Apt::Source my_source").that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'refreshed', id: GPG_KEY_ID, server: 'pgp.mit.edu', content: 'GPG key content', source: 'http://apt.puppetlabs.com/pubkey.gpg') } end end context 'with allow_unsigned true' do let :params do { location: 'hello.there', allow_unsigned: true, } end it { is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb \[trusted=yes\] hello.there jessie main\n}) } end context 'with a https location, install apt-transport-https' do let :params do { location: 'HTTPS://foo.bar', allow_unsigned: false, } end it { is_expected.to contain_package('apt-transport-https') } end context 'with a https location and custom release, install apt-transport-https' do let :facts do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - lsbdistid: 'Debian', - lsbdistcodename: 'jessie', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + codename: 'jessie', + id: 'Debian', + }, + }, puppetversion: Puppet.version, } end let :params do { location: 'HTTPS://foo.bar', allow_unsigned: false, release: 'customrelease', } end it { is_expected.to contain_package('apt-transport-https') } end context 'with a https location, do not install apt-transport-https on oses not in list eg buster' do let :facts do { - os: { family: 'Debian', name: 'Debian', release: { major: '10', full: '10.0' } }, - lsbdistid: 'Debian', - lsbdistcodename: 'buster', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '10', + full: '10.0', + }, + distro: { + codename: 'buster', + id: 'Debian', + }, + }, } end let :params do { location: 'https://foo.bar', allow_unsigned: false, } end it { is_expected.not_to contain_package('apt-transport-https') } end context 'with architecture equals x86_64' do let :facts do { - os: { family: 'Debian', name: 'Debian', release: { major: '7', full: '7.0' } }, - lsbdistid: 'Debian', - lsbdistcodename: 'wheezy', - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '7', + full: '7.0', + }, + distro: { + codename: 'wheezy', + id: 'Debian', + }, + }, } end let :params do { location: 'hello.there', include: { 'deb' => false, 'src' => true }, architecture: 'x86_64', } end it { is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb-src \[arch=x86_64\] hello.there wheezy main\n}) } end context 'with architecture fact and unset architecture parameter' do let :facts do super().merge(architecture: 'amd64') end let :params do { location: 'hello.there', include: { 'deb' => false, 'src' => true }, } end it { is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb-src hello.there jessie main\n}) } end context 'with include_src => true' do let :params do { location: 'hello.there', include: { 'src' => true }, } end it { is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb hello.there jessie main\ndeb-src hello.there jessie main\n}) } end context 'with include deb => false' do let :params do { include: { 'deb' => false }, location: 'hello.there', } end it { is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').without_content(%r{deb-src hello.there wheezy main\n}) } it { is_expected.to contain_apt__setting('list-my_source').without_content(%r{deb hello.there wheezy main\n}) } end context 'with include src => true and include deb => false' do let :params do { include: { 'deb' => false, 'src' => true }, location: 'hello.there', } end it { is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{deb-src hello.there jessie main\n}) } it { is_expected.to contain_apt__setting('list-my_source').without_content(%r{deb hello.there jessie main\n}) } end context 'with ensure => absent' do let :params do { ensure: 'absent', } end it { is_expected.to contain_apt__setting('list-my_source').with(ensure: 'absent') } end describe 'validation' do context 'with no release' do let :facts do { - os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, - osfamily: 'Debian', + os: { + family: 'Debian', + name: 'Debian', + release: { + major: '8', + full: '8.0', + }, + distro: { + id: 'Debian', + }, + }, } end let(:params) { { location: 'hello.there' } } it do - is_expected.to raise_error(Puppet::Error, %r{lsbdistcodename fact not available: release parameter required}) + is_expected.to raise_error(Puppet::Error, %r{os.distro.codename fact not available: release parameter required}) end end context 'with release is empty string' do let(:params) { { location: 'hello.there', release: '' } } it { is_expected.to contain_apt__setting('list-my_source').with_content(%r{hello\.there main}) } end context 'with invalid pin' do let :params do { location: 'hello.there', pin: true, } end it do is_expected.to raise_error(Puppet::Error, %r{expects a value}) end end context 'with notify_update = undef (default)' do let :params do { location: 'hello.there', } end it { is_expected.to contain_apt__setting("list-#{title}").with_notify_update(true) } end context 'with notify_update = true' do let :params do { location: 'hello.there', notify_update: true, } end it { is_expected.to contain_apt__setting("list-#{title}").with_notify_update(true) } end context 'with notify_update = false' do let :params do { location: 'hello.there', notify_update: false, } end it { is_expected.to contain_apt__setting("list-#{title}").with_notify_update(false) } end end end diff --git a/spec/spec_helper_acceptance_local.rb b/spec/spec_helper_acceptance_local.rb index d5339ae..cc3fc3f 100644 --- a/spec/spec_helper_acceptance_local.rb +++ b/spec/spec_helper_acceptance_local.rb @@ -1,41 +1,42 @@ # frozen_string_literal: true UNSUPPORTED_PLATFORMS = ['RedHat', 'Suse', 'windows', 'AIX', 'Solaris'].freeze MAX_RETRY_COUNT = 5 RETRY_WAIT = 3 ERROR_MATCHER = %r{(no valid OpenPGP data found|keyserver timed out|keyserver receive failed)}.freeze -# this is needed for puppet facts / apply +# lsb-release is needed for facter 3 (puppet 6) to resolve os.distro facts. Not needed with facter +# 4 (puppet 7). lsb_package = <<-MANIFEST package { 'lsb-release': ensure => installed, } MANIFEST include PuppetLitmus apply_manifest(lsb_package) # This method allows a block to be passed in and if an exception is raised # that matches the 'error_matcher' matcher, the block will wait a set number # of seconds before retrying. # Params: # - max_retry_count - Max number of retries # - retry_wait_interval_secs - Number of seconds to wait before retry # - error_matcher - Matcher which the exception raised must match to allow retry # Example Usage: # retry_on_error_matching(3, 5, /OpenGPG Error/) do # apply_manifest(pp, :catch_failures => true) # end def retry_on_error_matching(max_retry_count = MAX_RETRY_COUNT, retry_wait_interval_secs = RETRY_WAIT, error_matcher = ERROR_MATCHER) try = 0 begin puts "retry_on_error_matching: try #{try}" unless try.zero? try += 1 yield rescue StandardError => e raise('Attempted this %{value0} times. Raising %{value1}' % { value0: max_retry_count, value1: e }) unless try < max_retry_count && (error_matcher.nil? || e.message =~ error_matcher) sleep retry_wait_interval_secs retry end end