]>
Commit | Line | Data |
---|---|---|
ce96f77c | 1 | #!/bin/sh |
e2ea04e5 | 2 | set -eu |
ce96f77c | 3 | |
e2ea04e5 | 4 | PROGRAM=${0##*/} |
ce96f77c | 5 | |
e2ea04e5 ER |
6 | # defaults |
7 | : ${PACKAGE_NAME=''} | |
3ac42f8d | 8 | : ${NETWORKING=false} |
5d14e3f9 | 9 | : ${TRACING=false} |
60584f5d ER |
10 | : ${WITH=} |
11 | : ${WITHOUT=} | |
c31e256f | 12 | : ${KEEP_CONTAINER=true} |
2da31caa | 13 | : ${TMPFS="4G"} |
0d37247d | 14 | : ${EXEC=false} |
ce96f77c | 15 | |
ce96f77c | 16 | dir=$(pwd) |
47ec7a26 | 17 | image=registry.gitlab.com/pld-linux/cleanbuild |
ce96f77c | 18 | topdir=$dir/rpm |
8f52cf50 | 19 | home=/home/builder |
73d3710b | 20 | |
9ccc3554 ER |
21 | notice() { |
22 | echo >&2 "[cleanbuild:notice]: $*" | |
23 | } | |
24 | ||
e2ea04e5 | 25 | die() { |
20a616bf | 26 | local rc=${2:-1} |
9ccc3554 | 27 | echo >&2 "[cleanbuild:error]: $1" |
20a616bf | 28 | exit $rc |
e2ea04e5 ER |
29 | } |
30 | ||
2da31caa ER |
31 | is_no() { |
32 | # Test syntax | |
33 | if [ $# = 0 ]; then | |
34 | return 2 | |
35 | fi | |
36 | ||
37 | case "$1" in | |
38 | no|No|NO|false|False|FALSE|off|Off|OFF|N|n|0) | |
39 | # true returns zero | |
40 | return 0 | |
41 | ;; | |
42 | *) | |
43 | # false returns one | |
44 | return 1 | |
45 | ;; | |
46 | esac | |
47 | } | |
48 | ||
49 | tmpfs() { | |
8e5e409e | 50 | if is_no "${TMPFS:-true}" || [ "$TMPFS" = "0" ]; then |
2da31caa ER |
51 | return |
52 | fi | |
53 | ||
54 | echo "--tmpfs $home/rpm/BUILD:rw,exec,nosuid,size=$TMPFS" | |
55 | } | |
56 | ||
98e02557 ER |
57 | have_container() { |
58 | local name="$1" id | |
59 | ||
60 | id=$(docker ps -a -f "label=cleanbuild=$name" --format '{{.ID}}') | |
61 | ||
62 | test -n "$id" | |
63 | } | |
64 | ||
e2ea04e5 | 65 | create_container() { |
98e02557 ER |
66 | if ! $KEEP_CONTAINER; then |
67 | notice "Clean up old container: $name" | |
68 | docker kill $name >/dev/null 2>&1 || : | |
69 | docker rm $name >/dev/null 2>&1 || : | |
70 | fi | |
ce96f77c | 71 | |
e2ea04e5 | 72 | install -d $topdir/logs |
ce96f77c | 73 | |
e2ea04e5 | 74 | # start the container |
6569f6a5 | 75 | if ! have_container "$PACKAGE_NAME"; then |
98e02557 ER |
76 | TMPFS_SIZE=$TMPFS \ |
77 | PACKAGE_NAME=$PACKAGE_NAME \ | |
78 | docker-compose run --rm -d \ | |
79 | --name=$name \ | |
eb07c8d6 | 80 | --workdir=$home/rpm/packages/$PACKAGE_NAME \ |
98e02557 ER |
81 | --label=cleanbuild=$PACKAGE_NAME \ |
82 | cleanbuild | |
83 | fi | |
ce96f77c | 84 | |
6569f6a5 ER |
85 | UID=$(id -u) |
86 | GID=$(id -g) | |
87 | notice "Setup builder user ($UID:$GID)" | |
88 | ||
e2ea04e5 | 89 | docker exec --user=root -w / $name usermod -d $home builder |
621943d5 | 90 | |
6569f6a5 ER |
91 | if [ "$UID" -gt 0 ]; then |
92 | docker exec --user=root -w / $name usermod -u $UID builder | |
93 | fi | |
94 | if [ "$GID" -gt 0 ]; then | |
95 | docker exec --user=root -w / $name groupmod -g $GID builder | |
96 | fi | |
97 | ||
9ccc3554 | 98 | notice "Setup permissions" |
6569f6a5 | 99 | docker exec --user=root -w / $name sh -c "cd $home && chown builder:builder . rpm rpm/logs rpm/BUILD rpm/RPMS rpm/packages .ccache" |
e2ea04e5 ER |
100 | |
101 | if [ ! -d $topdir/rpm-build-tools ]; then | |
9ccc3554 | 102 | notice "Initialize rpm-build-tools" |
d59399e8 | 103 | docker exec -w / $name builder --init-rpm-dir |
ce96f77c | 104 | fi |
e2ea04e5 | 105 | } |
ce96f77c | 106 | |
0d37247d ER |
107 | enter_container() { |
108 | notice "Entering container for $PACKAGE_NAME" | |
109 | docker exec --user=root -it $name bash | |
110 | } | |
111 | ||
e2ea04e5 | 112 | package_prepare() { |
9ccc3554 | 113 | notice "Fetch sources and install dependencies" |
e2ea04e5 ER |
114 | if [ -d $topdir/packages/$PACKAGE_NAME ]; then |
115 | # chown, as it might be different owner (root) modified outside container | |
9ccc3554 | 116 | notice "Fix ownership of existing package directory" |
e2ea04e5 ER |
117 | docker exec --user=root -w / $name chown -R builder:builder $home/rpm/packages/$PACKAGE_NAME |
118 | fi | |
9ccc3554 ER |
119 | |
120 | notice "Fetch package sources" | |
98e02557 | 121 | docker exec --user=root -w / $name setfacl -x u:builder /etc/resolv.conf |
eb07c8d6 | 122 | docker exec -w / $name builder -g $PACKAGE_NAME |
e2ea04e5 | 123 | |
9ccc3554 ER |
124 | if ! $NETWORKING; then |
125 | notice "Disable networking: Prevent network access for user builder like PLD Linux builders" | |
126 | docker exec --user=root -w / $name setfacl -m u:builder:--- /etc/resolv.conf | |
127 | fi | |
e2ea04e5 | 128 | |
4fbca347 | 129 | notice "Find latest tag on the branch" |
eb07c8d6 | 130 | git_tag=$(docker exec -w / -e GIT_DIR=$home/rpm/packages/$PACKAGE_NAME/.git $name git describe --tags --always) |
e2ea04e5 | 131 | buildlog=rpm/logs/${git_tag#auto/*/}.log |
4fbca347 | 132 | notice "Build log: $buildlog" |
e2ea04e5 ER |
133 | } |
134 | ||
135 | package_build() { | |
60584f5d ER |
136 | # create default args for builder |
137 | set -- -nn ${WITH:+--with "${WITH# }"} ${WITHOUT:+--without "${WITHOUT# }"} "$PACKAGE_NAME" | |
138 | ||
e2ea04e5 | 139 | while true; do |
9ccc3554 | 140 | notice "Install dependencies" |
eb07c8d6 | 141 | docker exec -w / -t $name builder -g -R "$@" |
9ccc3554 | 142 | notice "Remove .la dependencies" |
60ca295b | 143 | docker exec --user=root -w / $name $home/cleanbuild/bin/cleanup-la |
9ccc3554 | 144 | notice "Reset findunusedbr state after deps install" |
60ca295b | 145 | docker exec --user=root -w / $name $home/cleanbuild/bin/findunusedbr -c / $home/rpm/packages/$PACKAGE_NAME/$PACKAGE_NAME.spec |
e2ea04e5 | 146 | |
9ccc3554 | 147 | notice "Build package" |
eb07c8d6 | 148 | docker exec -w $home $name cleanbuild/bin/teeboth $buildlog builder -bb --define '__spec_clean_body %{nil}' "$@" && rc=$? || rc=$? |
6ecf9aec ER |
149 | # Kill processes on Ctrl+C |
150 | if [ "$rc" = 255 ]; then | |
eb07c8d6 | 151 | docker exec -w / $name pkill -e -u builder |
6ecf9aec ER |
152 | die "Aborted" $rc |
153 | fi | |
e2ea04e5 ER |
154 | |
155 | findbr=$PACKAGE_NAME.findbr.log | |
eb07c8d6 | 156 | builddir=$(docker exec -w $home $name sh -c 'test ! -d rpm/BUILD/* || echo rpm/BUILD/*') |
e2ea04e5 | 157 | if [ -z "$builddir" ]; then |
20a616bf | 158 | die "No build dir. Build failed?" 6 |
e2ea04e5 | 159 | fi |
9ccc3554 | 160 | notice "Execute findbr" |
60ca295b | 161 | docker exec --user=root -w / $name sh -c "cd $home && cleanbuild/bin/findbr $builddir $buildlog" > $findbr |
e2ea04e5 ER |
162 | |
163 | installed_something=false | |
164 | while read pkg msg; do | |
03501aec | 165 | bin/addbr rpm/packages/$PACKAGE_NAME/$PACKAGE_NAME.spec "$pkg" "$msg" || continue |
e2ea04e5 ER |
166 | installed_something=true |
167 | done < $findbr | |
168 | rm -f $findbr | |
169 | ||
170 | # go for another try | |
171 | $installed_something && continue | |
172 | ||
9ccc3554 | 173 | notice "Execute findunusedbr" |
60ca295b | 174 | docker exec --user=root -w / $name $home/cleanbuild/bin/findunusedbr -c / $home/rpm/packages/$PACKAGE_NAME/$PACKAGE_NAME.spec |
e2ea04e5 | 175 | |
ad5ed75b | 176 | if [ $rc -eq 0 ] && ! $KEEP_CONTAINER; then |
9ccc3554 | 177 | notice "Finished ok, cleanup container" |
e2ea04e5 ER |
178 | docker kill $name >/dev/null && docker rm $name >/dev/null || : |
179 | fi | |
180 | ||
181 | # propagate error | |
182 | exit $rc | |
183 | done | |
184 | } | |
185 | ||
186 | parse_options() { | |
187 | local t | |
0d37247d | 188 | t=$(getopt -o 'x' --long 'network,exec,no-tmpfs,notmpfs,tmpfs:,keep-container:,with:,without:' -n "$PROGRAM" -- "$@") |
e2ea04e5 ER |
189 | [ $? != 0 ] && exit $? |
190 | eval set -- "$t" | |
191 | ||
192 | while :; do | |
193 | case "$1" in | |
5d14e3f9 ER |
194 | -x) |
195 | TRACING=true | |
196 | ;; | |
3ac42f8d ER |
197 | --network) |
198 | NETWORKING=true | |
199 | ;; | |
0d37247d ER |
200 | --exec) |
201 | EXEC=true | |
202 | ;; | |
8447721f ER |
203 | --no-tmpfs|--notmpfs) |
204 | TMPFS=false | |
205 | ;; | |
2da31caa ER |
206 | --tmpfs) |
207 | shift | |
208 | TMPFS="$1" | |
209 | ;; | |
ad5ed75b | 210 | --keep-container) |
c31e256f ER |
211 | shift |
212 | [ "$1" = "true" -o "$1" = "false" ] || die "Invalid boolean value: $1" | |
213 | KEEP_CONTAINER=$1 | |
ad5ed75b | 214 | ;; |
60584f5d ER |
215 | --with) |
216 | shift | |
9c5772e4 | 217 | WITH="$WITH,$1" |
60584f5d ER |
218 | ;; |
219 | --without) | |
220 | shift | |
9c5772e4 | 221 | WITHOUT="$WITHOUT,$1" |
60584f5d | 222 | ;; |
e2ea04e5 ER |
223 | --) |
224 | shift | |
225 | break | |
226 | ;; | |
227 | *) | |
228 | die "Internal error: [$1] not recognized!" | |
229 | ;; | |
230 | esac | |
231 | shift | |
232 | done | |
233 | ||
9ccc3554 | 234 | test "$#" -eq 1 || die "Package not specified or excess arguments" |
e2ea04e5 ER |
235 | PACKAGE_NAME="${1%.spec}" |
236 | } | |
237 | ||
238 | main() { | |
239 | parse_options "$@" | |
240 | ||
5d14e3f9 | 241 | $TRACING && set -x |
e2ea04e5 | 242 | local name="cleanbuild-$PACKAGE_NAME" |
0d37247d ER |
243 | if $EXEC; then |
244 | enter_container | |
245 | return | |
246 | fi | |
6569f6a5 | 247 | create_container |
e2ea04e5 ER |
248 | package_prepare |
249 | package_build | |
250 | } | |
251 | ||
252 | main "$@" |