Google Site SearchFN Site Search FN Blog Login FN Blog Login
Site Navigation:
 
 

Creating a local yum repository

by Alexandre de Abreu

The script

The first thing we need to do is check the requirements and download the script below to the repository machine. It'll get the packages from the specified mirror and then executes yum-arch program who creates the headers information. After doing this, you can go next page and follow the instructions.

#!/bin/sh

# Wgets(http) rpm packages then executes yum-arch/createrepo
# creating the repository headers on local machine
# http://fedoranews.org/alex/tutorial/yum/

# Last Modified: 05/01/2005

# Setup including:
# Mirror examples for RH9 and Fedora Base/Updates
# Yum.conf configuration
# GPG/MD5 checking, Proxy support
# yum-arch and createrepo compatible

# Visit FedoraNEWS Website http://fedoranews.org
# Author: Alexandre de Abreu [alex@fedoranews.org]

# For the impatient ones: just execute this script
# and follow the advice of error messages

# Fill the MIRROR variables as you wish and test running
# on the shell, after things working try the line below
# to setup a cron job for executing every six hours:
# 1 */6 * * * user /path/to/yum_repository.sh

# Configure your clients /etc/yum.conf with the following
# lines and start a web/ftp server on the repository
# [updates-local]
# name=Linux $releasever - $basearch - Updates
# baseurl=http://repository_ipaddr/path/to/repository/
# OR
# baseurl=ftp://repository_ipaddr/path/to/repository/

# And change the local repository server yum.conf to:
# baseurl=file:///path/to/repository/

# Mirrors arrays  ###################################
# Try to use those with "Indexes" Apache option enabled
# Fedora mirrors http://fedora.redhat.com/download/mirrors.html
# RedHat mirrors http://www.redhat.com/download/mirror.html
# Yum RPM for Red Hat http://www.linux.duke.edu/projects/yum/download.ptml

# Put any numbers of mirrors here, sequentially:
# MIRROR_URL[X]="http://url"
# MIRROR_DIR[X]="/filesystem/path"

# MIRROR_URL    -> Where to get .rpm files, must be a URL
# MIRROR_DIR    -> Where .rpm files and repository struct will be on the disk
# X             -> Subscript, array index, must begin with 0

# Fedora 3 Updates Mirror
MIRROR_URL[0]="http://distro.ibiblio.org/pub/linux/distributions/fedora/linux/core/updates/3/"
MIRROR_DIR[0]="/var/ftp/pub/linux/fedora/3/updates/"
# Fedora 2 Updates Mirror
MIRROR_URL[1]="http://distro.ibiblio.org/pub/linux/distributions/fedora/linux/core/updates/2/"
MIRROR_DIR[1]="/var/ftp/pub/linux/fedora/2/updates/"

# Red Hat Updates Mirror
#MIRROR_URL[0]="http://distro.ibiblio.org/pub/linux/distributions/redhat/updates/9/en/os/"
#MIRROR_DIR[0]="/var/ftp/pub/linux/redhat/9/updates/"

# The following can be disabled after download completes
# Points to rpm packages that come with installation CD/ISO
# Fedora Core 1 and Red Hat 9 tooks 3.6G of HD space
# After this working, you can forget CD medias and just do
# yum install package and stuff, see this article for more:
# http://fedoranews.org/tchung/howto/2003-11-09-yum-intro.shtml

# Fedora Base Mirror
# MIRROR_URL[2]="http://rpmfind.net/linux/fedora/core/1/i386/os/Fedora/RPMS/"
# MIRROR_DIR[2]="/var/ftp/pub/linux/fedora/1/os/"

# Red Hat Base Mirror
# MIRROR_URL[3]="http://rpmfind.net/linux/redhat/9/en/os/i386/RedHat/RPMS/"
# MIRROR_DIR[3]="/var/ftp/pub/linux/redhat/9/os/"

# If you want HTTP Proxy support, fill at least
# PROXY_SERVER and PROXY_PORT variables
# To disable proxy support left it blank
PROXY_SERVER=""
PROXY_PORT=""
# Be carefull with the following credentials, any "ps" will show them
# Use a public user or create rules w/o auth just from this machine
# when connecting to Mirror's IP addresses tcp port 80(http)
PROXY_USER=""
PROXY_PASS=''

