]> git.pld-linux.org Git - projects/cleanbuild.git/blob - cleanbuild
- renamed force to forceumount
[projects/cleanbuild.git] / cleanbuild
1 #!/usr/bin/sudo /bin/sh
2
3 RPMS_FROM="$HOME/rpm/cleanRPMS.repo"
4 DEST="th"
5 SRC="-n th-x86_64-test"
6 SUFFIX=""
7 CACHEDIR="$PWD/poldekcache"
8 IGNORE=""
9 ignore() { IGNORE="$IGNORE $*"; }
10 NODEBUG=true
11 CLEANAFTER=false
12 FORCE_UMOUNT=false
13
14 [ -r .cleanbuildrc ] && . ./.cleanbuildrc
15
16 [ -z "$USER" ] && echo "USER not defined" && exit 1
17 [ "$USER" == "root" ] && echo "USER must not be root" && exit 1
18
19 export LC_ALL=C
20 unset LANGUAGE
21 unset LANG
22
23 usage() {
24         [ $# -gt 0 ] && echo "$*"
25         echo "Usage:"
26         echo "  ./cleanbuild [cleanbuild options] specname [builder options]"
27         echo "  ./build [cleanbuild options] specname [builder options]"
28         echo "  ./clean [cleanbuild options]"
29         echo "  ./create [cleanbuild options]"
30         echo "  ./install [cleanbuild options] packages"
31         echo ""
32         echo "cleanbuild options:"
33         echo " -32, -64, -th-i486  - select architecture"
34         echo " --cleanafter | -ca  - clean after build"
35         echo " --forceumount | -fu - force umount tmpfs"
36         echo " --debug             - enable debug"
37         echo " -a, -b, -c, -d, -e  - select alternative chroot directory"
38         exit 1
39 }
40
41 FETCH=false
42 CLEAN=false
43 CREATE=false
44 BUILD=false
45 INSTALL=false
46
47 case "$0" in
48         *clean)
49                 CLEAN=exit_after
50                 ;;
51         *cleanbuild)
52                 FETCH=true
53                 CLEAN=true
54                 CREATE=true
55                 BUILD=true
56                 ;;
57         *build)
58                 CREATE=true
59                 BUILD=true
60                 ;;
61         *create)
62                 CLEAN=true
63                 CREATE=exit_after
64                 ;;
65         *install)
66                 CREATE=true
67                 INSTALL=exit_after
68                 ;;
69         *)
70                 usage
71                 ;;
72 esac
73
74 while [ $# -gt 0 ]; do
75         OPT="${1}"
76         case "$OPT" in
77                 -32)    OPT="-th-i686" ;;
78                 -64)    OPT="-th-x86_64" ;;
79                 -th-32) OPT="-th-i686" ;;
80                 -th-64) OPT="-th-x86_64" ;;
81                 -ti-32) OPT="-ti-i686" ;;
82                 -ti-64) OPT="-ti-x86_64" ;;
83                 -ac)    OPT="-ac-amd64" ;;
84                 -ac-32) OPT="-ac-i586" ;;
85                 -ac-64) OPT="-ac-amd64" ;;
86         esac
87
88         V="${OPT#-}"
89         case "$OPT" in
90                 -th-i[46]86 | -th-x86_64)
91                         DEST="$V"
92                         SRC="-n $V-ready"
93                         ;;
94                 -th-i[46]86-test | -th-x86_64-test)
95                         DEST="$V"
96                         SRC="-n $V"
97                         ;;
98                 -ti-i[56]86 | -ti-x86_64)
99                         DEST="$V"
100                         SRC="-n $V-ready"
101                         ;;
102                 -ti-i[56]86-test | -ti-x86_64-test)
103                         DEST="$V"
104                         SRC="-n $V"
105                         ;;
106                 -ac-amd64 | -ac-i[356]86 | -ac-athlon)
107                         DEST="$V"
108                         SRC="-n $V-ready"
109                         ;;
110                 --cleanafter | -ca)
111                         CLEANAFTER=true
112                         ;;
113                 --debug)
114                         NODEBUG=false
115                         ;;
116                 --forceumount | -fu)
117                         FORCE_UMOUNT=true
118                         ;;
119                 -[a-e])
120                         SUFFIX="$OPT"
121                         ;;
122                 -~*)
123                         SUFFIX="$V"
124                         ;;
125                 *)
126                         break
127                         ;;
128         esac
129         shift
130 done
131
132 if $BUILD; then
133         [ $# -ne 0 ] || usage
134         build_pkg="${1}"
135         shift
136
137         builder_options="$*"
138 fi
139
140 $NODEBUG || set -x
141
142 CHNAME="chroot-$DEST$SUFFIX"
143 CHDIR="$PWD/$CHNAME"
144 CHHOME="/home/users/$USER"
145
146 warn()
147 {
148         echo -n -e "\033[31;1m" >&2
149         echo -n "$*" >&2
150         echo -e "\033[0m" >&2
151 }
152
153 die()
154 {
155         code=$1
156         shift
157         warn "$*"
158         exit $code
159 }
160
161 info()
162 {
163         echo -n -e "\033[32m"
164         echo -n "$*"
165         echo -e "\033[0m"
166 }
167
168 title()
169 {
170         [ -t 1 ] || return 0
171         local msg="$CHNAME: $build_pkg: $*"
172         case "$TERM" in
173                 cygwin|xterm*)
174                         echo -ne "\033]1;$msg\007\033]2;$msg\007" >&2
175                         ;;
176                 screen*)
177                         echo -ne "\033]0;$msg\007" >&2
178                         ;;
179         esac
180         return 0
181 }
182
183 exit_after()
184 {
185         return 0;
186 }
187
188 check_running()
189 {
190         [ -r "$CHDIR/.pid" ] || return
191         PID=$(< "$CHDIR/.pid")
192         if [ -d /proc/$PID ]; then
193                 die 10 "Another process ($PID) already running in $CHNAME"
194         fi
195 }
196
197 for D in installed buildlogs $CACHEDIR; do
198         if [ ! -d "$D" ]; then
199                 info "mkdir $D"
200                 su $USER -c "mkdir -p $D" || die 13 "Cannot create work directories"
201         fi
202 done
203
204 ignore \
205         vserver-packages \
206         upstart\* \
207         xorg-driver-video-fglrx\* xorg-driver-video-nvidia\* xorg-xserver-xgl-libGL \
208         xorg-data-xbitmaps \
209         compat-gcc\* \
210         libpng1\* \
211         anacron fcron hc-cron \
212         masqmail msmtp-sendmail omta postfix sendmail ssmtp nail-mail nullmailer \
213         ghostscript-esp \
214         \*-multilib-\* \
215         gnome-speech-driver-festival gnome-speech-driver-speech-dispatcher
216
217
218 rebuilddb()
219 {
220         #rpm --root=$CHDIR --rebuilddb
221 }
222
223 poldek()
224 {
225         $NODEBUG || set -x
226         rebuilddb
227         /usr/bin/poldek $SRC -s "$RPMS_FROM" -r "$CHDIR" "--cachedir=$CACHEDIR" --conf=$PWD/poldekconf/poldek.conf "$@"
228 }
229
230
231 build_umount()
232 {
233         for DIR in $CHHOME/rpm $CHHOME dev proc sys; do
234                 [ -d $CHDIR/$DIR ] && umount $CHDIR/$DIR
235         done
236 }
237
238 build_remove_root()
239 {
240         $NODEBUG || set -x
241         if $FORCE_UMOUNT; then
242                 # safety checks.
243                 [ "$CHDIR" ] || exit 1
244                 [ -d "$CHDIR" ] || exit 1
245                 rm -rf $CHDIR/*
246                 umount -l $CHDIR
247         else
248                 umount $CHDIR
249         fi
250         rmdir $CHDIR
251 }
252
253 clean()
254 {
255         info "Cleaning $CHNAME"
256         title "cleaning chroot"
257         build_umount
258         build_remove_root
259 }
260
261 build_prepare_root()
262 {
263         title "preparing chroot"
264         set -e
265         $NODEBUG || set -x
266         mkdir $CHDIR
267         mount -t tmpfs -o size=8G,relatime /dev/null $CHDIR
268         echo $$ > $CHDIR/.pid
269
270         rpm --root=$CHDIR --initdb 
271         poldek --up || :
272         poldek -O "ignore=$IGNORE" -u rpm-build pwdutils coreutils
273
274         for DIR in dev proc sys; do
275                 # We need to create these directories manually, because they are marked
276                 # as netsharedpath in cleanbuild poldek.conf
277                 mkdir $CHDIR/$DIR
278                 mount -o bind /$DIR $CHDIR/$DIR
279         done
280
281         chroot $CHDIR useradd -m $USER -u$(getent passwd $USER | cut -d: -f3)
282
283         # replicate files which already belong to $USER
284         # so they will have correct owner and permissions
285         cp -a $CHDIR/$CHHOME/{tmp,rpm}
286         cp -a $CHDIR/$CHHOME/tmp $CHDIR/BUILD
287
288         cp -a $CHDIR/$CHHOME/{.bashrc,.rpmmacros}
289         cat <<-'EOM' > $CHDIR/$CHHOME/.rpmmacros
290         %_builddir              /BUILD
291         %buildroot              %{_builddir}/%{name}-%{version}-root-%(id -u -n)
292         %_rpmdirname    cleanRPMS
293         %_rpmdir                %{expand:%%global _rpmdir %([ -d %{_topdir}/../%{_rpmdirname} ] && (cd %{_topdir}/../%{_rpmdirname}; pwd) || echo %{_topdir}/%{_rpmdirname})}%_rpmdir
294         %distribution   CleanPLD
295         %_binary_payload        w1.gzdio
296         #%_smp_mflags   -j4
297 EOM
298
299         cp -a $CHDIR/$CHHOME/{.bashrc,.builderrc}
300         cat <<-'EORC' > $CHDIR/$CHHOME/.builderrc
301         TITLECHANGE=no
302 EORC
303         set +e
304 }
305
306 build_mount_home()
307 {
308         $NODEBUG || set -x
309         mount -o bind $HOME/rpm $CHDIR/$CHHOME/rpm
310 }
311
312
313 print_installed()
314 {
315         echo=$1
316         if [ -r installed/$build_pkg ]; then
317                 $echo "$(cat installed/$build_pkg | awk '{print $1}' | sort -u \
318                         | awk '{br=br ", " $1} END{gsub(/^, /, "- BR: ", br ); print br}')"
319                 cat installed/$build_pkg
320         fi
321 }
322
323 addlist()
324 {
325         LIST="$1"
326
327         print_installed info
328
329         return
330         echo "*** $build_pkg $(date --rfc-3339=seconds) ***" >> $LIST
331         print_installed echo >> $LIST
332 }
333
334 builddie()
335 {
336         LIST="$1"; shift
337         CODE="$1"; shift
338         MSG="$*"
339
340         rm -f $CHDIR/.pid
341
342         $CLEANAFTER && clean
343         title "failed !"
344
345         addlist "ERROR_$LIST"
346         die $CODE "$MSG"
347 }
348
349 LAST_INSTALL=""
350 poldek_install()
351 {
352         I="$1";
353         # Nothing to install
354         [ -n "$I" ] || return 1
355         # Installing same packets second time
356         [ "$LAST_INSTALL" != "$I" ] || return 1
357         LAST_INSTALL="$I"
358
359         info "Installing" $I
360         poldek -O "ignore=$IGNORE" -u $I | tee $$.poldek_install
361         ret=
362         if grep -q "Preparing...                ##################################################" $$.poldek_install \
363                         && ! grep -q "file .* from install of .* conflicts with file from package" $$.poldek_install
364                 then
365                 info "Poldek:" $I "installed"
366                 ret=0
367         elif grep -q "Nothing to do" $$.poldek_install; then
368                 warn "Poldek:" $I "installed already"
369                 ret=1
370         fi
371         rm $$.poldek_install
372         [ -n "$ret" ] && return $ret
373
374         # try harder
375         poldek -u $I && return 0
376         poldek -u $I && return 0
377         warn "Poldek:" "Could not install" $I
378         return 1
379 }
380
381 maybe_call()
382 {
383         local cond="$1"; shift
384         local func="$1"; shift
385
386         [ $cond == "false" ] && return
387         $func "$@"
388         [ $cond == "exit_after" ] && exit
389 }
390
391 fetch()
392 {
393         info "Fetching $build_pkg"
394         title "fetch"
395         $NODEBUG || set -x
396         su $USER -c "$HOME/rpm/packages/builder -g $build_pkg $builder_options" \
397                 || die 11 "Fetch failed"
398 }
399
400 create()
401 {
402         $NODEBUG || set -x
403         su $USER -c "poldek -s $RPMS_FROM --mkidx"
404
405         if [ ! -d $CHDIR ]; then
406                 info "Preparing $CHNAME"
407                 build_prepare_root
408                 build_mount_home
409         fi
410 }
411
412
413 maybe_call $FETCH fetch
414
415 check_running
416
417 maybe_call $CLEAN clean
418
419 maybe_call $CREATE create
420
421 echo $$ > $CHDIR/.pid
422
423 maybe_call $INSTALL poldek_install "$*"
424
425 $BUILD || exit
426
427 if [ -p /tmp/fixfreq ]; then
428         echo $$ > /tmp/fixfreq
429 fi
430
431 while true; do
432         info "Building $build_pkg in $CHNAME"
433         rebuilddb
434         buildlog="buildlogs/$build_pkg"
435         if [ -r $buildlog ]; then
436                 i=1
437                 while [ -r $buildlog.$i ]; do
438                         i=$((i+1))
439                 done
440                 info "moving $buildlog to $buildlog.$i"
441                 mv $buildlog $buildlog.$i
442         fi
443         ./findunusedbr -c $CHDIR $HOME/rpm/packages/$build_pkg/$build_pkg.spec
444         title "building"
445         { chroot $CHDIR su $USER -c "$CHHOME/rpm/packages/builder -nn -bb $build_pkg $builder_options" 2>&1; echo $? > ecode; } | tee $buildlog
446
447         ECODE=$(< ecode)
448         rm -f ecode
449
450         if grep -q "error: Failed build dependencies:" $buildlog; then
451                 SEARCH=$(cat $buildlog | awk '/^Error:/ { p = 0 }; { if ( p ) { f="p"; if ( $1 ~ /^\// ) f="f"; printf "search -%c %s; ", f, $1; } }; /error: Failed build dependencies:/ { p = 1 }')
452                 INSTALL=$(poldek -O "ignore=$IGNORE" --shcmd="$SEARCH" | awk '{ if ( p ) { print; p = 0; } } / package\(s\) found:$/ { p = 1 }' | sed 's/^\(.*\)-.*-.*$/\1/' | sort -u)
453
454                 if poldek_install "$INSTALL"; then
455                         info "Deps installed"
456                         continue
457                 else
458                         addlist ERROR_BRINSTALL
459                         die 4 "Cannot install BRs"
460                 fi
461         fi
462
463         ./findbr $CHDIR/BUILD $buildlog > $$.installed
464         installed_something=false
465         while read pkg msg; do
466                 if poldek_install $pkg; then
467                         info "findbr:" $pkg "installed"
468                         echo "$pkg $msg" >> installed/$build_pkg
469                         ./addbr $build_pkg "$pkg" "$msg"
470                         installed_something=true
471                 else
472                         warn "findbr:" $pkg "not installed"
473                 fi
474         done < $$.installed
475         rm -f $$.installed
476         $installed_something && continue
477
478         if [ $ECODE -eq 0 ]; then
479                 $CLEANAFTER && clean
480                 addlist BUILT_OK
481                 ./findunusedbr $CHDIR $HOME/rpm/packages/$build_pkg/$build_pkg.spec
482                 info "$build_pkg built OK !"
483                 title "OK !"
484                 exit 0
485         else
486                 builddie UNKNOWN 1 "Got error but dunno what to do !"
487         fi
488 done
489
490
491 # vim: ts=4 sw=4 filetype=sh
This page took 0.098792 seconds and 4 git commands to generate.