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