#####################################################
# Do not edit below this line unless you know what
# you are doing

# Filter what is intersting for us
IGNORE_FILES="*-debuginfo-*,*\.src\.rpm,*\.hdr"
ALLOW_FILES="*i[356]86\.rpm,*athlon\.rpm,*noarch\.rpm"

# List of ignored directories(space separated)
# x86_64 files are ignored by default, to disable leave it blank
IGNORE_DIRS="x86_64"

# Default umask
DEF_UMASK=022

# Log file, where all output will go
# If you dont want logging set LOG_FILE to /dev/null
# If you want to rotate it with logrotate every 1Mb
# edit /etc/logrotate.conf and add the following
# /var/log/yum_repository.log {
#	 create 644 user group
#        compress
#        nomail
#        missingok
#        notifempty
#        rotate 2
#        size 5M
# }
LOG_FILE="/var/log/yum_repository.log"

# Allow resume[-c]
# Do not create domain dir[-nH]
# Do not go to parent dirs[-np]
# Be recursive, needed[-r]
# Append to output log[-a]
WGET_ARGS="-a $LOG_FILE -R $IGNORE_FILES -A $ALLOW_FILES -np -nH -c -r"
WGET=$(/usr/bin/which --skip-dot --skip-tilde wget 2>/dev/null) || {
	/bin/echo "[*] Try installing wget and check PATH var"
	/bin/echo "[*] Exiting.."
	exit 1
}

# GPG/MD5 check, this can be done on yum.conf on clients too
# If enabled, bad packages will be renamed to with .BAD extentsion
# before repository structure creation/update
# This is done using "rpm -K package" command
# 0 = disable 1=enable
GPGCHECK=1

# Createrepo support for FC3+ compaibility
YUMARCH=$(/usr/bin/which --skip-dot --skip-tilde yum-arch 2>/dev/null)
CREATEREPO=$(/usr/bin/which --skip-dot --skip-tilde createrepo 2>/dev/null)

[ -z "$YUMARCH" -a -z "$CREATEREPO" ] && {
	/bin/echo "[*] Try installing yum-arch or createrepo programs and check PATH var"
	/bin/echo "[*] Exiting.."
	exit 1
}


[ 1$(/usr/bin/id -u) -eq 10 ] && {
	/bin/echo "[*] Why running this as superuser? Try as a normal user and check"
	/bin/echo "[*] write permissions to local repository directories."
	/bin/echo "[*] Exiting.."
	exit 1
}

RPM=$(/usr/bin/which --skip-dot --skip-tilde rpm 2>/dev/null) || {
	/bin/echo "[*] Try installing RPM and check PATH var"
	/bin/echo "[*] Exiting.."
	exit 1
}

# Check presence of public GPG key(s)
$RPM --quiet -q gpg-pubkey || {
	/bin/echo "[*] No public GPG key(s) installed."
	/bin/echo "[*] Try to execute: rpm --import /usr/share/rhn/GPG_KEY_FILE"
	exit 1
}

# Check if logfile is writable
[ -w $LOG_FILE ] || {
	/bin/echo "[*] No write permission on logfile: $LOG_FILE"
	/bin/echo "[*] Exiting.."
	exit 1
}

PID_FILE=/tmp/.yum_repository.pid

# Check if already running
[ -s "$PID_FILE" ] && {
	/bin/echo "[*] PID File exists $PID_FILE"
	/bin/echo "[*] Checking PID.."
	PID=$(/bin/egrep -o "^[0-9]{1,}" $PID_FILE)
	/bin/ps --pid $PID && {
		/bin/echo "[*] Process $PID found."
		/bin/echo "[*] Script seems to be already running!"
		/bin/echo "[*] Exiting.."
		exit 1
	}
	/bin/echo "[*] Process ID $PID not found"
	/bin/echo "[*] Starting new process.."
}

