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