summaryrefslogtreecommitdiff
path: root/code/environments/production/modules/apt/manifests
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2018-09-16 22:55:58 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2018-09-16 22:55:58 +0200
commit9513b93a992470e21e387db1451fa4fd21ffc5d6 (patch)
tree24b584e9a66ce00f053748ab938eecc8d91110ab /code/environments/production/modules/apt/manifests
parentb9c90f087cb54a0b8be222dbdcd88c8a73ef4f57 (diff)
downloadpuppet.DEV-9513b93a992470e21e387db1451fa4fd21ffc5d6.tar.gz
puppet.DEV-9513b93a992470e21e387db1451fa4fd21ffc5d6.tar.bz2
puppet.DEV-9513b93a992470e21e387db1451fa4fd21ffc5d6.zip
modules/apt: Ship puppetlabs-apt module v4.5.1.
Diffstat (limited to 'code/environments/production/modules/apt/manifests')
-rw-r--r--code/environments/production/modules/apt/manifests/backports.pp60
-rw-r--r--code/environments/production/modules/apt/manifests/conf.pp22
-rw-r--r--code/environments/production/modules/apt/manifests/init.pp200
-rw-r--r--code/environments/production/modules/apt/manifests/key.pp81
-rw-r--r--code/environments/production/modules/apt/manifests/params.pp126
-rw-r--r--code/environments/production/modules/apt/manifests/pin.pp96
-rw-r--r--code/environments/production/modules/apt/manifests/ppa.pp68
-rw-r--r--code/environments/production/modules/apt/manifests/setting.pp57
-rw-r--r--code/environments/production/modules/apt/manifests/source.pp109
-rw-r--r--code/environments/production/modules/apt/manifests/update.pp65
10 files changed, 884 insertions, 0 deletions
diff --git a/code/environments/production/modules/apt/manifests/backports.pp b/code/environments/production/modules/apt/manifests/backports.pp
new file mode 100644
index 0000000..6a7e87c
--- /dev/null
+++ b/code/environments/production/modules/apt/manifests/backports.pp
@@ -0,0 +1,60 @@
+# Defining backports for the apt class
+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,
+){
+ if $location {
+ $_location = $location
+ }
+ if $release {
+ $_release = $release
+ }
+ if $repos {
+ $_repos = $repos
+ }
+ if $key {
+ $_key = $key
+ }
+ if ($facts['lsbdistid'] == 'Debian' or $facts['lsbdistid'] == 'Ubuntu') {
+ unless $location {
+ $_location = $::apt::backports['location']
+ }
+ unless $release {
+ $_release = "${facts['lsbdistcodename']}-backports"
+ }
+ unless $repos {
+ $_repos = $::apt::backports['repos']
+ }
+ unless $key {
+ $_key = $::apt::backports['key']
+ }
+ } else {
+ unless $location and $release and $repos and $key {
+ fail('If not on Debian or Ubuntu, you must explicitly pass location, release, repos, and 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('pin must be either a string, number or hash')
+ }
+
+ apt::source { 'backports':
+ location => $_location,
+ release => $_release,
+ repos => $_repos,
+ key => $_key,
+ pin => $_pin,
+ }
+}
diff --git a/code/environments/production/modules/apt/manifests/conf.pp b/code/environments/production/modules/apt/manifests/conf.pp
new file mode 100644
index 0000000..b791f85
--- /dev/null
+++ b/code/environments/production/modules/apt/manifests/conf.pp
@@ -0,0 +1,22 @@
+# Defining apt config
+define apt::conf (
+ Optional[String] $content = undef,
+ Enum['present', 'absent'] $ensure = present,
+ Variant[String, Integer] $priority = 50,
+ Optional[Boolean] $notify_update = undef,
+) {
+
+ unless $ensure == 'absent' {
+ unless $content {
+ fail('Need to pass in content parameter')
+ }
+ }
+
+ $confheadertmp = epp('apt/_conf_header.epp')
+ apt::setting { "conf-${name}":
+ ensure => $ensure,
+ priority => $priority,
+ content => "${confheadertmp}${content}",
+ notify_update => $notify_update,
+ }
+}
diff --git a/code/environments/production/modules/apt/manifests/init.pp b/code/environments/production/modules/apt/manifests/init.pp
new file mode 100644
index 0000000..aa61986
--- /dev/null
+++ b/code/environments/production/modules/apt/manifests/init.pp
@@ -0,0 +1,200 @@
+# == Class: apt
+#
+# Manage APT (Advanced Packaging Tool)
+#
+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] $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,
+ Hash $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,
+ 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,
+ Hash $config_files = $apt::params::config_files,
+ Hash $source_key_defaults = $apt::params::source_key_defaults
+) inherits apt::params {
+
+ if $facts['osfamily'] != 'Debian' {
+ fail('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'])
+ }
+
+ $_purge = merge($::apt::purge_defaults, $purge)
+
+ if $proxy['ensure'] {
+ assert_type(Enum['file', 'present', 'absent'], $proxy['ensure'])
+ }
+ if $proxy['host'] {
+ assert_type(String, $proxy['host'])
+ }
+ if $proxy['port'] {
+ assert_type(Integer, $proxy['port'])
+ }
+ if $proxy['https']{
+ assert_type(Boolean, $proxy['https'])
+ }
+ if $proxy['direct']{
+ assert_type(Boolean, $proxy['direct'])
+ }
+
+ $_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}",
+ }
+ }
+
+ $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 => file,
+ path => $::apt::sources_list,
+ owner => root,
+ group => root,
+ mode => '0644',
+ content => $sources_list_content,
+ notify => Class['apt::update'],
+ }
+
+ file { 'sources.list.d':
+ ensure => directory,
+ path => $::apt::sources_list_d,
+ owner => root,
+ group => root,
+ mode => '0644',
+ 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,
+ mode => '0644',
+ notify => Class['apt::update'],
+ }
+
+ file { 'preferences.d':
+ ensure => directory,
+ path => $::apt::preferences_d,
+ owner => root,
+ group => root,
+ mode => '0644',
+ purge => $_purge['preferences.d'],
+ recurse => $_purge['preferences.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)
+ }
+
+ # manage pins if present
+ if $pins {
+ create_resources('apt::pin', $pins)
+ }
+
+ # required for adding GPG keys on Debian 9 (and derivatives)
+ case $facts['os']['name'] {
+ 'Debian': {
+ if versioncmp($facts['os']['release']['major'], '9') >= 0 {
+ ensure_packages(['dirmngr'])
+ }
+ }
+ 'Ubuntu': {
+ if versioncmp($facts['os']['release']['full'], '17.04') >= 0 {
+ ensure_packages(['dirmngr'])
+ }
+ }
+ default: { }
+ }
+}
diff --git a/code/environments/production/modules/apt/manifests/key.pp b/code/environments/production/modules/apt/manifests/key.pp
new file mode 100644
index 0000000..1933b3f
--- /dev/null
+++ b/code/environments/production/modules/apt/manifests/key.pp
@@ -0,0 +1,81 @@
+# == Define: apt::key
+define apt::key (
+ String $id = $title,
+ Enum['present', 'absent'] $ensure = present,
+ Optional[String] $content = undef,
+ Optional[String] $source = undef,
+ String $server = $::apt::keyserver,
+ Optional[String] $options = undef,
+ ) {
+
+ assert_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/,
+ ], $id)
+
+ if $source {
+ assert_type(Pattern[/\Ahttps?:\/\//, /\Aftp:\/\//, /\A\/\w+/], $source)
+ }
+
+ if $server {
+ assert_type(Pattern[/\A((hkp|http|https):\/\/)?([a-z\d])([a-z\d-]{0,61}\.)+[a-z\d]+(:\d{2,5})?$/], $server)
+ }
+
+ case $ensure {
+ present: {
+ if defined(Anchor["apt_key ${id} absent"]){
+ fail("key with id ${id} already ensured as absent")
+ }
+
+ if !defined(Anchor["apt_key ${id} present"]) {
+ apt_key { $title:
+ ensure => $ensure,
+ id => $id,
+ source => $source,
+ content => $content,
+ server => $server,
+ options => $options,
+ } -> anchor { "apt_key ${id} present": }
+
+ case $facts['os']['name'] {
+ 'Debian': {
+ if versioncmp($facts['os']['release']['major'], '9') >= 0 {
+ ensure_packages(['dirmngr'])
+ Apt::Key<| title == $title |>
+ }
+ }
+ 'Ubuntu': {
+ if versioncmp($facts['os']['release']['full'], '17.04') >= 0 {
+ ensure_packages(['dirmngr'])
+ Apt::Key<| title == $title |>
+ }
+ }
+ default: { }
+ }
+ }
+ }
+
+ absent: {
+ if defined(Anchor["apt_key ${id} present"]){
+ fail("key with id ${id} already ensured as present")
+ }
+
+ if !defined(Anchor["apt_key ${id} absent"]){
+ apt_key { $title:
+ ensure => $ensure,
+ id => $id,
+ source => $source,
+ content => $content,
+ server => $server,
+ options => $options,
+ } -> anchor { "apt_key ${id} absent": }
+ }
+ }
+
+ default: {
+ fail "Invalid 'ensure' value '${ensure}' for apt::key"
+ }
+ }
+}
diff --git a/code/environments/production/modules/apt/manifests/params.pp b/code/environments/production/modules/apt/manifests/params.pp
new file mode 100644
index 0000000..c11deba
--- /dev/null
+++ b/code/environments/production/modules/apt/manifests/params.pp
@@ -0,0 +1,126 @@
+# Setting params for the module
+class apt::params {
+
+ if $::osfamily != 'Debian' {
+ fail('This module only works on Debian or derivatives like Ubuntu')
+ }
+
+ $root = '/etc/apt'
+ $provider = '/usr/bin/apt-get'
+ $sources_list = "${root}/sources.list"
+ $sources_list_d = "${root}/sources.list.d"
+ $conf_d = "${root}/apt.conf.d"
+ $preferences = "${root}/preferences"
+ $preferences_d = "${root}/preferences.d"
+ $keyserver = 'keyserver.ubuntu.com'
+ $confs = {}
+ $update = {}
+ $purge = {}
+ $proxy = {}
+ $sources = {}
+ $keys = {}
+ $ppas = {}
+ $pins = {}
+ $settings = {}
+
+ $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,
+ 'direct' => false,
+ }
+
+ $purge_defaults = {
+ 'sources.list' => false,
+ 'sources.list.d' => false,
+ 'preferences' => false,
+ 'preferences.d' => false,
+ }
+
+ $source_key_defaults = {
+ 'server' => $keyserver,
+ 'options' => undef,
+ 'content' => undef,
+ 'source' => undef,
+ }
+
+ $include_defaults = {
+ 'deb' => true,
+ 'src' => false,
+ }
+
+ case $facts['os']['name']{
+ 'Debian': {
+ case $facts['os']['release']['full'] {
+ default: {
+ $backports = {
+ 'location' => 'http://deb.debian.org/debian',
+ 'key' => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553',
+ 'repos' => 'main contrib non-free',
+ }
+ }
+ }
+
+ $ppa_options = undef
+ $ppa_package = undef
+
+ }
+ 'Ubuntu': {
+ $backports = {
+ 'location' => 'http://archive.ubuntu.com/ubuntu',
+ 'key' => '630239CC130E1A7FD81A27B140976EAF437D05B5',
+ 'repos' => 'main universe multiverse restricted',
+ }
+
+ case $facts['os']['release']['full'] {
+ '10.04': {
+ $ppa_options = undef
+ $ppa_package = 'python-software-properties'
+ }
+ '12.04': {
+ $ppa_options = '-y'
+ $ppa_package = 'python-software-properties'
+ }
+ '14.04', '14.10', '15.04', '15.10', '16.04': {
+ $ppa_options = '-y'
+ $ppa_package = 'software-properties-common'
+ }
+ default: {
+ $ppa_options = '-y'
+ $ppa_package = 'python-software-properties'
+ }
+ }
+ }
+ undef: {
+ fail('Unable to determine value for fact os["name"]')
+ }
+ default: {
+ $ppa_options = undef
+ $ppa_package = undef
+ $backports = undef
+ }
+ }
+}
diff --git a/code/environments/production/modules/apt/manifests/pin.pp b/code/environments/production/modules/apt/manifests/pin.pp
new file mode 100644
index 0000000..831d75f
--- /dev/null
+++ b/code/environments/production/modules/apt/manifests/pin.pp
@@ -0,0 +1,96 @@
+# pin.pp
+# pin a release in apt, useful for unstable repositories
+
+define apt::pin(
+ Optional[Enum['file', 'present', 'absent']] $ensure = present,
+ Optional[String] $explanation = undef,
+ Variant[Integer] $order = 50,
+ Variant[String, Array] $packages = '*',
+ Variant[Numeric, String] $priority = 0,
+ Optional[String] $release = '', # a=
+ Optional[String] $origin = '',
+ Optional[String] $version = '',
+ Optional[String] $codename = '', # n=
+ Optional[String] $release_version = '', # v=
+ Optional[String] $component = '', # c=
+ Optional[String] $originator = '', # o=
+ Optional[String] $label = '', # l=
+) {
+
+ if $explanation {
+ $_explanation = $explanation
+ } else {
+ if defined('$caller_module_name') { # strict vars check
+ $_explanation = "${caller_module_name}: ${name}"
+ } else {
+ $_explanation = ": ${name}"
+ }
+ }
+
+ $pin_release_array = [
+ $release,
+ $codename,
+ $release_version,
+ $component,
+ $originator,
+ $label,
+ ]
+ $pin_release = join($pin_release_array, '')
+
+ # Read the manpage 'apt_preferences(5)', especially the chapter
+ # 'The Effect of APT Preferences' to understand the following logic
+ # and the difference between specific and general form
+ if $packages =~ Array {
+ $packages_string = join($packages, ' ')
+ } else {
+ $packages_string = $packages
+ }
+
+ if $packages_string != '*' { # specific form
+ if ( $pin_release != '' and ( $origin != '' or $version != '' )) or
+ ( $version != '' and ( $pin_release != '' or $origin != '' )) {
+ fail('parameters release, origin, and version are mutually exclusive')
+ }
+ } else { # general form
+ if $version != '' {
+ fail('parameter version cannot be used in general form')
+ }
+ if ( $pin_release != '' and $origin != '' ) {
+ fail('parameters release and origin are mutually exclusive')
+ }
+ }
+
+ # According to man 5 apt_preferences:
+ # The files have either no or "pref" as filename extension
+ # and only contain alphanumeric, hyphen (-), underscore (_) and period
+ # (.) characters. Otherwise APT will print a notice that it has ignored a
+ # file, unless that file matches a pattern in the
+ # Dir::Ignore-Files-Silently configuration list - in which case it will
+ # be silently ignored.
+ $file_name = regsubst($title, '[^0-9a-z\-_\.]', '_', 'IG')
+
+ $headertmp = epp('apt/_header.epp')
+
+ $pinpreftmp = epp('apt/pin.pref.epp', {
+ 'name' => $name,
+ 'pin_release' => $pin_release,
+ 'release' => $release,
+ 'codename' => $codename,
+ 'release_version' => $release_version,
+ 'component' => $component,
+ 'originator' => $originator,
+ 'label' => $label,
+ 'version' => $version,
+ 'origin' => $origin,
+ 'explanation' => $_explanation,
+ 'packages_string' => $packages_string,
+ 'priority' => $priority,
+ })
+
+ apt::setting { "pref-${file_name}":
+ ensure => $ensure,
+ priority => $order,
+ content => "${headertmp}${pinpreftmp}",
+ notify_update => false,
+ }
+}
diff --git a/code/environments/production/modules/apt/manifests/ppa.pp b/code/environments/production/modules/apt/manifests/ppa.pp
new file mode 100644
index 0000000..a67e1a1
--- /dev/null
+++ b/code/environments/production/modules/apt/manifests/ppa.pp
@@ -0,0 +1,68 @@
+# ppa.pp
+define apt::ppa(
+ String $ensure = 'present',
+ Optional[String] $options = $::apt::ppa_options,
+ Optional[String] $release = $facts['lsbdistcodename'],
+ Optional[String] $package_name = $::apt::ppa_package,
+ Boolean $package_manage = false,
+) {
+ unless $release {
+ fail('lsbdistcodename fact not available: release parameter required')
+ }
+
+ if $facts['lsbdistid'] == 'Debian' {
+ fail('apt::ppa is not currently supported on Debian.')
+ }
+
+ if versioncmp($facts['lsbdistrelease'], '15.10') >= 0 {
+ $distid = downcase($facts['lsbdistid'])
+ $filename = regsubst($name, '^ppa:([^/]+)/(.+)$', "\\1-${distid}-\\2-${release}")
+ } else {
+ $filename = regsubst($name, '^ppa:([^/]+)/(.+)$', "\\1-\\2-${release}")
+ }
+
+ $filename_no_slashes = regsubst($filename, '/', '-', 'G')
+ $filename_no_specialchars = regsubst($filename_no_slashes, '[\.\+]', '_', 'G')
+ $sources_list_d_filename = "${filename_no_specialchars}.list"
+
+ 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}",
+ unless => "/usr/bin/test -f ${::apt::sources_list_d}/${sources_list_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/code/environments/production/modules/apt/manifests/setting.pp b/code/environments/production/modules/apt/manifests/setting.pp
new file mode 100644
index 0000000..a7b11c4
--- /dev/null
+++ b/code/environments/production/modules/apt/manifests/setting.pp
@@ -0,0 +1,57 @@
+# Defining apt settings
+define apt::setting (
+ Variant[String, Integer, Array] $priority = 50,
+ Optional[Enum['file', 'present', 'absent']] $ensure = file,
+ Optional[String] $source = undef,
+ Optional[String] $content = undef,
+ Boolean $notify_update = true,
+) {
+
+ if $content and $source {
+ fail('apt::setting cannot have both content and source')
+ }
+
+ if !$content and !$source {
+ fail('apt::setting needs either of content or source')
+ }
+
+ $title_array = split($title, '-')
+ $setting_type = $title_array[0]
+ $base_name = join(delete_at($title_array, 0), '-')
+
+ assert_type(Pattern[/\Aconf\z/, /\Apref\z/, /\Alist\z/], $setting_type) |$a, $b| {
+ fail("apt::setting resource name/title must start with either 'conf-', 'pref-' or 'list-'")
+ }
+
+ if $priority !~ Integer {
+ # need this to allow zero-padded priority.
+ assert_type(Pattern[/^\d+$/], $priority) |$a, $b| {
+ fail('apt::setting priority must be an integer or a zero-padded integer')
+ }
+ }
+
+ if ($setting_type == 'list') or ($setting_type == 'pref') {
+ $_priority = ''
+ } else {
+ $_priority = $priority
+ }
+
+ $_path = $::apt::config_files[$setting_type]['path']
+ $_ext = $::apt::config_files[$setting_type]['ext']
+
+ if $notify_update {
+ $_notify = Class['apt::update']
+ } else {
+ $_notify = undef
+ }
+
+ file { "${_path}/${_priority}${base_name}${_ext}":
+ ensure => $ensure,
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ content => $content,
+ source => $source,
+ notify => $_notify,
+ }
+}
diff --git a/code/environments/production/modules/apt/manifests/source.pp b/code/environments/production/modules/apt/manifests/source.pp
new file mode 100644
index 0000000..54295b5
--- /dev/null
+++ b/code/environments/production/modules/apt/manifests/source.pp
@@ -0,0 +1,109 @@
+# source.pp
+# add an apt source
+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,
+) {
+
+ # This is needed for compat with 1.8.x
+ include ::apt
+
+ $_before = Apt::Setting["list-${title}"]
+
+ if !$release {
+ if $facts['lsbdistcodename'] {
+ $_release = $facts['lsbdistcodename']
+ } else {
+ fail('lsbdistcodename fact not available: release parameter required')
+ }
+ } else {
+ $_release = $release
+ }
+
+ # Some releases do not support https transport with default installation
+ $_transport_https_releases = [ 'wheezy', 'jessie', 'stretch', 'trusty', 'xenial' ]
+
+ if $ensure == 'present' {
+ if ! $location {
+ fail('cannot create a source entry without specifying a location')
+ } elsif $_release in $_transport_https_releases {
+ $method = split($location, '[:\/]+')[0]
+ if $method == 'https' {
+ ensure_packages('apt-transport-https')
+ }
+ }
+ }
+
+ $includes = merge($::apt::include_defaults, $include)
+
+ if $key {
+ if $key =~ Hash {
+ unless $key['id'] {
+ fail('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('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 {
+ apt::key { "Add key: ${$_key['id']} from Apt::Source ${title}":
+ ensure => present,
+ id => $_key['id'],
+ server => $_key['server'],
+ content => $_key['content'],
+ source => $_key['source'],
+ options => $_key['options'],
+ before => $_before,
+ }
+ }
+ }
+}
diff --git a/code/environments/production/modules/apt/manifests/update.pp b/code/environments/production/modules/apt/manifests/update.pp
new file mode 100644
index 0000000..00e0600
--- /dev/null
+++ b/code/environments/production/modules/apt/manifests/update.pp
@@ -0,0 +1,65 @@
+# Defining apt update
+class apt::update {
+ assert_private()
+
+ #TODO: to catch if $::apt_update_last_success has the value of -1 here. If we
+ #opt to do this, a info/warn would likely be all you'd need likely to happen
+ #on the first run, but if it's not run in awhile something is likely borked
+ #with apt and we'd want to know about it.
+
+ case $::apt::_update['frequency'] {
+ 'always': {
+ $_kick_apt = true
+ }
+ 'daily': {
+ #compare current date with the apt_update_last_success fact to determine
+ #if we should kick apt_update.
+ $daily_threshold = (strftime('%s') - 86400)
+ if $::apt_update_last_success {
+ if $::apt_update_last_success + 0 < $daily_threshold {
+ $_kick_apt = true
+ } else {
+ $_kick_apt = false
+ }
+ } else {
+ #if apt-get update has not successfully run, we should kick apt_update
+ $_kick_apt = true
+ }
+ }
+ 'weekly':{
+ #compare current date with the apt_update_last_success fact to determine
+ #if we should kick apt_update.
+ $weekly_threshold = (strftime('%s') - 604800)
+ if $::apt_update_last_success {
+ if ( $::apt_update_last_success + 0 < $weekly_threshold ) {
+ $_kick_apt = true
+ } else {
+ $_kick_apt = false
+ }
+ } else {
+ #if apt-get update has not successfully run, we should kick apt_update
+ $_kick_apt = true
+ }
+ }
+ default: {
+ #catches 'reluctantly', and any other value (which should not occur).
+ #do nothing.
+ $_kick_apt = false
+ }
+ }
+
+ if $_kick_apt {
+ $_refresh = false
+ } else {
+ $_refresh = true
+ }
+ exec { 'apt_update':
+ command => "${::apt::provider} update",
+ loglevel => $::apt::_update['loglevel'],
+ logoutput => 'on_failure',
+ refreshonly => $_refresh,
+ timeout => $::apt::_update['timeout'],
+ tries => $::apt::_update['tries'],
+ try_sleep => 1
+ }
+}