]> git.pld-linux.org Git - projects/cleanbuild.git/blob - bin/cleanbuild-docker.sh
Create container with docker-compose
[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         TMPFS_SIZE=$TMPFS \
60         PACKAGE_NAME=$PACKAGE_NAME \
61         docker-compose run --rm -d \
62                 --name=$name \
63                 --label=cleanbuild=$PACKAGE_NAME \
64                 cleanbuild
65
66         docker exec --user=root -w / $name usermod -d $home builder
67
68         # these paths need to be accessible for builder
69         docker exec --user=root -w / $name sh -c "cd $home && chown builder:builder rpm rpm/logs rpm/BUILD .ccache"
70
71         if [ ! -d $topdir/rpm-build-tools ]; then
72                 docker exec $name builder --init-rpm-dir
73         fi
74 }
75
76 package_prepare() {
77         # fetch sources and install deps
78         if [ -d $topdir/packages/$PACKAGE_NAME ]; then
79                 # chown, as it might be different owner (root) modified outside container
80                 docker exec --user=root -w / $name chown -R builder:builder $home/rpm/packages/$PACKAGE_NAME
81         fi
82         docker exec $name builder -g $PACKAGE_NAME
83
84         # prevent network access like pld builders do
85         $NETWORKING || docker exec --user=root -w / $name setfacl -m u:builder:--- /etc/resolv.conf
86
87         git_tag=$(GIT_DIR=$topdir/packages/$PACKAGE_NAME/.git git describe --tags --always)
88         buildlog=rpm/logs/${git_tag#auto/*/}.log
89 }
90
91 package_build() {
92         # create default args for builder
93         set -- -nn ${WITH:+--with "${WITH# }"} ${WITHOUT:+--without "${WITHOUT# }"} "$PACKAGE_NAME"
94
95         while true; do
96                 # install deps
97                 docker exec $name builder -g -R "$@"
98                 # remove .la dependencies
99                 docker exec --user=root -w / $name $home/cleanbuild/bin/cleanup-la
100                 # reset findunusedbr state after deps install
101                 docker exec --user=root -w / $name $home/cleanbuild/bin/findunusedbr -c / $home/rpm/packages/$PACKAGE_NAME/$PACKAGE_NAME.spec
102
103                 # actual build
104                 docker exec $name cleanbuild/bin/teeboth $buildlog builder -bb --define '__spec_clean_body %{nil}' "$@" && rc=$? || rc=$?
105
106                 findbr=$PACKAGE_NAME.findbr.log
107                 builddir=$(docker exec $name sh -c 'test ! -d rpm/BUILD/* || echo rpm/BUILD/*')
108                 if [ -z "$builddir" ]; then
109                         echo >&2 "No build dir. Build failed?"
110                         exit 6
111                 fi
112                 # need root to run poldek
113                 docker exec --user=root -w / $name sh -c "cd $home && cleanbuild/bin/findbr $builddir $buildlog" > $findbr
114
115                 installed_something=false
116                 while read pkg msg; do
117                         bin/addbr rpm/packages/$PACKAGE_NAME/$PACKAGE_NAME.spec "$pkg" "$msg" || continue
118                         installed_something=true
119                 done < $findbr
120                 rm -f $findbr
121
122                 # go for another try
123                 $installed_something && continue
124
125                 docker exec --user=root -w / $name $home/cleanbuild/bin/findunusedbr -c / $home/rpm/packages/$PACKAGE_NAME/$PACKAGE_NAME.spec
126
127                 if [ $rc -eq 0 ] && ! $KEEP_CONTAINER; then
128                         # finished ok, cleanup
129                         docker kill $name >/dev/null && docker rm $name >/dev/null || :
130                 fi
131
132                 # propagate error
133                 exit $rc
134         done
135 }
136
137 parse_options() {
138         local t
139         t=$(getopt -o 'x' --long 'network,no-tmpfs,notmpfs,tmpfs:,keep-container,with:,without:' -n "$PROGRAM" -- "$@")
140         [ $? != 0 ] && exit $?
141         eval set -- "$t"
142
143         while :; do
144                 case "$1" in
145                 -x)
146                         TRACING=true
147                         ;;
148                 --network)
149                         NETWORKING=true
150                         ;;
151                 --no-tmpfs|--notmpfs)
152                         TMPFS=false
153                         ;;
154                 --tmpfs)
155                         shift
156                         TMPFS="$1"
157                         ;;
158                 --keep-container)
159                         KEEP_CONTAINER=true
160                         ;;
161                 --with)
162                         shift
163                         WITH="$WITH $1"
164                         ;;
165                 --without)
166                         shift
167                         WITHOUT="$WITHOUT $1"
168                         ;;
169                 --)
170                         shift
171                         break
172                         ;;
173                 *)
174                         die "Internal error: [$1] not recognized!"
175                         ;;
176                 esac
177                 shift
178         done
179
180         test "$#" -eq 1 || die "package not specified or excess arguments"
181         PACKAGE_NAME="${1%.spec}"
182 }
183
184 main() {
185         parse_options "$@"
186
187         $TRACING && set -x
188         local name="cleanbuild-$PACKAGE_NAME"
189         create_container
190         package_prepare
191         package_build
192 }
193
194 main "$@"
This page took 0.109457 seconds and 4 git commands to generate.