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