7fd9a197336f2deaa5ae643b5c3797292513ed1d
[rpmbased-dist-chroot.git] / rpmbased-dist-chroot.sh
1 #!/bin/bash
2
3 # rpmbased-dist-chroot.sh - builds a simple chroot from a directory of .rpms
4 #                           best to feed it the RPMS directory of a particular
5 #                           distribution. Has been tested with FC4.
6 # Copyright (C) 2004 Brett Parker <iDunno@sommitrealweird.co.uk>
7 #
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
12
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
22 # Default to expecting a Fedora CD mounted at /media/cdrom
23 # and installing bash, coreutils and yum to /mnt/temp/fedora
24
25 RPMArchives=/media/cdrom/Fedora/RPMS
26 InstallRoot=/mnt/temp/fedora
27 installpackages="bash coreutils yum"
28
29 ourcachedirectory=$(mktemp -d)
30
31 architecture=$(uname -m)
32 export ARCH=$architecture
33
34 case $architecture in
35         i686)
36                 architecture="i686,i586,i486,i386"
37                 ;;
38         i586)
39                 architecture="i586,i486,i386"
40                 ;;
41         i486)
42                 architecture="i486,i386"
43                 ;;
44 esac
45
46 function displayHelp() {
47 cat <<END
48 Usage: $0 [options]
49
50 Options:
51         --install-root <directorytoinstallto>
52         --rpm-archives <pathtorpms>
53         --install-packages <listofpackagestoinstall>
54 END
55         exit $1
56 }
57
58 function startswithmm() {
59         if [ "${1##--*}" == "" ]; then
60                 return 0
61         else
62                 return 1
63         fi
64 }
65
66 function containsequals() {
67         if [ "${1//*=*}" == "" ]; then
68                 return 0
69         else
70                 return 1
71         fi
72 }
73
74 argcommand=""
75 for option in $@; do
76         if ( ! startswithmm $option ); then
77                 if [ "x$argcommand" == "xinstall-root" ]; then
78                         InstallRoot=$option
79                 elif [ "x$argcommand" == "xrpm-archives" ]; then
80                         RPMArchives=$option
81                 elif [ "x$argcommand" == "xinstall-packages" ]; then
82                         if [ "x$installpackages" == "x" ]; then
83                                 installpackages=$option
84                         else
85                                 installpackages="$installpackages $option"
86                         fi
87                 fi
88         else
89                 if ( containsequals $option ); then
90                         argcommand=${option%%=*}
91                         argcommand=${argcommand##--}
92                         option=${option##*=}
93
94                         if [ "x$argcommand" == "xinstall-root" ]; then
95                                 InstallRoot=$option
96                         elif [ "x$argcommand" == "xrpm-archives" ]; then
97                                 RPMArchives=$option
98                         elif [ "x$argcommand" == "xinstall-packages" ]; then
99                                 installpackages=$option
100                         else
101                                 echo "Unknown option $option"
102                                 exit 1
103                         fi
104                 else
105                         if [ "x$option" == "x--help" ]; then
106                                 displayHelp 0
107                         elif [ "x$option" == "x--install-root" ]; then
108                                 argcommand=${option##--}
109                         elif [ "x$option" == "x--rpm-archives" ]; then
110                                 argcommand=${option##--}
111                         elif [ "x$option" == "x--install-packages" ]; then
112                                 argcommand=${option##--}
113                                 installpackages=""
114                         else
115                                 echo "Unknown option $option"
116                                 exit 1
117                         fi
118                 fi
119         fi
120 done
121
122 echo "Install Packages: $installpackages"
123 echo "RPMArchives     : $RPMArchives"
124 echo "InstallRoot     : $InstallRoot"
125
126 function buildcache() {
127         cd $RPMArchives
128
129         for file in *.{noarch,$architecture}.rpm; do
130                 rpm -qpl $file | sed 's#^#'$file':#' >> $ourcachedirectory/files-cache
131                 rpm -qp --provides $file | cut -d " " -f 1 | sed 's#^#'$file':#' >> $ourcachedirectory/package-cache
132         done
133 }
134
135 function findrpm() {
136         name=$1
137         if [ -z $name ]; then
138                 return
139         fi
140         cd $RPMArchives
141
142         escapename=$(echo $name | sed -e 's#\+#\\+#g; s#\.#\\.#g; s#(#\\(#g; s#)#\\)#g;')
143
144         if [ ${name:0:1} == "/" ]; then
145                 grep -E "^.*:$escapename\$" $ourcachedirectory/files-cache | cut -d ":" -f 1 | head -n 1
146         else
147                 grep -E "^.*:$escapename\$" $ourcachedirectory/package-cache | cut -d ":" -f 1 | head -n 1
148         fi
149 }
150
151 function getdependencies() {
152         filename=$1
153         name=$2
154
155         rpm -qp --requires ${RPMArchives}/$filename | grep -v '^.*('$name')' | cut -d " " -f 1 | sort | uniq | grep -Ev '^[     ]*$' | while read line; do
156                 if [ ! -z $line ]; then
157                         fname=$(findrpm $line)
158                         packagename=$(getpackagename $fname)
159                         if [ ! -z $name ] && [ ! -z $packagename ]; then
160                                 if [[ $firstpackage == 0 ]]; then
161                                         if ( ! grep '^'$fname' ' $ourcachedirectory/build-packagelist > /dev/null ) && ( ! rpm -r ${InstallRoot} -qv $packagename > /dev/null ); then
162                                                 echo $fname $packagename >> $ourcachedirectory/build-packagelist
163                                                 getdependencies $fname $packagename
164                                         fi
165                                 else
166                                         if ( ! grep '^'$fname' ' $ourcachedirectory/build-packagelist > /dev/null ); then
167                                                 echo $fname $packagename >> $ourcachedirectory/build-packagelist
168                                                 getdependencies $fname $packagename
169                                         fi
170                                 fi
171                         fi
172                 fi
173         done
174 }
175
176 function getpackagename() {
177         filename=$1
178         if [ ! -z $filename ]; then
179                 rpm -qp --queryformat "%{NAME}\n" ${RPMArchives}/$filename
180         fi
181 }
182
183 cd ${InstallRoot}
184 mkdir -p var/lib/rpm
185 mkdir root
186 mkdir etc
187 mkdir usr
188 mkdir dev
189 cp /etc/resolv.conf etc/
190 mknod -m 666 dev/null c 1 3
191 touch etc/fstab
192
193 buildcache
194
195 rpm -r ${InstallRoot} --initdb
196
197 firstpackage=1
198
199 for package in $installpackages; do
200         
201         rm -f $ourcachedirectory/build-packagelist
202         touch $ourcachedirectory/build-packagelist
203
204         echo "Installing packages required for $package"
205         
206         if [[ "x$(findrpm $package)" != "x" ]]; then
207                 
208                 getdependencies $(findrpm $package) $package
209                 echo " RPM File    :" $(findrpm $package)
210                 echo " Dependencies:"
211                 cat $ourcachedirectory/build-packagelist | cut -d ' ' -f 2 | sed -e 's#^#  #;'
212                 
213                 echo rpm -r ${InstallRoot} --ignorearch --install $(cat $ourcachedirectory/build-packagelist | cut -d ' ' -f 1) >> $ourcachedirectory/install-log
214
215                 firstpackage=0
216                 
217                 cd ${RPMArchives} && rpm -r ${InstallRoot} --ignorearch --install $(cat $ourcachedirectory/build-packagelist | cut -d ' ' -f 1)
218                 if ( ! grep " $package\$" $ourcachedirectory/build-packagelist > /dev/null 2>/dev/null ); then
219                         echo rpm -r ${InstallRoot} --ignorearch --install $(findrpm $package) >> $ourcachedirectory/install-log
220                         cd ${RPMArchives} && rpm -r ${InstallRoot} --ignorearch --install $(findrpm $package)
221                 fi
222         else
223                 echo " Failed to find the RPM providing $package - skipping"
224         fi
225 done
226
227 read -p "Remove cache directory ($ourcachedirectory)? [Yn]: " cleanup
228
229 cleanup=${cleanup:0:1}
230
231 if [ "$cleanup" == "N" ] || [ "$cleanup" == "n" ] ; then
232         echo leaving logs in $ourcachedirectory
233 else
234         echo removing logs directory
235         rm -r $ourcachedirectory
236 fi