Don't print output of 'cd' (Ján ONDREJ (SAL)).
[febootstrap.git] / febootstrap.sh
1 #!/bin/bash -
2 # febootstrap
3 # (C) Copyright 2009 Red Hat Inc.
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 #
19 # Written by Richard W.M. Jones <rjones@redhat.com>
20
21 TEMP=`getopt \
22         -o g:i:p:u: \
23         --long groupinstall:,group-install:,help,install:,noclean,no-clean,proxy:,updates: \
24         -n febootstrap -- "$@"`
25 if [ $? != 0 ]; then
26     echo "febootstrap: problem parsing the command line arguments"
27     exit 1
28 fi
29 eval set -- "$TEMP"
30
31 declare -a packages
32 packages[0]="@Core"
33 i=0
34
35 clean=yes
36
37 usage ()
38 {
39     echo "Usage: febootstrap [--options] REPO TARGET [MIRROR]"
40     echo "Please read febootstrap(8) man page for more information."
41 }
42
43 while true; do
44     case "$1" in
45         -i|--install)
46             packages[i++]="$2"
47             shift 2;;
48         --groupinstall|--group-install)
49             packages[i++]="@$2"
50             shift 2;;
51         -p|--proxy)
52             proxy="proxy=$2"
53             shift 2;;
54         -u|--updates)
55             updates="$2";
56             shift 2;;
57         --noclean|--no-clean)
58             clean=no
59             shift;;
60         --help)
61             usage
62             exit 0;;
63         --)
64             shift
65             break;;
66         *)
67             echo "Internal error!"
68             exit 1;;
69     esac
70 done
71
72 if [ $# -lt 2 -o $# -gt 3 ]; then
73     usage
74     exit 1
75 fi
76
77 repo="$1"
78 target="$2"
79 mirror="$3"
80
81 # Architecture is currently always the same as the current arch.  We
82 # cannot do --foreign builds.  See discussion in the manpage.
83 arch=$(arch)
84 case $arch in
85     i?86) arch=i386 ;;
86 esac
87
88 # Create a temporary directory, make sure it gets cleaned up at the end.
89 tmpdir=$(mktemp -d)
90 remove_tmpdir ()
91 {
92   status=$?
93   rm -rf "$tmpdir" && exit $status
94 }
95 trap remove_tmpdir EXIT
96
97 # Create the temporary repository configuration.  The name of the
98 # repository is always 'febootstrap'.
99 cat > $tmpdir/febootstrap.repo <<__EOF__
100 [febootstrap]
101 name=febootstrap $repo $arch
102 failovermethod=priority
103 enabled=1
104 gpgcheck=0
105 $proxy
106 __EOF__
107
108 # "Mirror" parameter is a bit misnamed, but it means a local mirror,
109 # instead of the public Fedora mirrors.
110 if [ -n "$mirror" ]; then
111     echo "baseurl=$mirror" >> "$tmpdir"/febootstrap.repo
112 else
113     echo "mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=$repo&arch=$arch" >> "$tmpdir"/febootstrap.repo
114 fi
115
116 # Add the updates repository if asked.
117 case "$updates" in
118     none|no)
119         ;;
120     *://*)
121         cat >> $tmpdir/febootstrap.repo <<EOF
122
123 [febootstrap-updates]
124 name=febootstrap updates $arch
125 failovermethod=priority
126 enabled=1
127 gpgcheck=0
128 $proxy
129 baseurl=$updates
130 EOF
131         ;;
132     *)
133         cat >> $tmpdir/febootstrap.repo <<EOF
134
135 [febootstrap-updates]
136 name=febootstrap $updates $arch
137 failovermethod=priority
138 enabled=1
139 gpgcheck=0
140 $proxy
141 mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=$updates&arch=$arch
142 EOF
143         ;;
144 esac
145
146 # Create the target filesystem.
147 rm -rf "$target"
148 mkdir "$target"
149
150 # Target must be an absolute path.
151 target=$(cd "$target" > /dev/null; pwd)
152
153 # This is necessary to keep yum happy.  It's not clear why yum can't
154 # just create this file itself.
155 mkdir -p "$target"/var/cache/yum/febootstrap/packages
156
157 # NB: REQUIRED for useradd/groupadd to run properly.
158 #
159 # However this causes 'filesystem' RPM install to give the
160 # following error.  Not sure how serious the error is:
161 # error: unpacking of archive failed on file /proc: cpio: utime
162 export FAKECHROOT_EXCLUDE_PATH=/proc
163
164 # Substitute some statically-linked commands.  This is only supported
165 # in fakechroot > 2.9.  For previous versions of fakechroot it is
166 # ignored.
167 export FAKECHROOT_CMD_SUBST=/sbin/ldconfig=/bin/true:/usr/sbin/glibc_post_upgrade.i686=/bin/true:/usr/sbin/glibc_post_upgrade.x86_64=/bin/true:/usr/sbin/build-locale-archive=/bin/true:/usr/sbin/libgcc_post_upgrade=/bin/true
168
169 # Make the device nodes inside the fake chroot.
170 # (Copied from mock/backend.py)  Why isn't there a base package which
171 # creates these?
172 make_device_nodes ()
173 {
174     mkdir "$target"/proc
175     mkdir "$target"/sys
176     mkdir "$target"/dev
177     (
178         cd "$target"/dev
179         mkdir pts
180         mkdir shm
181         mkdir mapper
182         mknod null c 1 3;    chmod 0666 null
183         mknod full c 1 7;    chmod 0666 full
184         mknod zero c 1 5;    chmod 0666 zero
185         mknod random c 1 8;  chmod 0666 random
186         mknod urandom c 1 9; chmod 0444 urandom
187         mknod tty c 5 0;     chmod 0666 tty
188         mknod console c 5 1; chmod 0600 console
189         mknod ptmx c 5 2;    chmod 0666 ptmx
190         ln -sf /proc/self/fd/0 stdin
191         ln -sf /proc/self/fd/1 stdout
192         ln -sf /proc/self/fd/2 stderr
193     )
194 }
195 export -f make_device_nodes
196 export target
197
198 if [ $(id -u) -ne 0 ]; then
199     fakeroot -s "$target"/fakeroot.log \
200     make_device_nodes
201 else
202     make_device_nodes
203 fi
204
205 # Run yum.
206 run_yum ()
207 {
208     yum \
209         -y -c "$tmpdir"/febootstrap.repo \
210         --disablerepo=* --enablerepo=febootstrap \
211         --noplugins --nogpgcheck \
212         --installroot="$target" \
213         install "$@"
214 }
215 export -f run_yum
216 export tmpdir
217
218 if [ $(id -u) -ne 0 ]; then
219     # Bash doesn't support exporting array variables, hence this
220     # tortuous workaround.
221     fakeroot -i "$target"/fakeroot.log -s "$target"/fakeroot.log \
222     fakechroot -s \
223     bash -c 'run_yum "$@"' run_yum "${packages[@]}"
224 else
225     run_yum "${packages[@]}"
226 fi
227
228 # Clean up the yum repository.
229 if [ "$clean" = "yes" ]; then
230     rm -rf "$target"/var/cache/yum/febootstrap
231 fi