diff options
| author | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2021-12-20 12:39:15 +0100 | 
|---|---|---|
| committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2021-12-20 12:39:15 +0100 | 
| commit | f56d2d7888be1a27d7ef05d850afdc4e9dbb464a (patch) | |
| tree | e193c75cbdb40c5290906d97b3ac8966a1099a47 /code/environments/production/modules/apt/manifests | |
| download | puppet.SGM-f56d2d7888be1a27d7ef05d850afdc4e9dbb464a.tar.gz puppet.SGM-f56d2d7888be1a27d7ef05d850afdc4e9dbb464a.tar.bz2 puppet.SGM-f56d2d7888be1a27d7ef05d850afdc4e9dbb464a.zip  | |
initial draft of a minimal puppet config template
Diffstat (limited to 'code/environments/production/modules/apt/manifests')
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 +  } +}  | 
