root / devel / build_chroot @ 33ead7a7
History | View | Annotate | Download (12.9 kB)
1 |
#!/bin/bash |
---|---|
2 |
#Configuration |
3 |
: ${ARCH:=amd64} |
4 |
: ${DIST_RELEASE:=squeeze} |
5 |
: ${CONF_DIR:=/etc/schroot/chroot.d} |
6 |
: ${CHROOT_DIR:=/srv/chroot} |
7 |
: ${ALTERNATIVE_EDITOR:=/usr/bin/vim.basic} |
8 |
: ${CHROOT_FINAL_HOOK:=/bin/true} |
9 |
# Additional Variables taken from the environmen |
10 |
# DATA_DIR |
11 |
# CHROOT_EXTRA_DEBIAN_PACKAGES |
12 |
|
13 |
#Automatically generated variables |
14 |
CHROOTNAME=$DIST_RELEASE-$ARCH |
15 |
CHNAME=building_$CHROOTNAME |
16 |
TEMP_CHROOT_CONF=$CONF_DIR/$CHNAME.conf |
17 |
FINAL_CHROOT_CONF=$CHROOTNAME.conf |
18 |
ROOT=`pwd` |
19 |
CHDIR=$ROOT/$CHNAME |
20 |
USER=`whoami` |
21 |
COMP_FILENAME=$CHROOTNAME.tar.gz |
22 |
COMP_FILEPATH=$ROOT/$COMP_FILENAME |
23 |
TEMP_DATA_DIR=`mktemp -d` |
24 |
ACTUAL_DATA_DIR=$DATA_DIR |
25 |
ACTUAL_DATA_DIR=${ACTUAL_DATA_DIR:-$TEMP_DATA_DIR} |
26 |
GHC_VERSION="7.6.3" |
27 |
CABAL_INSTALL_VERSION="1.18.0.2" |
28 |
SHA1_LIST=' |
29 |
cabal-install-1.18.0.2.tar.gz 2d1f7a48d17b1e02a1e67584a889b2ff4176a773 |
30 |
ghc-7.6.3-i386-unknown-linux.tar.bz2 f042b4171a2d4745137f2e425e6949c185f8ea14 |
31 |
ghc-7.6.3-x86_64-unknown-linux.tar.bz2 46ec3f3352ff57fba0dcbc8d9c20f7bcb6924b77 |
32 |
' |
33 |
|
34 |
# export all variables needed in the schroot |
35 |
export ARCH GHC_VERSION CABAL_INSTALL_VERSION SHA1_LIST |
36 |
|
37 |
# Use gzip --rsyncable if available, to speed up transfers of generated files |
38 |
# The environment variable GZIP is read automatically by 'gzip', |
39 |
# see ENVIRONMENT in gzip(1). |
40 |
gzip --rsyncable </dev/null >/dev/null 2>&1 && export GZIP="--rsyncable" |
41 |
|
42 |
#Runnability checks |
43 |
if [ $USER != 'root' ] |
44 |
then |
45 |
echo "This script requires root permissions to run" |
46 |
exit |
47 |
fi |
48 |
|
49 |
if [ -f $TEMP_CHROOT_CONF ] |
50 |
then |
51 |
echo "The configuration file name for the temporary chroot" |
52 |
echo " $TEMP_CHROOT_CONF" |
53 |
echo "already exists." |
54 |
echo "Remove it or change the CHNAME value in the script." |
55 |
exit |
56 |
fi |
57 |
|
58 |
#Create configuration dir and files if they do not exist |
59 |
if [ ! -d $ACTUAL_DATA_DIR ] |
60 |
then |
61 |
mkdir $ACTUAL_DATA_DIR |
62 |
echo "The data directory" |
63 |
echo " $ACTUAL_DATA_DIR" |
64 |
echo "has been created." |
65 |
fi |
66 |
|
67 |
if [ ! -f $ACTUAL_DATA_DIR/final.schroot.conf.in ] |
68 |
then |
69 |
cat <<END >$ACTUAL_DATA_DIR/final.schroot.conf.in |
70 |
[${CHROOTNAME}] |
71 |
description=Debian ${DIST_RELEASE} ${ARCH} |
72 |
groups=src |
73 |
source-root-groups=root |
74 |
type=file |
75 |
file=${CHROOT_DIR}/${COMP_FILENAME} |
76 |
END |
77 |
echo "The file" |
78 |
echo " $ACTUAL_DATA_DIR/final.schroot.conf.in" |
79 |
echo "has been created with default configurations." |
80 |
fi |
81 |
|
82 |
if [ ! -f $ACTUAL_DATA_DIR/temp.schroot.conf.in ] |
83 |
then |
84 |
cat <<END >$ACTUAL_DATA_DIR/temp.schroot.conf.in |
85 |
[${CHNAME}] |
86 |
description=Debian ${DIST_RELEASE} ${ARCH} |
87 |
directory=${CHDIR} |
88 |
groups=src |
89 |
users=root |
90 |
type=directory |
91 |
END |
92 |
echo "The file" |
93 |
echo " $ACTUAL_DATA_DIR/temp.schroot.conf.in" |
94 |
echo "has been created with default configurations." |
95 |
fi |
96 |
|
97 |
#Stop on errors |
98 |
set -e |
99 |
|
100 |
#Cleanup |
101 |
rm -rf $CHDIR |
102 |
mkdir $CHDIR |
103 |
|
104 |
#Install tools for building chroots |
105 |
apt-get install -y schroot debootstrap |
106 |
|
107 |
shopt -s expand_aliases |
108 |
alias in_chroot='schroot -c $CHNAME -d / ' |
109 |
function subst_variables { |
110 |
sed \ |
111 |
-e "s/\${ARCH}/$ARCH/" \ |
112 |
-e "s*\${CHDIR}*$CHDIR*" \ |
113 |
-e "s/\${CHNAME}/$CHNAME/" \ |
114 |
-e "s/\${CHROOTNAME}/$CHROOTNAME/" \ |
115 |
-e "s*\${CHROOT_DIR}*$CHROOT_DIR*" \ |
116 |
-e "s/\${COMP_FILENAME}/$COMP_FILENAME/" \ |
117 |
-e "s/\${DIST_RELEASE}/$DIST_RELEASE/" $@ |
118 |
} |
119 |
|
120 |
#Generate chroot configurations |
121 |
cat $ACTUAL_DATA_DIR/temp.schroot.conf.in | subst_variables > $TEMP_CHROOT_CONF |
122 |
cat $ACTUAL_DATA_DIR/final.schroot.conf.in | subst_variables > $FINAL_CHROOT_CONF |
123 |
|
124 |
#Install the base system |
125 |
debootstrap --arch $ARCH $DIST_RELEASE $CHDIR |
126 |
|
127 |
APT_INSTALL="apt-get install -y --no-install-recommends" |
128 |
|
129 |
if [ DIST_RELEASE = squeeze ] |
130 |
then |
131 |
echo "deb http://backports.debian.org/debian-backports" \ |
132 |
"$DIST_RELEASE-backports main contrib non-free" \ |
133 |
> $CHDIR/etc/apt/sources.list.d/backports.list |
134 |
fi |
135 |
|
136 |
#Install all the packages |
137 |
in_chroot -- \ |
138 |
apt-get update |
139 |
|
140 |
# arguments : file_name expected_sha1 |
141 |
function verify_sha1 { |
142 |
local SUM="$( sha1sum "$1" | awk '{print $1;exit}' )" |
143 |
if [ "$SUM" != "$2" ] ; then |
144 |
echo "ERROR: The SHA1 sum $SUM of $1 doesn't match $2." >&2 |
145 |
return 1 |
146 |
else |
147 |
echo "SHA1 of $1 verified correct." |
148 |
fi |
149 |
} |
150 |
export -f verify_sha1 |
151 |
|
152 |
# arguments: URL |
153 |
function lookup_sha1 { |
154 |
grep -o "${1##*/}"'\s\+[0-9a-fA-F]*' <<<"$SHA1_LIST" | awk '{print $2;exit}' |
155 |
} |
156 |
export -f lookup_sha1 |
157 |
|
158 |
# arguments : file_name URL |
159 |
function download { |
160 |
local FNAME="$1" |
161 |
local URL="$2" |
162 |
wget --output-document="$FNAME" "$URL" |
163 |
verify_sha1 "$FNAME" "$( lookup_sha1 "$URL" )" |
164 |
} |
165 |
export -f download |
166 |
|
167 |
function install_ghc { |
168 |
set -e |
169 |
local TDIR=$( mktemp -d ) ; |
170 |
pushd "$TDIR" |
171 |
{ |
172 |
local GHC_ARCH=$ARCH |
173 |
if [ "$ARCH" == "amd64" ] ; then |
174 |
download ghc.tar.bz2 \ |
175 |
http://www.haskell.org/ghc/dist/${GHC_VERSION}/ghc-${GHC_VERSION}-x86_64-unknown-linux.tar.bz2 |
176 |
elif [ "$ARCH" == "i386" ] ; then |
177 |
download ghc.tar.bz2 \ |
178 |
http://www.haskell.org/ghc/dist/${GHC_VERSION}/ghc-${GHC_VERSION}-i386-unknown-linux.tar.bz2 |
179 |
else |
180 |
echo "Don't know what GHC to download for architecture $ARCH" >&2 |
181 |
return 1 |
182 |
fi |
183 |
tar xjf ghc.tar.bz2 |
184 |
cd ghc-${GHC_VERSION} |
185 |
./configure --prefix=/usr/local |
186 |
make install |
187 |
} |
188 |
popd |
189 |
[ -d "$TDIR" ] && rm -rf "$TDIR" |
190 |
} |
191 |
# export everything so that the function can be called in a sub-shell |
192 |
export -f install_ghc |
193 |
|
194 |
function install_cabal { |
195 |
set -e |
196 |
local TDIR=$( mktemp -d ) |
197 |
pushd "$TDIR" |
198 |
{ |
199 |
download cabal-install.tar.gz \ |
200 |
http://www.haskell.org/cabal/release/cabal-install-${CABAL_INSTALL_VERSION}/cabal-install-${CABAL_INSTALL_VERSION}.tar.gz |
201 |
tar xzf cabal-install.tar.gz |
202 |
cd cabal-install-${CABAL_INSTALL_VERSION} |
203 |
./bootstrap.sh --global |
204 |
} |
205 |
popd |
206 |
[ -d "$TDIR" ] && rm -rf "$TDIR" |
207 |
} |
208 |
# export everything so that the function can be called in a sub-shell |
209 |
export -f install_cabal |
210 |
|
211 |
case $DIST_RELEASE in |
212 |
|
213 |
squeeze) |
214 |
|
215 |
# do not install libghc6-network-dev, since it's too old, and just |
216 |
# confuses the dependencies |
217 |
in_chroot -- \ |
218 |
$APT_INSTALL \ |
219 |
autoconf automake \ |
220 |
zlib1g-dev \ |
221 |
libgmp3-dev \ |
222 |
libcurl4-gnutls-dev \ |
223 |
libpcre3-dev \ |
224 |
happy \ |
225 |
hlint hscolour pandoc \ |
226 |
graphviz qemu-utils \ |
227 |
python-docutils \ |
228 |
python-simplejson \ |
229 |
python-pyparsing \ |
230 |
python-pyinotify \ |
231 |
python-pycurl \ |
232 |
python-ipaddr \ |
233 |
python-yaml \ |
234 |
python-paramiko |
235 |
|
236 |
in_chroot -- \ |
237 |
$APT_INSTALL python-setuptools python-dev build-essential |
238 |
|
239 |
in_chroot -- \ |
240 |
easy_install \ |
241 |
logilab-astng==0.24.1 \ |
242 |
logilab-common==0.58.3 \ |
243 |
mock==1.0.1 \ |
244 |
pylint==0.26.0 |
245 |
|
246 |
in_chroot -- \ |
247 |
easy_install \ |
248 |
sphinx==1.1.3 \ |
249 |
pep8==1.3.3 \ |
250 |
coverage==3.4 \ |
251 |
bitarray==0.8.0 |
252 |
|
253 |
in_chroot -p -- \ |
254 |
bash -c install_ghc |
255 |
|
256 |
in_chroot -p -- \ |
257 |
bash -c install_cabal |
258 |
|
259 |
in_chroot -- \ |
260 |
cabal update |
261 |
|
262 |
in_chroot -- \ |
263 |
cabal install --global \ |
264 |
attoparsec-0.11.1.0 \ |
265 |
base64-bytestring-1.0.0.1 \ |
266 |
blaze-builder-0.3.3.2 \ |
267 |
case-insensitive-1.1.0.3 \ |
268 |
Crypto-4.2.5.1 \ |
269 |
curl-1.3.8 \ |
270 |
happy \ |
271 |
hashable-1.2.1.0 \ |
272 |
hinotify-0.3.6 \ |
273 |
hscolour-1.20.3 \ |
274 |
hslogger-1.2.3 \ |
275 |
json-0.7 \ |
276 |
lifted-base-0.2.2.0 \ |
277 |
MonadCatchIO-transformers-0.3.0.0 \ |
278 |
network-2.4.1.2 \ |
279 |
parallel-3.2.0.4 \ |
280 |
parsec-3.1.3 \ |
281 |
regex-pcre-0.94.4 \ |
282 |
temporary-1.2.0.1 \ |
283 |
vector-0.10.9.1 \ |
284 |
zlib-0.5.4.1 \ |
285 |
\ |
286 |
hlint-1.8.57 \ |
287 |
HUnit-1.2.5.2 \ |
288 |
QuickCheck-2.6 \ |
289 |
test-framework-0.8.0.3 \ |
290 |
test-framework-hunit-0.3.0.1 \ |
291 |
test-framework-quickcheck2-0.3.0.2 \ |
292 |
\ |
293 |
snap-server-0.9.4.0 \ |
294 |
\ |
295 |
cabal-file-th-0.2.3 \ |
296 |
shelltestrunner |
297 |
|
298 |
#Install selected packages from backports |
299 |
in_chroot -- \ |
300 |
$APT_INSTALL -t squeeze-backports \ |
301 |
git \ |
302 |
git-email \ |
303 |
vim |
304 |
|
305 |
;; |
306 |
|
307 |
wheezy) |
308 |
|
309 |
in_chroot -- \ |
310 |
$APT_INSTALL \ |
311 |
autoconf automake ghc ghc-haddock libghc-network-dev \ |
312 |
libghc-test-framework{,-hunit,-quickcheck2}-dev \ |
313 |
libghc-json-dev libghc-curl-dev libghc-hinotify-dev \ |
314 |
libghc-parallel-dev libghc-utf8-string-dev \ |
315 |
libghc-hslogger-dev libghc-crypto-dev \ |
316 |
libghc-regex-pcre-dev libghc-attoparsec-dev \ |
317 |
libghc-vector-dev libghc-temporary-dev \ |
318 |
libghc-snap-server-dev libpcre3 libpcre3-dev hscolour hlint pandoc \ |
319 |
libghc-zlib-dev \ |
320 |
cabal-install \ |
321 |
python-setuptools python-sphinx python-epydoc graphviz python-pyparsing \ |
322 |
python-simplejson python-pycurl python-paramiko \ |
323 |
python-bitarray python-ipaddr python-yaml qemu-utils python-coverage pep8 \ |
324 |
shelltestrunner python-dev pylint openssh-client vim git git-email |
325 |
|
326 |
# We need version 0.9.4 of pyinotify because the packaged version, 0.9.3, is |
327 |
# incompatibile with the packaged version of python-epydoc 3.0.1. |
328 |
# Reason: a logger class in pyinotify calculates its superclasses at |
329 |
# runtime, which clashes with python-epydoc's static analysis phase. |
330 |
# |
331 |
# Problem introduced in: |
332 |
# https://github.com/seb-m/pyinotify/commit/2c7e8f8959d2f8528e0d90847df360 |
333 |
# and "fixed" in: |
334 |
# https://github.com/seb-m/pyinotify/commit/98c5f41a6e2e90827a63ff1b878596 |
335 |
|
336 |
in_chroot -- \ |
337 |
easy_install pyinotify==0.9.4 |
338 |
|
339 |
in_chroot -- \ |
340 |
cabal update |
341 |
|
342 |
in_chroot -- \ |
343 |
cabal install --global \ |
344 |
base64-bytestring \ |
345 |
'lifted-base>=0.1.2' |
346 |
;; |
347 |
precise) |
348 |
# ghc, git-email and other dependencies are hosted in the universe |
349 |
# repository, which is not enabled by default. |
350 |
echo "Adding universe repository..." |
351 |
cat > $CHDIR/etc/apt/sources.list.d/universe.list <<EOF |
352 |
deb http://archive.ubuntu.com/ubuntu precise universe |
353 |
EOF |
354 |
in_chroot -- \ |
355 |
apt-get update |
356 |
|
357 |
echo "Installing packages" |
358 |
in_chroot -- \ |
359 |
$APT_INSTALL \ |
360 |
autoconf automake ghc ghc-haddock libghc-network-dev \ |
361 |
libghc-test-framework{,-hunit,-quickcheck2}-dev \ |
362 |
libghc-json-dev libghc-curl-dev libghc-hinotify-dev \ |
363 |
libghc-parallel-dev libghc-utf8-string-dev \ |
364 |
libghc-hslogger-dev libghc-crypto-dev \ |
365 |
libghc-regex-pcre-dev libghc-attoparsec-dev \ |
366 |
libghc-vector-dev libghc-temporary-dev \ |
367 |
libghc-snap-server-dev libpcre3 libpcre3-dev hscolour hlint pandoc \ |
368 |
python-setuptools python-sphinx python-epydoc graphviz python-pyparsing \ |
369 |
python-simplejson python-pyinotify python-pycurl python-paramiko \ |
370 |
python-bitarray python-ipaddr python-yaml qemu-utils python-coverage pep8 \ |
371 |
python-dev pylint openssh-client vim git git-email \ |
372 |
build-essential |
373 |
|
374 |
echo "Installing cabal packages" |
375 |
in_chroot -- \ |
376 |
$APT_INSTALL cabal-install |
377 |
|
378 |
in_chroot -- \ |
379 |
cabal update |
380 |
|
381 |
in_chroot -- \ |
382 |
cabal install --global \ |
383 |
base64-bytestring \ |
384 |
'lifted-base>=0.1.2' |
385 |
|
386 |
in_chroot -- \ |
387 |
cabal install --global shelltestrunner |
388 |
;; |
389 |
|
390 |
*) |
391 |
in_chroot -- \ |
392 |
$APT_INSTALL \ |
393 |
autoconf automake ghc ghc-haddock libghc-network-dev \ |
394 |
libghc-test-framework{,-hunit,-quickcheck2}-dev \ |
395 |
libghc-json-dev libghc-curl-dev libghc-hinotify-dev \ |
396 |
libghc-parallel-dev libghc-utf8-string-dev \ |
397 |
libghc-hslogger-dev libghc-crypto-dev \ |
398 |
libghc-regex-pcre-dev libghc-attoparsec-dev \ |
399 |
libghc-vector-dev libghc-temporary-dev \ |
400 |
libghc-snap-server-dev libpcre3 libpcre3-dev hscolour hlint pandoc \ |
401 |
libghc-lifted-base-dev \ |
402 |
libghc-base64-bytestring-dev \ |
403 |
python-setuptools python-sphinx python-epydoc graphviz python-pyparsing \ |
404 |
python-simplejson python-pyinotify python-pycurl python-paramiko \ |
405 |
python-bitarray python-ipaddr python-yaml qemu-utils python-coverage pep8 \ |
406 |
shelltestrunner python-dev pylint openssh-client vim git git-email \ |
407 |
build-essential |
408 |
|
409 |
;; |
410 |
esac |
411 |
|
412 |
# print what packages and versions are installed: |
413 |
in_chroot -- \ |
414 |
cabal list --installed --simple-output |
415 |
|
416 |
in_chroot -- \ |
417 |
$APT_INSTALL sudo fakeroot rsync locales less socat |
418 |
|
419 |
# Configure the locale |
420 |
case $DIST_RELEASE in |
421 |
precise) |
422 |
in_chroot -- \ |
423 |
$APT_INSTALL language-pack-en |
424 |
;; |
425 |
*) |
426 |
echo "en_US.UTF-8 UTF-8" >> $CHDIR/etc/locale.gen |
427 |
|
428 |
in_chroot -- \ |
429 |
locale-gen |
430 |
;; |
431 |
esac |
432 |
|
433 |
in_chroot -- \ |
434 |
$APT_INSTALL lvm2 ssh bridge-utils iproute iputils-arping \ |
435 |
ndisc6 python-openssl openssl \ |
436 |
python-mock fping qemu-utils |
437 |
|
438 |
in_chroot -- \ |
439 |
easy_install affinity |
440 |
|
441 |
in_chroot -- \ |
442 |
easy_install jsonpointer \ |
443 |
jsonpointer \ |
444 |
jsonpatch |
445 |
|
446 |
in_chroot -- \ |
447 |
$APT_INSTALL \ |
448 |
python-epydoc debhelper quilt |
449 |
|
450 |
# extra debian packages |
451 |
|
452 |
for package in $CHROOT_EXTRA_DEBIAN_PACKAGES |
453 |
do in_chroot -- \ |
454 |
$APT_INSTALL $package |
455 |
done |
456 |
|
457 |
#Set default editor |
458 |
in_chroot -- \ |
459 |
update-alternatives --set editor $ALTERNATIVE_EDITOR |
460 |
|
461 |
# Final user hook |
462 |
|
463 |
in_chroot -- $CHROOT_FINAL_HOOK |
464 |
|
465 |
rm -f $COMP_FILEPATH |
466 |
echo "Creating compressed schroot image..." |
467 |
cd $CHDIR |
468 |
tar czf $COMP_FILEPATH ./* |
469 |
cd $ROOT |
470 |
|
471 |
rm -rf $CHDIR |
472 |
rm -f $TEMP_CHROOT_CONF |
473 |
rm -rf $TEMP_DATA_DIR |
474 |
|
475 |
echo "Chroot created. In order to run it:" |
476 |
echo " * Copy the file $FINAL_CHROOT_CONF to $CONF_DIR/$FINAL_CHROOT_CONF" |
477 |
echo " * Copy the file $COMP_FILEPATH to $CHROOT_DIR/$COMP_FILENAME" |
478 |
echo "Then run \"schroot -c $CHROOTNAME\"" |