diff options
Diffstat (limited to 'puppet/modules/apt/manifests')
24 files changed, 669 insertions, 0 deletions
diff --git a/puppet/modules/apt/manifests/apt_conf.pp b/puppet/modules/apt/manifests/apt_conf.pp new file mode 100644 index 00000000..949f6157 --- /dev/null +++ b/puppet/modules/apt/manifests/apt_conf.pp @@ -0,0 +1,45 @@ +define apt::apt_conf( + $ensure = 'present', + $source = '', + $content = undef, + $refresh_apt = true ) +{ + + if $source == '' and $content == undef { + fail("One of \$source or \$content must be specified for apt_conf ${name}") + } + + if $source != '' and $content != undef { + fail("Only one of \$source or \$content must specified for apt_conf ${name}") + } + + include apt::dot_d_directories + + # One would expect the 'file' resource on sources.list.d to trigger an + # apt-get update when files are added or modified in the directory, but it + # apparently doesn't. + file { "/etc/apt/apt.conf.d/${name}": + ensure => $ensure, + owner => root, + group => 0, + mode => '0644', + } + + if $source { + File["/etc/apt/apt.conf.d/${name}"] { + source => $source, + } + } + else { + File["/etc/apt/apt.conf.d/${name}"] { + content => $content, + } + } + + if $refresh_apt { + File["/etc/apt/apt.conf.d/${name}"] { + notify => Exec['apt_updated'], + } + } + +} diff --git a/puppet/modules/apt/manifests/apticron.pp b/puppet/modules/apt/manifests/apticron.pp new file mode 100644 index 00000000..9c94f9c9 --- /dev/null +++ b/puppet/modules/apt/manifests/apticron.pp @@ -0,0 +1,24 @@ +class apt::apticron( + $ensure_version = 'installed', + $config = "apt/${::operatingsystem}/apticron_${::debian_codename}.erb", + $email = 'root', + $diff_only = '1', + $listchanges_profile = 'apticron', + $system = false, + $ipaddressnum = false, + $ipaddresses = false, + $notifyholds = '0', + $notifynew = '0', + $customsubject = '' +) { + + package { 'apticron': ensure => $ensure_version } + + file { '/etc/apticron/apticron.conf': + content => template($apt::apticron::config), + owner => root, + group => root, + mode => '0644', + require => Package['apticron']; + } +} diff --git a/puppet/modules/apt/manifests/cron/base.pp b/puppet/modules/apt/manifests/cron/base.pp new file mode 100644 index 00000000..39fc3061 --- /dev/null +++ b/puppet/modules/apt/manifests/cron/base.pp @@ -0,0 +1,20 @@ +class apt::cron::base { + + package { 'cron-apt': ensure => installed } + + case $apt_cron_hours { + '': {} + default: { + # cron-apt defaults to run every night at 4 o'clock + # so we try not to run at the same time. + cron { 'apt_cron_every_N_hours': + command => 'test -x /usr/sbin/cron-apt && /usr/sbin/cron-apt', + user => root, + hour => "${apt_cron_hours}", + minute => 10, + require => Package['cron-apt'], + } + } + } + +} diff --git a/puppet/modules/apt/manifests/cron/dist_upgrade.pp b/puppet/modules/apt/manifests/cron/dist_upgrade.pp new file mode 100644 index 00000000..74403bb7 --- /dev/null +++ b/puppet/modules/apt/manifests/cron/dist_upgrade.pp @@ -0,0 +1,29 @@ +class apt::cron::dist_upgrade inherits apt::cron::base { + + $action = "autoclean -y +dist-upgrade -y -o APT::Get::Show-Upgraded=true -o 'DPkg::Options::=--force-confold' +" + + file { '/etc/cron-apt/action.d/3-download': + ensure => absent, + } + + package { 'apt-listbugs': ensure => absent } + + file { '/etc/cron-apt/action.d/4-dist-upgrade': + content => $action, + owner => root, + group => 0, + mode => '0644', + require => Package[cron-apt]; + } + + file { '/etc/cron-apt/config.d/MAILON': + content => "MAILON=upgrade\n", + owner => root, + group => 0, + mode => '0644', + require => Package[cron-apt]; + } + +} diff --git a/puppet/modules/apt/manifests/cron/download.pp b/puppet/modules/apt/manifests/cron/download.pp new file mode 100644 index 00000000..4a19fec1 --- /dev/null +++ b/puppet/modules/apt/manifests/cron/download.pp @@ -0,0 +1,27 @@ +class apt::cron::download inherits apt::cron::base { + + $action = "autoclean -y +dist-upgrade -d -y -o APT::Get::Show-Upgraded=true +" + + file { '/etc/cron-apt/action.d/4-dist-upgrade': + ensure => absent, + } + + file { '/etc/cron-apt/action.d/3-download': + content => $action, + require => Package[cron-apt], + owner => root, + group => 0, + mode => '0644'; + } + + file { '/etc/cron-apt/config.d/MAILON': + content => "MAILON=changes\n", + require => Package[cron-apt], + owner => root, + group => 0, + mode => '0644'; + } + +} diff --git a/puppet/modules/apt/manifests/dist_upgrade.pp b/puppet/modules/apt/manifests/dist_upgrade.pp new file mode 100644 index 00000000..19c031e0 --- /dev/null +++ b/puppet/modules/apt/manifests/dist_upgrade.pp @@ -0,0 +1,9 @@ +class apt::dist_upgrade { + + exec { 'apt_dist-upgrade': + command => '/usr/bin/apt-get -q -y -o \'DPkg::Options::=--force-confold\' dist-upgrade', + refreshonly => true, + before => Exec['apt_updated'] + } + +} diff --git a/puppet/modules/apt/manifests/dist_upgrade/initiator.pp b/puppet/modules/apt/manifests/dist_upgrade/initiator.pp new file mode 100644 index 00000000..d2389883 --- /dev/null +++ b/puppet/modules/apt/manifests/dist_upgrade/initiator.pp @@ -0,0 +1,23 @@ +class apt::dist_upgrade::initiator inherits apt::dist_upgrade { + + $initiator = 'upgrade_initiator' + $initiator_abs = "${apt::apt_base_dir}/${initiator}" + + file { 'apt_upgrade_initiator': + mode => '0644', + owner => root, + group => 0, + path => $initiator_abs, + checksum => md5, + source => [ + "puppet:///modules/site_apt/${::fqdn}/${initiator}", + "puppet:///modules/site_apt/${initiator}", + "puppet:///modules/apt/${initiator}", + ], + } + + Exec['apt_dist-upgrade'] { + subscribe +> File['apt_upgrade_initiator'], + } + +} diff --git a/puppet/modules/apt/manifests/dot_d_directories.pp b/puppet/modules/apt/manifests/dot_d_directories.pp new file mode 100644 index 00000000..0ace8630 --- /dev/null +++ b/puppet/modules/apt/manifests/dot_d_directories.pp @@ -0,0 +1,15 @@ +class apt::dot_d_directories { + + # watch .d directories and ensure they are present + file { + '/etc/apt/apt.conf.d': + ensure => directory, + checksum => mtime, + notify => Exec['apt_updated']; + '/etc/apt/sources.list.d': + ensure => directory, + checksum => mtime, + notify => Exec['apt_updated']; + } + +} diff --git a/puppet/modules/apt/manifests/dselect.pp b/puppet/modules/apt/manifests/dselect.pp new file mode 100644 index 00000000..2b99a43d --- /dev/null +++ b/puppet/modules/apt/manifests/dselect.pp @@ -0,0 +1,11 @@ +# manage dselect, like +# suppressing the annoying help texts +class apt::dselect { + + file_line { 'dselect_expert': + path => '/etc/dpkg/dselect.cfg', + line => 'expert', + } + + package { 'dselect': ensure => installed } +} diff --git a/puppet/modules/apt/manifests/init.pp b/puppet/modules/apt/manifests/init.pp new file mode 100644 index 00000000..4c44af2a --- /dev/null +++ b/puppet/modules/apt/manifests/init.pp @@ -0,0 +1,150 @@ +# apt.pp - common components and defaults for handling apt +# Copyright (C) 2008 Micah Anerson <micah@riseup.net> +# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at> +# See LICENSE for the full license granted to you. + +class apt( + $use_lts = $apt::params::use_lts, + $use_volatile = $apt::params::use_volatile, + $use_backports = $apt::params::use_backports, + $include_src = $apt::params::include_src, + $use_next_release = $apt::params::use_next_release, + $debian_url = $apt::params::debian_url, + $security_url = $apt::params::security_url, + $backports_url = $apt::params::backports_url, + $lts_url = $apt::params::lts_url, + $volatile_url = $apt::params::volatile_url, + $ubuntu_url = $apt::params::ubuntu_url, + $repos = $apt::params::repos, + $custom_preferences = $apt::params::custom_preferences, + $custom_sources_list = '', + $custom_key_dir = $apt::params::custom_key_dir +) inherits apt::params { + case $::operatingsystem { + 'debian': { + $real_repos = $repos ? { + 'auto' => 'main contrib non-free', + default => $repos, + } + } + 'ubuntu': { + $real_repos = $repos ? { + 'auto' => 'main restricted universe multiverse', + default => $repos, + } + } + } + + package { 'apt': + ensure => installed, + require => undef, + } + + $sources_content = $custom_sources_list ? { + '' => template( "apt/${::operatingsystem}/sources.list.erb"), + default => $custom_sources_list + } + file { + # include main and security + # additional sources should be included via the apt::sources_list define + '/etc/apt/sources.list': + content => $sources_content, + notify => Exec['apt_updated'], + owner => root, + group => 0, + mode => '0644'; + } + + apt_conf { '02show_upgraded': + source => [ "puppet:///modules/site_apt/${::fqdn}/02show_upgraded", + 'puppet:///modules/site_apt/02show_upgraded', + 'puppet:///modules/apt/02show_upgraded' ] + } + + if ( $::virtual == 'vserver' ) { + apt_conf { '03clean_vserver': + source => [ "puppet:///modules/site_apt/${::fqdn}/03clean_vserver", + 'puppet:///modules/site_apt/03clean_vserver', + 'puppet:///modules/apt/03clean_vserver' ], + alias => '03clean'; + } + } + else { + apt_conf { '03clean': + source => [ "puppet:///modules/site_apt/${::fqdn}/03clean", + 'puppet:///modules/site_apt/03clean', + 'puppet:///modules/apt/03clean' ] + } + } + + case $custom_preferences { + false: { + include apt::preferences::absent + } + default: { + # When squeeze becomes the stable branch, transform this file's header + # into a preferences.d file + include apt::preferences + } + } + + include apt::dot_d_directories + + ## This package should really always be current + package { 'debian-archive-keyring': ensure => latest } + + # backports uses the normal archive key now + package { 'debian-backports-keyring': ensure => absent } + + if ($use_backports and !($::debian_release in ['testing', 'unstable', 'experimental'])) { + apt::sources_list { + 'backports': + content => "deb $backports_url ${::debian_codename}-backports ${apt::real_repos}", + } + if $include_src { + apt::sources_list { + 'backports-src': + content => "deb-src $backports_url ${::debian_codename}-backports ${apt::real_repos}", + } + } + } + + include common::moduledir + common::module_dir { 'apt': } + $apt_base_dir = "${common::moduledir::module_dir_path}/apt" + + if $custom_key_dir { + file { "${apt_base_dir}/keys.d": + source => $custom_key_dir, + recurse => true, + owner => root, + group => root, + mode => '0755', + } + exec { 'custom_keys': + command => "find ${apt_base_dir}/keys.d -type f -exec apt-key add '{}' \\;", + subscribe => File["${apt_base_dir}/keys.d"], + refreshonly => true, + notify => Exec[refresh_apt] + } + if $custom_preferences != false { + Exec['custom_keys'] { + before => File['apt_config'] + } + } + } + + # workaround for preseeded_package component + file { [ '/var/cache', '/var/cache/local', '/var/cache/local/preseeding' ]: ensure => directory } + + exec { 'update_apt': + command => '/usr/bin/apt-get update', + require => [ + File['/etc/apt/apt.conf.d', '/etc/apt/preferences' ], + File['/etc/apt/sources.list'] ], + refreshonly => true, + # Another Semaphor for all packages to reference + alias => [ 'apt_updated', 'refresh_apt'] + } + +} diff --git a/puppet/modules/apt/manifests/key.pp b/puppet/modules/apt/manifests/key.pp new file mode 100644 index 00000000..cb70ec6a --- /dev/null +++ b/puppet/modules/apt/manifests/key.pp @@ -0,0 +1,13 @@ +define apt::key ($source, $ensure = 'present') { + validate_re( + $name, '\.gpg$', + 'An apt::key resource name must have the .gpg extension', + ) + + file { + "/etc/apt/trusted.gpg.d/${name}": + ensure => $ensure, + source => $source, + notify => Exec['apt_updated'], + } +} diff --git a/puppet/modules/apt/manifests/key/plain.pp b/puppet/modules/apt/manifests/key/plain.pp new file mode 100644 index 00000000..dff8b51b --- /dev/null +++ b/puppet/modules/apt/manifests/key/plain.pp @@ -0,0 +1,13 @@ +define apt::key::plain ($source) { + file { + "${apt::apt_base_dir}/keys/${name}": + source => $source; + "${apt::apt_base_dir}/keys": + ensure => directory; + } + exec { "apt-key add '${apt::apt_base_dir}/keys/${name}'": + subscribe => File["${apt::apt_base_dir}/keys/${name}"], + refreshonly => true, + notify => Exec['apt_updated'], + } +} diff --git a/puppet/modules/apt/manifests/listchanges.pp b/puppet/modules/apt/manifests/listchanges.pp new file mode 100644 index 00000000..e64bb1b7 --- /dev/null +++ b/puppet/modules/apt/manifests/listchanges.pp @@ -0,0 +1,19 @@ +class apt::listchanges( + $ensure_version = 'installed', + $config = "apt/${::operatingsystem}/listchanges_${::debian_codename}.erb", + $frontend = 'mail', + $email = 'root', + $confirm = '0', + $saveseen = '/var/lib/apt/listchanges.db', + $which = 'both' +){ + package { 'apt-listchanges': ensure => $ensure_version } + + file { '/etc/apt/listchanges.conf': + content => template($apt::listchanges::config), + owner => root, + group => root, + mode => '0644', + require => Package['apt-listchanges']; + } +} diff --git a/puppet/modules/apt/manifests/params.pp b/puppet/modules/apt/manifests/params.pp new file mode 100644 index 00000000..28af06eb --- /dev/null +++ b/puppet/modules/apt/manifests/params.pp @@ -0,0 +1,22 @@ +class apt::params () { + $use_lts = false + $use_volatile = false + $use_backports = true + $include_src = false + $use_next_release = false + $debian_url = 'http://httpredir.debian.org/debian/' + $security_url = 'http://security.debian.org/' + $ubuntu_url = 'http://archive.ubuntu.com/ubuntu' + $backports_url = $::debian_codename ? { + 'squeeze' => 'http://backports.debian.org/debian-backports/', + default => $::operatingsystem ? { + 'Ubuntu' => $ubuntu_url, + default => $debian_url, + } + } + $lts_url = $debian_url + $volatile_url = 'http://volatile.debian.org/debian-volatile/' + $repos = 'auto' + $custom_preferences = '' + $custom_key_dir = false +} diff --git a/puppet/modules/apt/manifests/preferences.pp b/puppet/modules/apt/manifests/preferences.pp new file mode 100644 index 00000000..6982ca05 --- /dev/null +++ b/puppet/modules/apt/manifests/preferences.pp @@ -0,0 +1,20 @@ +class apt::preferences { + + $pref_contents = $apt::custom_preferences ? { + '' => $::operatingsystem ? { + 'debian' => template("apt/${::operatingsystem}/preferences_${::debian_codename}.erb"), + 'ubuntu' => template("apt/${::operatingsystem}/preferences_${::ubuntu_codename}.erb"), + }, + default => $apt::custom_preferences + } + + file { '/etc/apt/preferences': + ensure => present, + alias => 'apt_config', + # only update together + content => $pref_contents, + require => File['/etc/apt/sources.list'], + owner => root, group => 0, mode => '0644'; + } + +} diff --git a/puppet/modules/apt/manifests/preferences/absent.pp b/puppet/modules/apt/manifests/preferences/absent.pp new file mode 100644 index 00000000..f32e0307 --- /dev/null +++ b/puppet/modules/apt/manifests/preferences/absent.pp @@ -0,0 +1,7 @@ +class apt::preferences::absent { + + file { '/etc/apt/preferences': + ensure => absent, + alias => 'apt_config', + } +} diff --git a/puppet/modules/apt/manifests/preferences_snippet.pp b/puppet/modules/apt/manifests/preferences_snippet.pp new file mode 100644 index 00000000..b7dba0d8 --- /dev/null +++ b/puppet/modules/apt/manifests/preferences_snippet.pp @@ -0,0 +1,59 @@ +define apt::preferences_snippet ( + $priority = undef, + $package = false, + $ensure = 'present', + $source = '', + $release = '', + $pin = '' +) { + + $real_package = $package ? { + false => $name, + default => $package, + } + + if $ensure == 'present' { + if $apt::custom_preferences == false { + fail('Trying to define a preferences_snippet with $custom_preferences set to false.') + } + + if $priority == undef { + fail('apt::preferences_snippet requires the \'priority\' argument to be set') + } + + if !$pin and !$release { + fail('apt::preferences_snippet requires one of the \'pin\' or \'release\' argument to be set') + } + if $pin and $release { + fail('apt::preferences_snippet requires either a \'pin\' or \'release\' argument, not both') + } + } + + file { "/etc/apt/preferences.d/${name}": + ensure => $ensure, + owner => root, group => 0, mode => '0644', + before => Exec['apt_updated']; + } + + case $source { + '': { + case $release { + '': { + File["/etc/apt/preferences.d/${name}"]{ + content => template('apt/preferences_snippet.erb') + } + } + default: { + File["/etc/apt/preferences.d/${name}"]{ + content => template('apt/preferences_snippet_release.erb') + } + } + } + } + default: { + File["/etc/apt/preferences.d/${name}"]{ + source => $source + } + } + } +} diff --git a/puppet/modules/apt/manifests/preseeded_package.pp b/puppet/modules/apt/manifests/preseeded_package.pp new file mode 100644 index 00000000..3ef06879 --- /dev/null +++ b/puppet/modules/apt/manifests/preseeded_package.pp @@ -0,0 +1,21 @@ +define apt::preseeded_package ( + $ensure = 'installed', + $content = '' +) { + $seedfile = "/var/cache/local/preseeding/${name}.seeds" + $real_content = $content ? { + '' => template ( "site_apt/${::debian_codename}/${name}.seeds" ), + default => $content + } + + file { $seedfile: + content => $real_content, + mode => '0600', owner => root, group => root, + } + + package { $name: + ensure => $ensure, + responsefile => $seedfile, + require => File[$seedfile], + } +} diff --git a/puppet/modules/apt/manifests/proxy_client.pp b/puppet/modules/apt/manifests/proxy_client.pp new file mode 100644 index 00000000..9ba79f23 --- /dev/null +++ b/puppet/modules/apt/manifests/proxy_client.pp @@ -0,0 +1,9 @@ +class apt::proxy_client( + $proxy = 'http://localhost', + $port = '3142', +){ + + apt_conf { '20proxy': + content => template('apt/20proxy.erb'), + } +} diff --git a/puppet/modules/apt/manifests/reboot_required_notify.pp b/puppet/modules/apt/manifests/reboot_required_notify.pp new file mode 100644 index 00000000..722e8a5e --- /dev/null +++ b/puppet/modules/apt/manifests/reboot_required_notify.pp @@ -0,0 +1,21 @@ +class apt::reboot_required_notify { + + # This package installs the script that created /var/run/reboot-required*. + # This script (/usr/share/update-notifier/notify-reboot-required) is + # triggered e.g. by kernel packages. + package { 'update-notifier-common': + ensure => installed, + } + + # cron-apt defaults to run every night at 4 o'clock + # plus some random time <1h. + # so we check if a reboot is required a bit later. + cron { 'apt_reboot_required_notify': + command => 'if [ -f /var/run/reboot-required ]; then echo "Reboot required\n" ; cat /var/run/reboot-required.pkgs ; fi', + user => root, + hour => 5, + minute => 20, + require => Package['update-notifier-common'], + } + +} diff --git a/puppet/modules/apt/manifests/sources_list.pp b/puppet/modules/apt/manifests/sources_list.pp new file mode 100644 index 00000000..0ee068d1 --- /dev/null +++ b/puppet/modules/apt/manifests/sources_list.pp @@ -0,0 +1,40 @@ +define apt::sources_list ( + $ensure = 'present', + $source = '', + $content = undef +) { + + if $ensure == 'present' { + if $source == '' and $content == undef { + fail("One of \$source or \$content must be specified for apt_sources_snippet ${name}") + } + if $source != '' and $content != undef { + fail("Only one of \$source or \$content must specified for apt_sources_snippet ${name}") + } + } + + include apt::dot_d_directories + + $realname = regsubst($name, '\.list$', '') + + # One would expect the 'file' resource on sources.list.d to trigger an + # apt-get update when files are added or modified in the directory, but it + # apparently doesn't. + file { "/etc/apt/sources.list.d/${realname}.list": + ensure => $ensure, + owner => root, group => 0, mode => '0644', + notify => Exec['apt_updated'], + } + + if $source { + File["/etc/apt/sources.list.d/${realname}.list"] { + source => $source, + } + } + else { + File["/etc/apt/sources.list.d/${realname}.list"] { + content => $content, + } + } +} + diff --git a/puppet/modules/apt/manifests/unattended_upgrades.pp b/puppet/modules/apt/manifests/unattended_upgrades.pp new file mode 100644 index 00000000..52d75425 --- /dev/null +++ b/puppet/modules/apt/manifests/unattended_upgrades.pp @@ -0,0 +1,34 @@ +class apt::unattended_upgrades ( + $config_content = undef, + $config_template = 'apt/50unattended-upgrades.erb', + $mailonlyonerror = true, + $mail_recipient = 'root', + $blacklisted_packages = [], + $ensure_version = present +) { + + package { 'unattended-upgrades': + ensure => $ensure_version + } + + # For some reason, this directory is sometimes absent, which causes + # unattended-upgrades to crash. + file { '/var/log/unattended-upgrades': + ensure => directory, + owner => 'root', + group => 0, + mode => '0755', + require => Package['unattended-upgrades'], + } + + $file_content = $config_content ? { + undef => template($config_template), + default => $config_content + } + + apt_conf { '50unattended-upgrades': + content => $file_content, + require => Package['unattended-upgrades'], + refresh_apt => false + } +} diff --git a/puppet/modules/apt/manifests/update.pp b/puppet/modules/apt/manifests/update.pp new file mode 100644 index 00000000..dde83200 --- /dev/null +++ b/puppet/modules/apt/manifests/update.pp @@ -0,0 +1,7 @@ +class apt::update inherits ::apt { + + Exec['update_apt'] { + refreshonly => false + } + +} diff --git a/puppet/modules/apt/manifests/upgrade_package.pp b/puppet/modules/apt/manifests/upgrade_package.pp new file mode 100644 index 00000000..30572c96 --- /dev/null +++ b/puppet/modules/apt/manifests/upgrade_package.pp @@ -0,0 +1,31 @@ +define apt::upgrade_package ( + $version = '' +) { + + $version_suffix = $version ? { + '' => '', + 'latest' => '', + default => "=${version}", + } + + if !defined(Package['apt-show-versions']) { + package { 'apt-show-versions': + ensure => installed, + require => undef, + } + } + + if !defined(Package['dctrl-tools']) { + package { 'dctrl-tools': + ensure => installed, + require => undef, + } + } + + exec { "apt-get -q -y -o 'DPkg::Options::=--force-confold' install ${name}${version_suffix}": + onlyif => [ "grep-status -F Status installed -a -P $name -q", "apt-show-versions -u $name | grep -q upgradeable" ], + require => Package['apt-show-versions', 'dctrl-tools'], + before => Exec['apt_updated'] + } + +} |