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