-
Notifications
You must be signed in to change notification settings - Fork 0
/
build
executable file
·333 lines (280 loc) · 8.62 KB
/
build
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
#!/bin/bash
#
# build environment for building MySQL from src.rpms
#
myname=$(basename $0)
log () {
echo "$(date +'%Y-%m-%d %H:%M:%S') $myname[$$]: $@"
}
exit_error () {
log "ERROR: $@"
exit 1
}
# Set MAJOR_VERSION from VERSION_ID in /etc/os-release if not set.
# - MAJOR_VERSION will be a single digit major version
get_os_and_version () {
if [ -z "$ID" ]; then
. /etc/os-release
case $ID in
almalinux|ol|rocky|centos|rhel)
# convert to a single digit if there's a decimal part
MAJOR_VERSION=$(echo $VERSION_ID | sed -e 's/\..*//')
;;
*)
exit_error "Unrecognised OS: $NAME ($ID $VERSION_ID). Provide a patch to support your linux version if needed."
esac
fi
}
setup_build_user () {
if ! grep $BUILD_USER /etc/passwd; then
log "### Adding missing build user: $BUILD_USER"
useradd -m $BUILD_USER
else
log "### Required build user $BUILD_USER already present"
fi
# Create missing directories used for persisting data
local directories="/data/SRPMS /data/log /data/built"
local dir
for dir in $directories; do
if ! test -d $dir; then
log "Creating missing directory: $dir, ownership set to $BUILD_USER:$BUILD_USER"
mkdir -p $dir
chown $BUILD_USER:$BUILD_USER $dir
fi
done
}
# Install the appropriate src.rpm from upstream sources
# - keep local copy to speed up process so if we do this frequently
install_srpms () {
local SRPMS="$1" # space separated list of src.rpms to install from urls
local location
local rpm
local url
log "########################################################"
log "# Installing SRPMS #"
log "########################################################"
echo
for url in $SRPMS; do
log "- Want to install $url"
rpm=$(basename $url)
location=/data/SRPMS/$rpm
if [ -e $location ]; then
log "- Found cached $location"
else
log "- Downloading $url to $location"
( cd /data/SRPMS && wget $url )
fi
log "- Installing $url from $location"
rpm -ivh $location
done
log "- SRPMS installed:"
ls -l ~/rpmbuild/SOURCES/ ~/rpmbuild/SPECS
echo
}
# - just copy the file and log
copy_file () {
local src=$1
local dst=$2
log "- copying $src to $dst"
cp $src $dst
}
copy_files () {
local srcdir=$1
local dstdir=$2
local file
if [ -d $srcdir ]; then
for file in $srcdir/*; do
copy_file $file $dstdir/
done
fi
}
# install custom patches / sources for the specified build version if provided.
# - assume running as $BUILD_USER user
install_custom_patches () {
local version="$1"
local dir
if [ -d /data/config/$version ]; then
log "- applying custom patches for $version"
for dir in SPECS SOURCES; do
if [ $(find /data/config/$version/$dir -type f | wc -l) != 0 ]; then
copy_files /data/config/$version/$dir ~/rpmbuild/$dir
fi
done
# applying patches if present to spec file
# - applied in filesort order
if [ $(find ~/rpmbuild/SPECS -type f -name "*patch*" | wc -l) != 0 ]; then
for file in ~/rpmbuild/SPECS/*patch*; do
log "- applying patch: $file"
( cd ~/rpmbuild/SPECS && patch -p0 < $file )
done
fi
else
log "- No custom patches to apply for $version"
fi
}
# return the src rpm location based on the build version / OS we are building
get_srpm_location () {
awk -v os_version="${ID}${MAJOR_VERSION}" -v mysql_label=$mysql_label 'mysql_label == $1 && os_version == $2 { print $5 }' $config
}
# build package
# - FIXME (add signing)
rpmbuild_rpms () {
local label=${mysql_label}__${ID}${VERSION_ID}__$(date +%Y%m%d.%H%M%S)
cd ~/rpmbuild/SPECS
# Careful with spacing and quoting!
log "### rpmbuild started at $(date)"
set -x
rpmbuild --define 'el'$MAJOR_VERSION' 1' -ba mysql.spec
rc=$?
set +x
log "### rpmbuild terminated at $(date), exit status: $rc"
# If build is successful record the installed package list,
# or record the failed list as that may need fixing.
rpm_qa=/data/log/rpm-qa.$label
if [ $rc = 0 ]; then
rpm -qa | sort > $rpm_qa
else
rpm -qa | sort > $rpm_qa.failed
fi
return $rc
}
# run the BUILD_USER stage: build rpms as the build user.
build_rpm_stage () {
set -o pipefail
local logfile=/data/log/build__${label}.log
log "Sending build logging to $logfile"
build_rpm_stage_logged 2>&1 | tee -a $logfile
}
get_build_script () {
awk -v os_version="${ID}${MAJOR_VERSION}" -v mysql_label=$mysql_label 'mysql_label == $1 && os_version == $2 { print $4 }' $config
}
# run the BUILD_USER stage with logging enabled
build_rpm_stage_logged () {
local build_script
local final_location
log "### Starting build stage at $(date)"
build_script=$(get_build_script)
if [ -z "$build_script" ]; then
exit_error "No rpm build script defined for ${ID}${MAJOR_VERSION} and ${mysql_label}. Please configure one."
fi
build_script=/data/config/build/$build_script
if [ ! -e "$build_script" ]; then
log "Missing build script in $build_script to build $mysql_label on $ID${MAJOR_VERSION}"
log "MAJOR_VERSION: $MAJOR_VERSION"
log "NAME: $NAME"
log "ID: $ID"
log "VERSION_ID: $VERSION_ID"
log "mysql_label: $mysql_label"
exit 1
fi
log "Sourcing: $build_script"
. $build_script
log "Sourcing: $build_script complete"
build
rc=$?
if [ $rc = 0 ]; then
# Move built rpms to built location to ensure that they are kept
log "### Build succeeded, moving rpms to /data/built"
final_location=/data/built/${ID}${MAJOR_VERSION}__${mysql_label}
if [ ! -d $final_location ]; then
log "- creating directory $final_location"
mkdir -p $final_location
fi
for file in ~/rpmbuild/SRPMS/*.rpm ~/rpmbuild/RPMS/*/*.rpm; do
log "- moving $file --> $final_location"
mv $file $final_location/
done
cp /etc/os-release $final_location/etc_os-release
fi
log "### Completed build stage at $(date) in $SECONDS seconds with exit status: $rc"
}
# run the root user stage: prepare the OS for the build
ossetup_stage () {
local logfile=/data/log/ossetup__${label}.log
log "Sending prepare logging to $logfile"
set -o pipefail
ossetup_stage_logged 2>&1 | tee -a $logfile
log "ossetup_stage_logged took $SECONDS seconds to run" | tee -a $logfile
# Complete the rpm build part if requested.
# - if not indicate how to proceed
if [ -z "$build_all" ]; then
log "Continue the build as $BUILD_USER by doing:"
log
log " su - $BUILD_USER /data/build $mysql_label"
log
log "Alternatively rerun the complete process in one go with:"
log
log " $0 -a $mysql_label"
log
exit 0
fi
log "##############################################################"
log "# Switching to user $BUILD_USER to complete the rpm build"
log "##############################################################"
echo
su - $BUILD_USER $0 $mysql_label
}
get_ossetup_script () {
awk -v os_version="${ID}${MAJOR_VERSION}" -v mysql_label=$mysql_label 'mysql_label == $1 && os_version == $2 { print $3 }' $config
}
ossetup_stage_logged () {
ossetup_script=$(get_ossetup_script)
if [ -z "$ossetup_script" ]; then
exit_error "No OS prepare script defined for ${ID}${MAJOR_VERSION} and ${mysql_label}. Please configure one."
fi
ossetup_script=/data/config/ossetup/$ossetup_script
if [ ! -e "$ossetup_script" ]; then
log "Missing prepare script '$ossetup_script' prepare operating system $NAME ($ID $VERSION_ID) to build MySQL version $mysql_label"
log "MAJOR_VERSION: $MAJOR_VERSION"
log "NAME: $NAME"
log "ID: $ID"
log "VERSION_ID: $VERSION_ID"
log "mysql_label: $mysql_label"
exit 1
fi
log "########################################################"
log "# Preparing OS: $NAME ($ID $VERSION_ID)"
log "# for building rpms with label $mysql_label"
log "########################################################"
echo
log "Sourcing: $ossetup_script"
. $ossetup_script
log "Sourcing: $ossetup_script complete"
prepare
setup_build_user
log
log "########################################################"
log "# Completed OS: $NAME ($ID $VERSION_ID) preparation"
log "# for building rpms with label $mysql_label"
log "########################################################"
echo
}
config=/data/build.conf
BUILD_USER=rpmbuild
build_all=
set -e
if [ -z "$USER" ]; then
USER=$(id -un)
fi
while getopts an flag; do
case $flag in
a) build_all=1 ;;
n) build_all= ;;
*) exit_error "INVALID FLAG $flag"
esac
done
shift $(($OPTIND - 1))
mysql_label=$1
if [ -z "$mysql_label" ]; then
exit_error "Please provide mysql_label name for building"
fi
log "Getting OS version info"
get_os_and_version
log "NAME: $NAME, ID: $ID, MAJOR_VERSION: $MAJOR_VERSION, VERSION_ID: $VERSION_ID"
# Used for logging
label=${mysql_label}__${ID}${MAJOR_VERSION}__$(date +%Y%m%d.%H%M%S)
case "$USER" in
root) ossetup_stage;;
$BUILD_USER) build_rpm_stage;;
*) exit_error "unexpected USER $USER, please call the script properly"
esac