Fix for olllllld bash
[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 function displayHelp() {
35 cat <<END
36 Usage: $0 [options]
37
38 Options:
39         --install-root <directorytoinstallto>
40         --rpm-archives <pathtorpms>
41         --install-packages <listofpackagestoinstall>
42 END
43         exit $1
44 }
45
46 function startswithmm() {
47         if [ "${1##--*}" == "" ]; then
48                 return 0
49         else
50                 return 1
51         fi
52 }
53
54 function containsequals() {
55         if [ "${1//*=*}" == "" ]; then
56                 return 0
57         else
58                 return 1
59         fi
60 }
61
62 argcommand=""
63 for option in $@; do
64         if ( ! startswithmm $option ); then
65                 if [ "x$argcommand" == "xinstall-root" ]; then
66                         InstallRoot=$option
67                 elif [ "x$argcommand" == "xrpm-archives" ]; then
68                         RPMArchives=$option
69                 elif [ "x$argcommand" == "xinstall-packages" ]; then
70                         if [ "x$installpackages" == "x" ]; then
71                                 installpackages=$option
72                         else
73                                 installpackages="$installpackages $option"
74                         fi
75                 fi
76         else
77                 if ( containsequals $option ); then
78                         argcommand=${option%%=*}
79                         argcommand=${argcommand##--}
80                         option=${option##*=}
81
82                         if [ "x$argcommand" == "xinstall-root" ]; then
83                                 InstallRoot=$option
84                         elif [ "x$argcommand" == "xrpm-archives" ]; then
85                                 RPMArchives=$option
86                         elif [ "x$argcommand" == "xinstall-packages" ]; then
87                                 installpackages=$option
88                         else
89                                 echo "Unknown option $option"
90                                 exit 1
91                         fi
92                 else
93                         if [ "x$option" == "x--help" ]; then
94                                 displayHelp 0
95                         elif [ "x$option" == "x--install-root" ]; then
96                                 argcommand=${option##--}
97                         elif [ "x$option" == "x--rpm-archives" ]; then
98                                 argcommand=${option##--}
99                         elif [ "x$option" == "x--install-packages" ]; then
100                                 argcommand=${option##--}
101                                 installpackages=""
102                         else
103                                 echo "Unknown option $option"
104                                 exit 1
105                         fi
106                 fi
107         fi
108 done
109
110 echo "Install Packages: $installpackages"
111 echo "RPMArchives     : $RPMArchives"
112 echo "InstallRoot     : $InstallRoot"
113
114 function buildcache() {
115         cd $RPMArchives
116
117         for file in *.{noarch,$architecture}.rpm; do
118                 rpm -qpl $file | sed 's#^#'$file':#' >> $ourcachedirectory/files-cache
119                 rpm -qp --provides $file | cut -d " " -f 1 | sed 's#^#'$file':#' >> $ourcachedirectory/package-cache
120         done
121 }
122
123 function findrpm() {
124         name=$1
125         if [ -z $name ]; then
126                 return
127         fi
128         cd $RPMArchives
129
130         escapename=$(echo $name | sed -e 's#\+#\\+#g; s#\.#\\.#g; s#(#\\(#g; s#)#\\)#g;')
131
132         if [ ${name:0:1} == "/" ]; then
133                 grep -E "^.*:$escapename\$" $ourcachedirectory/files-cache | cut -d ":" -f 1 | head -n 1
134         else
135                 grep -E "^.*:$escapename\$" $ourcachedirectory/package-cache | cut -d ":" -f 1 | head -n 1
136         fi
137 }
138
139 function getdependencies() {
140         filename=$1
141         name=$2
142
143         rpm -qp --requires ${RPMArchives}/$filename | grep -v '^.*('$name')' | cut -d " " -f 1 | sort | uniq | grep -Ev '^[     ]*$' | while read line; do
144                 if [ ! -z $line ]; then
145                         fname=$(findrpm $line)
146                         packagename=$(getpackagename $fname)
147                         if [ ! -z $name ] && [ ! -z $packagename ]; then
148                                 if [[ $firstpackage == 0 ]]; then
149                                         if ( ! grep '^'$fname' ' $ourcachedirectory/build-packagelist > /dev/null ) && ( ! rpm -r ${InstallRoot} -qv $packagename > /dev/null ); then
150                                                 echo $fname $packagename >> $ourcachedirectory/build-packagelist
151                                                 getdependencies $fname $packagename
152                                         fi
153                                 else
154                                         if ( ! grep '^'$fname' ' $ourcachedirectory/build-packagelist > /dev/null ); then
155                                                 echo $fname $packagename >> $ourcachedirectory/build-packagelist
156                                                 getdependencies $fname $packagename
157                                         fi
158                                 fi
159                         fi
160                 fi
161         done
162 }
163
164 function getpackagename() {
165         filename=$1
166         if [ ! -z $filename ]; then
167                 rpm -qp --queryformat "%{NAME}\n" ${RPMArchives}/$filename
168         fi
169 }
170
171 cd ${InstallRoot}
172 mkdir -p var/lib/rpm
173 mkdir root
174 mkdir etc
175 mkdir usr
176 mkdir dev
177 cp /etc/resolv.conf etc/
178 mknod -m 666 dev/null c 1 3
179 touch etc/fstab
180
181 buildcache
182
183 rpm -r ${InstallRoot} --initdb
184
185 firstpackage=1
186
187 for package in $installpackages; do
188         
189         rm -f $ourcachedirectory/build-packagelist
190         touch $ourcachedirectory/build-packagelist
191
192         echo "Installing packages required for $package"
193         
194         if [[ "x$(findrpm $package)" != "x" ]]; then
195                 
196                 getdependencies $(findrpm $package) $package
197                 echo " RPM File    :" $(findrpm $package)
198                 echo " Dependencies:"
199                 cat $ourcachedirectory/build-packagelist | cut -d ' ' -f 2 | sed -e 's#^#  #;'
200                 
201                 echo rpm -r ${InstallRoot} --ignorearch --install $(cat $ourcachedirectory/build-packagelist | cut -d ' ' -f 1) >> $ourcachedirectory/install-log
202
203                 firstpackage=0
204                 
205                 cd ${RPMArchives} && rpm -r ${InstallRoot} --ignorearch --install $(cat $ourcachedirectory/build-packagelist | cut -d ' ' -f 1)
206                 if ( ! grep " $package\$" $ourcachedirectory/build-packagelist > /dev/null 2>/dev/null ); then
207                         echo rpm -r ${InstallRoot} --ignorearch --install $(findrpm $package) >> $ourcachedirectory/install-log
208                         cd ${RPMArchives} && rpm -r ${InstallRoot} --ignorearch --install $(findrpm $package)
209                 fi
210         else
211                 echo " Failed to find the RPM providing $package - skipping"
212         fi
213 done
214
215 read -p "Remove cache directory ($ourcachedirectory)? [Yn]: " cleanup
216
217 cleanup=${cleanup:0:1}
218
219 if [ "$cleanup" == "N" ] || [ "$cleanup" == "n" ] ; then
220         echo leaving logs in $ourcachedirectory
221 else
222         echo removing logs directory
223         rm -r $ourcachedirectory
224 fi