]> git.pld-linux.org Git - projects/cleanbuild.git/blob - bin/cleanbuild-docker.sh
Move scripts to bin
[projects/cleanbuild.git] / bin / cleanbuild-docker.sh
1 #!/bin/sh
2 set -eu
3
4 PROGRAM=${0##*/}
5
6 # defaults
7 : ${PACKAGE_NAME=''}
8 : ${NETWORKING=false}
9 : ${TRACING=false}
10 : ${WITH=}
11 : ${WITHOUT=}
12 : ${KEEP_CONTAINER=false}
13 : ${TMPFS="4G"}
14
15 dir=$(pwd)
16 image=registry.gitlab.com/pld-linux/cleanbuild
17 topdir=$dir/rpm
18 home=/home/builder
19
20 die() {
21         echo >&2 "$0: $*"
22         exit 1
23 }
24
25 is_no() {
26         # Test syntax
27         if [ $# = 0 ]; then
28                 return 2
29         fi
30
31         case "$1" in
32         no|No|NO|false|False|FALSE|off|Off|OFF|N|n|0)
33                 # true returns zero
34                 return 0
35                 ;;
36         *)
37                 # false returns one
38                 return 1
39                 ;;
40         esac
41 }
42
43 tmpfs() {
44         if is_no "${TMPFS:-true}" || [ "$TMPFS" = "0" ]; then
45                 return
46         fi
47
48         echo "--tmpfs $home/rpm/BUILD:rw,exec,nosuid,size=$TMPFS"
49 }
50
51 create_container() {
52         # cleanup first
53         docker kill $name >/dev/null 2>&1 || :
54         docker rm $name >/dev/null 2>&1 || :
55
56         install -d $topdir/logs
57
58         # start the container
59         docker run --name=$name -d \
60                 -w $home \
61                 -v $topdir:$home/rpm \
62                 -v $dir:$home/cleanbuild \
63                 -v $dir/cache/poldek:/var/cache/poldek \
64                 -v $dir/cache/ccache/$PACKAGE_NAME:$home/.ccache \
65                 --label=cleanbuild=$name \
66                 $(tmpfs) \
67                 $image >/dev/null
68
69         # set the homedir
70         docker exec --user=root -w / $name usermod -d $home builder
71
72         # these paths need to be accessible for builder
73         docker exec --user=root -w / $name sh -c "cd $home && chown builder:builder rpm rpm/logs rpm/BUILD .ccache"
74
75         if [ ! -d $topdir/rpm-build-tools ]; then
76                 docker exec $name builder --init-rpm-dir
77         fi
78 }
79
80 package_prepare() {
81         # fetch sources and install deps
82         if [ -d $topdir/packages/$PACKAGE_NAME ]; then
83                 # chown, as it might be different owner (root) modified outside container
84                 docker exec --user=root -w / $name chown -R builder:builder $home/rpm/packages/$PACKAGE_NAME
85         fi
86         docker exec $name builder -g $PACKAGE_NAME
87
88         # prevent network access like pld builders do
89         $NETWORKING || docker exec --user=root -w / $name setfacl -m u:builder:--- /etc/resolv.conf
90
91         git_tag=$(GIT_DIR=$topdir/packages/$PACKAGE_NAME/.git git describe --tags --always)
92         buildlog=rpm/logs/${git_tag#auto/*/}.log
93 }
94
95 package_build() {
96         # create default args for builder
97         set -- -nn ${WITH:+--with "${WITH# }"} ${WITHOUT:+--without "${WITHOUT# }"} "$PACKAGE_NAME"
98
99         while true; do
100                 # install deps
101                 docker exec $name builder -g -R "$@"
102                 # remove .la dependencies
103                 docker exec --user=root -w / $name $home/cleanbuild/bin/cleanup-la
104                 # reset findunusedbr state after deps install
105                 docker exec --user=root -w / $name $home/cleanbuild/bin/findunusedbr -c / $home/rpm/packages/$PACKAGE_NAME/$PACKAGE_NAME.spec
106
107                 # actual build
108                 docker exec $name cleanbuild/bin/teeboth $buildlog builder -bb --define '__spec_clean_body %{nil}' "$@" && rc=$? || rc=$?
109
110                 findbr=$PACKAGE_NAME.findbr.log
111                 builddir=$(docker exec $name sh -c 'test ! -d rpm/BUILD/* || echo rpm/BUILD/*')
112                 if [ -z "$builddir" ]; then
113                         echo >&2 "No build dir. Build failed?"
114                         exit 6
115                 fi
116                 # need root to run poldek
117                 docker exec --user=root -w / $name sh -c "cd $home && cleanbuild/bin/findbr $builddir $buildlog" > $findbr
118
119                 installed_something=false
120                 while read pkg msg; do
121                         ./addbr rpm/packages/$PACKAGE_NAME/$PACKAGE_NAME.spec "$pkg" "$msg" || continue
122                         installed_something=true
123                 done < $findbr
124                 rm -f $findbr
125
126                 # go for another try
127                 $installed_something && continue
128
129                 docker exec --user=root -w / $name $home/cleanbuild/bin/findunusedbr -c / $home/rpm/packages/$PACKAGE_NAME/$PACKAGE_NAME.spec
130
131                 if [ $rc -eq 0 ] && ! $KEEP_CONTAINER; then
132                         # finished ok, cleanup
133                         docker kill $name >/dev/null && docker rm $name >/dev/null || :
134                 fi
135
136                 # propagate error
137                 exit $rc
138         done
139 }
140
141 parse_options() {
142         local t
143         t=$(getopt -o 'x' --long 'network,no-tmpfs,notmpfs,tmpfs:,keep-container,with:,without:' -n "$PROGRAM" -- "$@")
144         [ $? != 0 ] && exit $?
145         eval set -- "$t"
146
147         while :; do
148                 case "$1" in
149                 -x)
150                         TRACING=true
151                         ;;
152                 --network)
153                         NETWORKING=true
154                         ;;
155                 --no-tmpfs|--notmpfs)
156                         TMPFS=false
157                         ;;
158                 --tmpfs)
159                         shift
160                         TMPFS="$1"
161                         ;;
162                 --keep-container)
163                         KEEP_CONTAINER=true
164                         ;;
165                 --with)
166                         shift
167                         WITH="$WITH $1"
168                         ;;
169                 --without)
170                         shift
171                         WITHOUT="$WITHOUT $1"
172                         ;;
173                 --)
174                         shift
175                         break
176                         ;;
177                 *)
178                         die "Internal error: [$1] not recognized!"
179                         ;;
180                 esac
181                 shift
182         done
183
184         test "$#" -eq 1 || die "package not specified or excess arguments"
185         PACKAGE_NAME="${1%.spec}"
186 }
187
188 main() {
189         parse_options "$@"
190
191         $TRACING && set -x
192         local name="cleanbuild-$PACKAGE_NAME"
193         create_container
194         package_prepare
195         package_build
196 }
197
198 main "$@"
This page took 0.092015 seconds and 4 git commands to generate.