Create device nodes.
[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: \
23         --long groupinstall:,group-install:,help,install: \
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 usage ()
36 {
37     echo "Usage: febootstrap [--options] REPO TARGET [MIRROR]"
38     echo "Please read febootstrap(8) man page for more information."
39 }
40
41 while true; do
42     case "$1" in
43         -i|--install)
44             packages[i++]="$2"
45             shift 2;;
46         --groupinstall|--group-install)
47             packages[i++]="@$2"
48             shift 2;;
49         --help)
50             usage
51             exit 0;;
52         --)
53             shift
54             break;;
55         *)
56             echo "Internal error!"
57             exit 1;;
58     esac
59 done
60
61 if [ $# -lt 2 -o $# -gt 3 ]; then
62     usage
63     exit 1
64 fi
65
66 repo="$1"
67 target="$2"
68 mirror="$3"
69
70 # Architecture is currently always the same as the current arch.  We
71 # cannot do --foreign builds.  See discussion in the manpage.
72 arch=$(arch)
73
74 # Create a temporary directory, make sure it gets cleaned up at the end.
75 tmpdir=$(mktemp -d)
76 remove_tmpdir ()
77 {
78   status=$?
79   rm -rf "$tmpdir" && exit $status
80 }
81 trap remove_tmpdir EXIT
82
83 # Create the temporary repository configuration.  The name of the
84 # repository is always 'febootstrap'.
85 cat > $tmpdir/febootstrap.repo <<__EOF__
86 [febootstrap]
87 name=febootstrap $repo $arch
88 failovermethod=priority
89 enabled=1
90 gpgcheck=0
91 __EOF__
92
93 # "Mirror" parameter is a bit misnamed, but it means a local mirror,
94 # instead of the public Fedora mirrors.
95 if [ -n "$mirror" ]; then
96     echo "baseurl=$mirror" >> "$tmpdir"/febootstrap.repo
97 else
98     echo "mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=$repo&arch=$arch" >> "$tmpdir"/febootstrap.repo
99 fi
100
101 # Create the target filesystem.
102 rm -rf "$target"
103 mkdir "$target"
104
105 # Target must be an absolute path.
106 target=$(cd "$target"; pwd)
107
108 # This is necessary to keep yum happy.  It's not clear why yum can't
109 # just create this file itself.
110 mkdir -p "$target"/var/cache/yum/febootstrap/packages
111
112 # Make the device nodes inside the fake chroot.
113 # (Copied from mock/backend.py)  Why isn't there a base package which
114 # creates these?
115 make_device_nodes ()
116 {
117     mkdir "$target"/dev
118     (
119         cd "$target"/dev
120         mkdir pts
121         mkdir shm
122         mknod null c 1 3;    chmod 0666 null
123         mknod full c 1 7;    chmod 0666 full
124         mknod zero c 1 5;    chmod 0666 zero
125         mknod random c 1 8;  chmod 0666 random
126         mknod urandom c 1 9; chmod 0444 urandom
127         mknod tty c 5 0;     chmod 0666 tty
128         mknod console c 5 1; chmod 0600 console
129         mknod ptmx c 5 2;    chmod 0666 ptmx
130         ln -sf /proc/self/fd/0 stdin
131         ln -sf /proc/self/fd/1 stdout
132         ln -sf /proc/self/fd/2 stderr
133     )
134 }
135 export -f make_device_nodes
136 export target
137
138 if [ $(id -u) -ne 0 ]; then
139     fakeroot -s "$target"/fakeroot.log \
140     make_device_nodes
141 else
142     make_device_nodes
143 fi
144
145 # Run yum.
146 run_yum ()
147 {
148     yum \
149         -y -c "$tmpdir"/febootstrap.repo \
150         --disablerepo=* --enablerepo=febootstrap \
151         --noplugins --nogpgcheck \
152         --installroot="$target" \
153         install "$@"
154 }
155 export -f run_yum
156 export tmpdir
157
158 if [ $(id -u) -ne 0 ]; then
159     # Bash doesn't support exporting array variables, hence this
160     # tortuous workaround.
161     fakeroot -i "$target"/fakeroot.log -s "$target"/fakeroot.log \
162     fakechroot -s \
163     bash -c 'run_yum "$@"' run_yum "${packages[@]}"
164 else
165     run_yum "${packages[@]}"
166 fi