diff --git a/Puppetfile b/Puppetfile index 3c81565..fd87de8 100644 --- a/Puppetfile +++ b/Puppetfile @@ -11,3 +11,5 @@ mod 'ghoneycutt-puppet', '3.3.0' mod 'puppet-archive', '7.0.0' mod 'puppet-chrony', '2.6.0' mod 'puppetlabs-vcsrepo', '6.1.0' +mod 'puppetlabs-yumrepo_core', '2.0.0' +mod 'puppet-yum', '7.0.0' diff --git a/hiera.yaml b/hiera.yaml index 600c7fd..c601683 100644 --- a/hiera.yaml +++ b/hiera.yaml @@ -6,5 +6,9 @@ defaults: hierarchy: - name: Node-specific data path: "nodes/%{trusted.certname}.yaml" + - name: "Per-OS & Release Specific Data" + path: "os/%{facts.os.name}/%{facts.os.name}%{facts.os.release.major}.yaml" + - name: "Per-OS Specific Data" + path: "os/%{facts.os.name}/all_releases.yaml" - name: Common data shared across nodes path: "common.yaml" diff --git a/hieradata/os/AlmaLinux/AlmaLinux8.yaml b/hieradata/os/AlmaLinux/AlmaLinux8.yaml new file mode 100644 index 0000000..054926a --- /dev/null +++ b/hieradata/os/AlmaLinux/AlmaLinux8.yaml @@ -0,0 +1,7 @@ +# hieradata/os/AlmaLinux/AlmaLinux8.yaml +--- +profile::yum::managed_repos: + - 'base' + - 'extras' + - 'appstream' + - 'epel' diff --git a/hieradata/os/AlmaLinux/AlmaLinux9.yaml b/hieradata/os/AlmaLinux/AlmaLinux9.yaml new file mode 100644 index 0000000..b0c9384 --- /dev/null +++ b/hieradata/os/AlmaLinux/AlmaLinux9.yaml @@ -0,0 +1,7 @@ +# hieradata/os/AlmaLinux/AlmaLinux9.yaml +--- +profile::yum::managed_repos: + - 'base' + - 'extras' + - 'appstream' + - 'epel' diff --git a/hieradata/os/AlmaLinux/all_releases.yaml b/hieradata/os/AlmaLinux/all_releases.yaml new file mode 100644 index 0000000..a02c28e --- /dev/null +++ b/hieradata/os/AlmaLinux/all_releases.yaml @@ -0,0 +1,4 @@ +# hieradata/os/almalinux/all_releases.yaml +--- +profile::yum::base::baseurl: http://almalinux.mirror.digitalpacific.com.au +profile::yum::epel::baseurl: http://epel.mirror.digitalpacific.com.au diff --git a/site/profile/manifests/base.pp b/site/profile/manifests/base.pp index 1e9744e..feb8c5e 100644 --- a/site/profile/manifests/base.pp +++ b/site/profile/manifests/base.pp @@ -5,4 +5,6 @@ class profile::base ( class { 'chrony': servers => $ntp_servers, } + + include profile::yum::global } diff --git a/site/profile/manifests/yum/base.pp b/site/profile/manifests/yum/base.pp new file mode 100644 index 0000000..7ac952e --- /dev/null +++ b/site/profile/manifests/yum/base.pp @@ -0,0 +1,67 @@ +# Class: profile::yum::base +# +# This class manages the 'base', extras' and 'appstream' yum +# repositories for a system, based on the provided list of managed repositories. +# +# Parameters: +# ----------- +# - $managed_repos: An array containing the names of the repositories to be +# managed. This can include 'base', 'extras', +# and 'appstream'. +# +# - $baseurl: The base URL for the yum repositories. This should be the root +# URL of your yum mirror server. +# +# Actions: +# -------- +# - Sets up the 'base', extras', and 'appstream' yum repositories +# as specified in the $managed_repos parameter, all using the provided baseurl. +# +# - Each repo configuration includes the baseurl parameterized with the OS +# release version and architecture, and specifies the GPG key. +# +# Example usage: +# -------------- +# To use this class with the default parameters: +# class { 'profile::yum::base': +# managed_repos => ['base', 'extras', 'appstream'], +# baseurl => 'http://mylocalmirror.com/yum', +# } +# +class profile::yum::base ( + Array[String] $managed_repos, + String $baseurl, +) { + $releasever = $facts['os']['release']['major'] + $basearch = $facts['os']['architecture'] + + if 'base' in $managed_repos { + yumrepo { 'base': + name => 'base', + descr => 'base repository', + target => '/etc/yum.repos.d/base.repo', + baseurl => "${baseurl}/${releasever}/BaseOS/${basearch}/os/", + gpgkey => "${baseurl}/RPM-GPG-KEY-${facts['os']['name']}", + } + } + + if 'extras' in $managed_repos { + yumrepo { 'extras': + name => 'extras', + descr => 'extras repository', + target => '/etc/yum.repos.d/extras.repo', + baseurl => "${baseurl}/${releasever}/extras/${basearch}/os/", + gpgkey => "${baseurl}/RPM-GPG-KEY-${facts['os']['name']}", + } + } + + if 'appstream' in $managed_repos { + yumrepo { 'appstream': + name => 'appstream', + descr => 'appstream repository', + target => '/etc/yum.repos.d/appstream.repo', + baseurl => "${baseurl}/${releasever}/AppStream/${basearch}/os/", + gpgkey => "${baseurl}/RPM-GPG-KEY-${facts['os']['name']}", + } + } +} diff --git a/site/profile/manifests/yum/epel.pp b/site/profile/manifests/yum/epel.pp new file mode 100644 index 0000000..47f1b10 --- /dev/null +++ b/site/profile/manifests/yum/epel.pp @@ -0,0 +1,57 @@ +# Class: profile::yum::epel +# +# This class manages the EPEL yum repository for the system. +# +# Parameters: +# ----------- +# - $baseurl: The base URL for the EPEL yum repository. This should be the root +# URL of your EPEL mirror server. +# +# Actions: +# -------- +# - Checks the OS release version. +# +# - If the release version is 7, 8, or 9, it sets up the 'epel' yum repository +# and installs the EPEL release RPM from the provided baseurl. +# +# - If the release version is not supported, it raises an error. +# +# - The repo configuration includes the baseurl parameterized with the OS +# release version and architecture, and specifies the GPG key. +# +# Example usage: +# -------------- +# To use this class with the default parameters: +# include profile::yum::epel +# +# To specify a custom base URL: +# class { 'profile::yum::epel': +# baseurl => 'http://mylocalmirror.com/yum', +# } +class profile::yum::epel ( + Array[String] $managed_repos, + String $baseurl, +) { + $releasever = $facts['os']['release']['major'] + $basearch = $facts['os']['architecture'] + + if 'epel' in $managed_repos { + if ($releasever in [7,8,9]) { + $source = "${baseurl}/epel-release-latest-${releasever}.noarch.rpm" + + yum::install { 'epel-release': + ensure => present, + source => $source, + } + } else { + err("Unsupported OS release ${releasever}") + } + yumrepo { 'epel': + name => 'epel', + descr => 'epel repository', + target => '/etc/yum.repos.d/epel.repo', + baseurl => "${baseurl}/${releasever}/Everything/${basearch}/", + gpgkey => "${baseurl}/RPM-GPG-KEY-EPEL-${releasever}", + } + } +} diff --git a/site/profile/manifests/yum/global.pp b/site/profile/manifests/yum/global.pp new file mode 100644 index 0000000..6946d9a --- /dev/null +++ b/site/profile/manifests/yum/global.pp @@ -0,0 +1,98 @@ +# Class: profile::yum::global +# +# This class manages global YUM configurations and optionally includes the +# base and EPEL yum repository profiles based on the content of the +# $managed_repos parameter, which is an array of repository names. +# +# Parameters: +# ----------- +# - $managed_repos: An array of repository names that the Puppet agent should +# manage. This parameter is mandatory and the class will +# fail if it is not provided via hieradata. +# Example: ['base', 'updates', 'extras', 'appstream'] +# +# Actions: +# -------- +# - Configures global YUM settings, including keeping the kernel development +# packages and cleaning old kernels. +# +# - Establishes default parameters for any YUM repositories managed by Puppet. +# This includes the repository file location, the repository description, +# and enabling the repository and GPG checks. +# +# - Depending on the content of the $managed_repos parameter, it includes the +# profile::yum::base and/or profile::yum::epel classes. +# +# - Manages all .repo files under /etc/yum.repos.d. All the repositories listed +# in $managed_repos will have their corresponding .repo files preserved. Any +# .repo file that is not listed in $managed_repos will be removed. +# +# - Creates and maintains a /etc/yum.repos.d/.managed file that lists all the +# .repo files that should be managed by Puppet. +# +# Example usage: +# -------------- +# To use this class, include the class and configure hieradata: +# include profile::yum::global +# +# profile::yum::managed_repos: +# - 'base' +# - 'extras' +# - 'appstream' +# +class profile::yum::global ( + Array[String] $managed_repos = lookup('profile::yum::managed_repos'), +){ + class { 'yum': + keep_kernel_devel => true, + clean_old_kernels => true, + config_options => { + gpgcheck => true, + }, + } + + Yumrepo { + ensure => 'present', + enabled => 1, + gpgcheck => 1, + mirrorlist => 'absent', + } + +# tidy { '/etc/yum.repos.d': +# matches => ['*.repo', '!*.managed.repo'], +# recurse => true, +# rmdirs => false, +# age => '0s', +# backup => false, +# type => 'ctime', +# } + + # Generate the content for the .managed file + $managed_file_content = $managed_repos.map |$repo_name| { "${repo_name}.repo" }.join("\n") + + # Create the .managed file + file { '/etc/yum.repos.d/.managed': + ensure => file, + content => $managed_file_content, + } + + # Define exec resource to remove .repo files not listed in .managed + exec { 'cleanup_yum_repos': + command => '/bin/bash -c "comm -23 <(ls /etc/yum.repos.d | sort) + <(sort /etc/yum.repos.d/.managed) | + xargs -n1 rm -f /etc/yum.repos.d/{}"', + path => ['/bin', '/usr/bin'], + onlyif => '/bin/bash -c "comm -23 <(ls /etc/yum.repos.d | sort) + <(sort /etc/yum.repos.d/.managed) | grep .repo"', + } + + # Setup base repos + class { 'profile::yum::base': + managed_repos => $managed_repos, + } + + # Setup epel if included in managed_repos + class { 'profile::yum::epel': + managed_repos => $managed_repos, + } +}