Setting up a local YUM repository of installed RPMs

I was looking for a way to set up a local YUM repository of RPMs that are installed on my Fedora 8 system. Searching on the web, I came across this HOWTO: http://www.howtoforge.com/setting-up-a-local-yum-repository-fedora8. While I liked the idea of using rsync to mirror a YUM repository, it was prohibitively expensive to download the entire Everything folder which exceeded 9GB. I only wanted those RPMs that are currently installed on my system.

Another way I found that may work is to use the livecd-creator script in livecd-tools at http://fedoraproject.org/wiki/FedoraLiveCD/LiveCDHowTo. The livecd-creator script can download the packages specified in a kickstart file. But it will also try to create a LiveCD at the same time so it was doing more than what I need. I could hack the script but it would take some time to understand the yum Python module.

In the end, I settled for a quick-and-dirty shell script that did the job. It first creates a list of all installed RPMs and then it downloads them from the specified YUM repository mirror. Obsolete RPMs are removed and we can also check the signature of the downloaded RPMs. The script is posted below for all to use. It can also be downloaded here: mirrorf8_v1.

Usage is self-explanatory. Just run the script and it will explain to you how it should be used. Note that it requires you to have rsync and createrepo pre-installed.

#!/bin/sh

MIR=rsync://mirrors.kernel.org/fedora
REL=$MIR/releases/8/Everything/i386/os/Packages
UPD=$MIR/updates/8/i386

rsync_list() {
  echo "Contacting rsync server ($1) --> $3"
  mkdir -p $1
  rsync --dry-run -v --files-from=list_a.txt $2 . 2>/dev/null | grep rpm > $3
}

rsync_get() {
  rsync -vzP --delete --files-from=$1 $2 $3
}

remove_obsolete() {
  echo "Removing obsolete files ($1)"
  [ -e $1 ] && mv $1 $1.tmp
  mkdir -p $1
  for j in `cat $2`
  do
    [ -e $1.tmp/$j ] && mv $1.tmp/$j $1
  done
  rm -rf $1.tmp
}

cmd_list() {
  echo "Generating list of installed rpms --> list_a.txt"
  rpm -qa --qf "%{N}-%{V}-%{R}.%{ARCH}.rpm\n" | sort > list_a.txt
  rsync_list releases $REL/ list_r.txt
  rsync_list updates  $UPD/ list_u.txt
  wc list_*.txt
}

cmd_get() {
  remove_obsolete releases list_r.txt
  remove_obsolete updates list_u.txt
  rsync_get list_r.txt $REL/ releases/
  rsync_get list_u.txt $UPD/ updates/
}

cmd_checksig() {
  echo "Checking signatures (releases)"
  for i in releases/*.rpm; do rpm -K $i; done > sigs
  cut -d ":" -f 2- sigs | sort | uniq
  echo "Checking signatures (updates)"
  for i in updates/*.rpm; do rpm -K $i; done > sigs
  cut -d ":" -f 2- sigs | sort | uniq
  rm sigs
}

cmd_createrepo() {
  createrepo releases
  createrepo updates
}

cmd_clean() {
  echo "Cleaning up"
  rm -f list_[aru].txt
}

usage() {
  cat <<-MSG
	USAGE:
	  `basename $0` [ list | get | checksig | createrepo | clean ]

	  The commands below should be executed in order.
	  list       : create lists of currently installed RPMs
	  get        : fetches RPMs from repository using rsync
	  checksig   : check signatures of downloaded RPMs
	  createrepo : executes createrepo command on downloaded RPMs
	  clean      : remove lists of currently installed RPMs

MSG
  exit 1
}

case "$1" in
  list)         cmd_list ;;
  get)          cmd_get ;;
  checksig)     cmd_checksig ;;
  createrepo)   cmd_createrepo ;;
  clean)        cmd_clean ;;
  *)            usage
esac
Posted in hacks. Tags: , , . 3 Comments »