Yum Server Build Recipe
Changes
2007-03-31
- Packages downloaded via download_file now trigger an exec that indexes via createrepo.
- Simplified file system layout for Dag Wieer packages.
2007-03-29
- All local file paths are now compatible with lsbdistid and lsbdistrelease facts. This was done in order to ease the pain of generating baseurl values when using the yumrepo type to manage yum clients.
2007-03-28
- Split downloading functionality into a separate definition for a cleaner approach.
Features
- Full support to host yum repos for RHEL 4ES and CentOS4
- Partial support to mirror Dag Wieer's repos (Currently only RHEL EL4 packages)
- Creates a user ('repo' unless overridden) who:
- Owns the repo's files
- Runs periodic cron jobs
- Updates can be enabled/disabled
- Cron job creation to handle updates and periodic runs of createrepo
- Pulls down Dag's rhel el4 packages for yum and its dependencies (my "yum_clients" manifest installs these on rhel 4 clients before buiding repo configs).
Assumptions
- The following packages are installed on the node that includes this recipe:
- httpd
- rsync
- createrepo
- Sysadmin will need to populate the repo with base packages and run createrepo. Doing so in this recipe would be too dangerous (disk space) and would probably result in a less portable recipe.
- When calling this definition from within a node, the following elements are required:
- $name - This should be a fqdn that clients will use. I personally set this to a value that I have CNAME'd in DNS.
- $repo_root - I personally set this to /var/www/yum
To Do
- Extend support for other distros
- Decide how to satisfy package requirements. This may be tricky since we can't assume the node is configured to use yum.
Example
Once the files below have been imported into the system, a node can have a repo installed/configured simply by doing something like:
node foo {
yum_server { "yum.example.com":
repo_root => "/var/www/yum"
}
Templates
Template for Apache's Virtual Host
<VirtualHost *:80>
ServerName <%= name %>
ServerAlias <%= server_alias %>
ServerAdmin <%= server_admin %>
ServerSignature Off
ErrorLog logs/error_log
CustomLog logs/access_log combined
<Directory />
Options FollowSymLinks
AllowOverride None
Order allow,deny
Deny from all
</Directory>
# override index.html.var map crud set in the main httpd.conf
DirectoryIndex index.html
# where YUM data is located, e.g. /var/www/yum
DocumentRoot <%= repo_root %>
<Directory "<%= repo_root %>">
Options Indexes FollowSymLinks
AllowOverride None
IndexOptions -FancyIndexing +FoldersFirst
<Limit GET POST OPTIONS PROPFIND>
Order allow,deny
Allow from all
</Limit>
<LimitExcept GET POST OPTIONS PROPFIND>
Order deny,allow
Deny from all
</LimitExcept>
</Directory>
<IfModule mod_userdir.c>
UserDir disabled
</IfModule>
</VirtualHost>
Template for update-repo.sh
#!/bin/sh
#
# update-repo.sh
#
# This script was generated by Puppet via update-repo.tpl
#
updates_rhel_4es_i386_enabled=<%= updates_rhel_4es_i386_enabled %>
updates_rhel_4es_x86_64_enabled=<%= updates_rhel_4es_x86_64_enabled %>
updates_centos_4_i386_enabled=<%= updates_centos_4_i386_enabled %>
updates_centos_4_x86_64_enabled=<%= updates_centos_4_x86_64_enabled %>
if [ "$updates_rhel_4es_i386_enabled" = "true" ]; then
rsync -ar mirrors.usc.edu::redhat/updates/enterprise/4/en/os/i386/SRPMS/ <%= repo_root %>/RedHatEnterpriseES/updates/i386/SRPMS
fi
if [ "$updates_rhel_4es_x86_64_enabled" = "true" ]; then
rsync -ar mirrors.usc.edu::redhat/updates/enterprise/4/en/os/x86_64/SRPMS/ <%= repo_root %>/RedhatEnterpriseES/updates/x86_64/SRPMS
fi
# Add more as needed...
Recipe
####################################################################################################
#
# Overview
#
# This recipe will create a yum repo
#
# Package Requirements:
#
# httpd
# createrepo
# rsync
#
####################################################################################################
#
# Configuring fileserver.conf
#
# fileserver.conf should be configured to offer a share called 'gpg'.
#
# Each distro that is supported by this recipe should have a its corresponding RPM-GPG-KEY file
# placed in this location.
#
####################################################################################################
#
# Additional Information
#
# Support for automatic registration to RHN may be added in the future via rhnreg_ks
#
# createrepo will be loaded into the user's crontab. However, the initial run
# should still be executed by the sysadmin after the RPMS are copied over.
#
####################################################################################################
define yum_server(
$server_alias="yum",
$server_admin="admin@${fqdn}",
$repo_root,
$repo_owner="repo",
$updates_rhel_4es_i386_enabled=false,
$updates_rhel_4es_x86_64_enabled=false,
$updates_centos_4_i386_enabled=false,
$updates_centos_4_x86_64_enabled=false
) {
####################################################################################################
#
# The user that will maintain the repo
#
####################################################################################################
user { $repo_owner:
home => $repo_root,
shell => "/bin/bash",
}
####################################################################################################
#
# The file system
#
# When describing distros and releases in these paths, use strings that will be compatible with
# puppet facts like 'lsbdistid' and 'lsbdistrelease'.
#
# lsbdistid/lsbdistrelease
#
# Doing so will allow us to use this facts later from within the yumrepo type when we configure
# machines to use this repo
#
####################################################################################################
file { "$repo_root":
ensure => directory,
owner => $repo_owner,
group => root,
mode => 755,
require => Package[httpd]
}
# dag wieer
# http://apt.sw.be
file { [
"${repo_root}/dag",
"${repo_root}/dag/RedHatEnterpriseES",
"${repo_root}/dag/RedHatEnterpriseES/3",
"${repo_root}/dag/RedHatEnterpriseES/3/en",
"${repo_root}/dag/RedHatEnterpriseES/3/en/noarch",
"${repo_root}/dag/RedHatEnterpriseES/3/en/noarch/RPMS",
"${repo_root}/dag/RedHatEnterpriseES/3/en/i386",
"${repo_root}/dag/RedHatEnterpriseES/3/en/i386/RPMS",
"${repo_root}/dag/RedHatEnterpriseES/3/en/x86_64",
"${repo_root}/dag/RedHatEnterpriseES/3/en/x86_64/RPMS",
"${repo_root}/dag/RedHatEnterpriseES/4",
"${repo_root}/dag/RedHatEnterpriseES/4/en",
"${repo_root}/dag/RedHatEnterpriseES/4/en/noarch",
"${repo_root}/dag/RedHatEnterpriseES/4/en/noarch/RPMS",
"${repo_root}/dag/RedHatEnterpriseES/4/en/i386",
"${repo_root}/dag/RedHatEnterpriseES/4/en/i386/RPMS",
"${repo_root}/dag/RedHatEnterpriseES/4/en/x86_64",
"${repo_root}/dag/RedHatEnterpriseES/4/en/x86_64/RPMS" ]:
ensure => directory, owner => $repo_owner, group => root, mode => 755,
require => File["$repo_root"],
}
# redhat
file { [
"${repo_root}/RedHatEnterpriseES",
"${repo_root}/RedHatEnterpriseES/4",
"${repo_root}/RedHatEnterpriseES/4/i386",
"${repo_root}/RedHatEnterpriseES/4/i386/RPMS",
"${repo_root}/RedHatEnterpriseES/4/x86_64",
"${repo_root}/RedHatEnterpriseES/4/x86_64/RPMS",
"${repo_root}/RedHatEnterpriseES/updates",
"${repo_root}/RedHatEnterpriseES/updates/4",
"${repo_root}/RedHatEnterpriseES/updates/4/en",
"${repo_root}/RedHatEnterpriseES/updates/4/en/os",
"${repo_root}/RedHatEnterpriseES/updates/4/en/os/SRPMS",
"${repo_root}/RedHatEnterpriseES/site" ]:
ensure => directory, owner => $repo_owner, group => root, mode => 755,
require => File["$repo_root"],
}
# centos4
# http://isoredirect.centos.org/centos/4.4/os/
file { [
"${repo_root}/CentOS",
"${repo_root}/CentOS/4.4",
"${repo_root}/CentOS/4.4/os",
"${repo_root}/CentOS/4.4/os/i386",
"${repo_root}/CentOS/4.4/os/i386/CentOS",
"${repo_root}/CentOS/4.4/os/i386/CentOS/RPMS",
"${repo_root}/CentOS/4.4/os/x86_64",
"${repo_root}/CentOS/4.4/os/x86_64/CentOS",
"${repo_root}/CentOS/4.4/os/x86_64/CentOS/RPMS",
"${repo_root}/CentOS/4.4/updates",
"${repo_root}/CentOS/4.4/updates/i386",
"${repo_root}/CentOS/4.4/updates/i386/RPMS",
"${repo_root}/CentOS/4.4/updates/x86_64",
"${repo_root}/CentOS/4.4/updates/x86_64/RPMS",
"${repo_root}/CentOS/4.4/site" ]:
ensure => directory, owner => $repo_owner, group => root, mode => 755,
require => File["$repo_root"],
}
####################################################################################################
#
# Grab some stuff we'll need because RHEL sucks
#
# download_file is available from https://reductivelabs.com/trac/puppet/wiki/DownloadFileRecipe
#
####################################################################################################
# Dag packages for RHEL3 i386
# Dag packages for RHEL3 x86_64
# Dag packages for RHEL4 (i386)
download_file { [
"python-elementtree-1.2.6-7.el4.rf.i386.rpm",
"python-sqlite-1.0.1-1.2.el4.rf.i386.rpm",
"perl-Socket6-0.19-1.2.el4.rf.i386.rpm"
]:
site => "http://apt.sw.be/redhat/el4/en/i386/dag/RPMS",
cwd => "${repo_root}/dag/RedHatEnterpriseES/4/en/i386/RPMS",
creates => "${repo_root}/dag/RedHatEnterpriseES/4/en/i386/RPMS/$name",
require => File["${repo_root}/dag/RedHatEnterpriseES/4/en/i386/RPMS"],
user => $repo_owner,
notify => Exec["Indexing Repo"],
}
# Dag packages for RHEL4 x86_64
download_file { [
"python-elementtree-1.2.6-7.el4.rf.x86_64.rpm",
"python-sqlite-1.0.1-1.2.el4.rf.x86_64.rpm",
"perl-Socket6-0.19-1.2.el4.rf.x86_64.rpm"
]:
site => "http://apt.sw.be/redhat/el4/en/x86_64/dag/RPMS",
cwd => "${repo_root}/dag/RedHatEnterpriseES/4/en/x86_64/RPMS",
creates => "${repo_root}/dag/RedHatEnterpriseES/4/en/x86_64/RPMS/$name",
require => File["${repo_root}/dag/RedHatEnterpriseES/4/en/x86_64/RPMS"],
user => $repo_owner,
notify => Exec["Indexing Repo"],
}
# Dag packages for RHEL4 (noarch)
download_file { [
"python-urlgrabber-2.9.7-1.2.el4.rf.noarch.rpm",
"yum-2.4.2-0.4.el4.rf.noarch.rpm"
]:
site => "http://apt.sw.be/redhat/el4/en/i386/dag/RPMS",
cwd => "${repo_root}/dag/RedHatEnterpriseES/4/en/noarch/RPMS",
creates => "${repo_root}/dag/RedHatEnterpriseES/4/en/noarch/RPMS/$name",
require => File["${repo_root}/dag/RedHatEnterpriseES/4/en/noarch/RPMS"],
user => $repo_owner,
notify => Exec["Indexing Repo"],
}
# misc packages
download_file {
"perl-Digest-HMAC-1.01-14.noarch.rpm":
site => "ftp://rpmfind.net/linux/fedora/core/4/i386/os/Fedora/RPMS",
cwd => "${repo_root}/misc",
creates => "${repo_root}/misc/${name}",
require => File["${repo_root}/misc"],
user => $repo_owner,
notify => Exec["Indexing Repo"],
}
exec { "Indexing Repo":
command => "find $repo_root -type d -name 'RPMS' | while read rpmdir; do /usr/bin/createrepo \$rpmdir > /dev/null; done",
user => $repo_owner,
refreshonly => true,
}
####################################################################################################
#
# Manage updates
#
####################################################################################################
file { "/usr/local/bin/update_repo.sh":
ensure => present,
owner => $repo_owner,
group => root,
mode => 700,
content => template("scripts/update_repo.tpl"),
require => User["$repo_owner"]
}
cron { cron_update_repo:
ensure => present,
command => "/usr/local/bin/update_repo.sh",
weekday => 0,
hour => 1,
user => $repo_owner,
require => [ User["$repo_owner"], File["/usr/local/bin/update_repo.sh"] ]
}
cron { "cron-creatrepo":
ensure => present,
command => "find $repo_root -type d -name 'RPMS' | while read rpmdir; do /usr/bin/createrepo \$rpmdir > /dev/null; done
",
weekday => 1,
hour => 1,
user => $repo_owner,
require => [ User["$repo_owner"], File["$repo_root"] ]
}
####################################################################################################
#
# Web Server
#
####################################################################################################
file { "/etc/httpd/conf.d/vhost-yum-repo.conf":
alias => "vhost-conf",
content => template("services/vhost-yum-repo.tpl"),
ensure => present,
owner => root,
group => root,
mode => 644,
require => Package[httpd]
}
tidy { "/etc/httpd/conf.d/welcome.conf":
age => '0s',
before => Service[httpd]
}
package { httpd:
ensure => installed
}
service { httpd:
ensure=> true,
subscribe => File[vhost-conf],
}
####################################################################################################
#
# GPG Keys for package validation
#
####################################################################################################
file { "${repo_root}/RedHatEnterpriseES/RPM-GPG-KEY":
ensure => present,
owner => root,
group => root,
mode => 444,
source => "puppet://puppet/gpg/RPM-GPG-KEY-RedHat",
checksum => md5,
require => [ File["$repo_root"], File["${repo_root}/RedHatEnterpriseES"] ]
}
file { "${repo_root}/CentOS/RPM-GPG-KEY":
ensure => present,
owner => root,
group => root,
mode => 444,
source => "puppet://puppet/gpg/RPM-GPG-KEY-CentOS",
checksum => md5,
require => [ File["$repo_root"], File["${repo_root}/CentOS"] ]
}
file { "${repo_root}/dag/RPM-GPG-KEY":
ensure => present,
owner => root,
group => root,
mode => 444,
source => "puppet://puppet/gpg/RPM-GPG-KEY-dag",
checksum => md5,
require => [ File["$repo_root"], File["${repo_root}/dag"] ]
}
# Some RHEL stuff if we decide to get more involved later...
#file { "/etc/sysconfig/rhn/systemid":
# alias => "rhn-subscribed"
#}
}