# Check proxy options
[ -n "$PROXY_SERVER" -a -n "$PROXY_PORT" ] && {
	# Exporting for wget
	export http_proxy="$PROXY_SERVER:$PROXY_PORT" && PROXY_FLAG=1
	WGET_ARGS="$WGET_ARGS --proxy=on"
	[ -n "$PROXY_USER" -a -n "$PROXY_PASS" ] && WGET_ARGS="$WGET_ARGS \
	--proxy-user=$PROXY_USER --proxy-passwd=$PROXY_PASS"
}

# No process running, starting new one
/bin/echo $$ > $PID_FILE

# Sets umask
umask $DEF_UMASK

# Starts from 1st mirror definition
count=0

while [ ${MIRROR_URL[count]} ]; do
	# Some checking
	[ -d ${MIRROR_DIR[count]} ] || {
		/bin/echo "[*] Try creating localdir ${MIRROR_DIR[count]}" 
		/bin/echo "[*] Exiting.."
		exit 1
	}

	[ -w ${MIRROR_DIR[count]} ] || {
		/bin/echo "[*] Check write permissions on localdir ${MIRROR_DIR[count]}" 
		/bin/echo "[*] Exiting.."
		exit 1
	}
	
	cd ${MIRROR_DIR[count]}
	
	CUT_DIRS=$(/bin/echo "${MIRROR_URL[count]}" | /bin/egrep -o "\/" | /usr/bin/wc -l)
	CUT_DIRS=$((CUT_DIRS-3))

	/bin/echo -e "[*] Writing logs to $LOG_FILE"
	/bin/echo -e "[*] Getting files from ${MIRROR_URL[count]}"
	/bin/echo -n "[*] Download started: " >> $LOG_FILE 
	/bin/date >> $LOG_FILE

	# Capture some intersting signals
	trap "{
		/bin/echo \"[*] Removing PID file..\"
		/bin/rm -f $PID_FILE
		[ 1$PROXY_FLAG -ne 1 ] && {
			/bin/echo \"[*] Unseting http_proxy var..\"
			unset http_proxy
		}
		/bin/echo -e \"[*] Exiting..\"
		exit 1
	}" 2 3 15 19

        [ -n "$IGNORE_DIRS" ] && {
                for i in $IGNORE_DIRS; do
                        WGET_ARGS="$WGET_ARGS -X /"`echo "${MIRROR_URL[count]}" | cut -d/ -f4-`"$i"
                done
        }

	eval $WGET $WGET_ARGS --cut-dirs $CUT_DIRS ${MIRROR_URL[count]}
	/bin/echo -e "[*] Download complete for ${MIRROR_URL[count]}\n" >> $LOG_FILE
	/bin/echo -e "[*] Download complete for ${MIRROR_URL[count]}\n"

	# md5 and gpg signature check
	# any package that fails this check will be renamed with extension .BAD
	[ 1$GPGCHECK -eq 11 ] && {
		for rpm in `find ${MIRROR_DIR[count]} -name "*.rpm"`; do
			$RPM -K $rpm >> $LOG_FILE || {
				/bin/echo "[*] Bad RPM found: $rpm"
				/bin/echo "[*] Moving to $rpm.BAD"
				/bin/echo -e "\n[*] BAD package found: $rpm\n" >> $LOG_FILE
				/bin/mv -f $rpm $rpm.BAD
			}
		done
	}
	
	for PROG in $YUMARCH $CREATEREPO;do
		# create repository dirs
		/bin/echo -e "[*] Executing $PROG on ${MIRROR_DIR[count]}"
		/bin/echo -n "[*] Time started: " >> $LOG_FILE
		/bin/date >> $LOG_FILE
		eval $PROG ${MIRROR_DIR[count]} >> $LOG_FILE 2>&1
	done
	/bin/echo -e "[*] Repository creation complete for ${MIRROR_DIR[count]}\n" >> $LOG_FILE
	/bin/echo -e "[*] Repository creation complete for ${MIRROR_DIR[count]}\n"
	/bin/echo -e "[*] Done.\n\n"

	count=$((count+1))
done

/bin/chmod 600 $LOG_FILE
/bin/rm -f $PID_FILE
[ 1$PROXY_FLAG -ne 1 ] && unset http_proxy

/bin/echo "[*] Finished"
/bin/echo -n "[*] Finished on " >> $LOG_FILE
/bin/date >> $LOG_FILE

exit 0