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