CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/scripts/chroot-buildpackages.sh
Views: 3960
1
#!/bin/bash
2
#
3
# Copyright (c) 2013-2021 Igor Pecovnik, igor.pecovnik@gma**.com
4
#
5
# This file is licensed under the terms of the GNU General Public
6
# License version 2. This program is licensed "as is" without any
7
# warranty of any kind, whether express or implied.
8
9
10
# Functions:
11
12
# create_chroot
13
# chroot_prepare_distccd
14
# chroot_build_packages
15
# chroot_installpackages_local
16
# chroot_installpackages
17
18
19
20
21
# create_chroot <target_dir> <release> <arch>
22
#
23
create_chroot()
24
{
25
local target_dir="$1"
26
local release=$2
27
local arch=$3
28
declare -A qemu_binary apt_mirror components
29
qemu_binary['armhf']='qemu-arm-static'
30
qemu_binary['arm64']='qemu-aarch64-static'
31
apt_mirror['stretch']="$DEBIAN_MIRROR"
32
apt_mirror['buster']="$DEBIAN_MIRROR"
33
apt_mirror['bullseye']="$DEBIAN_MIRROR"
34
apt_mirror['bookworm']="$DEBIAN_MIRROR"
35
apt_mirror['xenial']="$UBUNTU_MIRROR"
36
apt_mirror['bionic']="$UBUNTU_MIRROR"
37
apt_mirror['focal']="$UBUNTU_MIRROR"
38
apt_mirror['hirsute']="$UBUNTU_MIRROR"
39
apt_mirror['impish']="$UBUNTU_MIRROR"
40
components['stretch']='main,contrib'
41
apt_mirror['jammy']="$UBUNTU_MIRROR"
42
apt_mirror['noble']="$UBUNTU_MIRROR"
43
components['buster']='main,contrib'
44
components['bullseye']='main,contrib'
45
components['bookworm']='main,contrib'
46
components['sid']='main'
47
components['xenial']='main,universe,multiverse'
48
components['bionic']='main,universe,multiverse'
49
components['focal']='main,universe,multiverse'
50
components['hirsute']='main,universe,multiverse'
51
components['impish']='main,universe,multiverse'
52
components['jammy']='main,universe,multiverse'
53
components['noble']='main,universe,multiverse'
54
display_alert "Creating build chroot" "$release/$arch" "info"
55
local includes="ccache,locales,git,ca-certificates,devscripts,libfile-fcntllock-perl,debhelper,rsync,python3,distcc,apt-utils"
56
57
# perhaps a temporally workaround
58
case $release in
59
buster|bullseye|focal|hirsute|sid|bookworm)
60
includes=${includes}",perl-openssl-defaults,libnet-ssleay-perl"
61
;;
62
esac
63
64
if [[ $NO_APT_CACHER != yes ]]; then
65
local mirror_addr="http://localhost:3142/${apt_mirror[${release}]}"
66
else
67
local mirror_addr="http://${apt_mirror[${release}]}"
68
fi
69
70
mkdir -p "${target_dir}"
71
cd "${target_dir}"
72
73
debootstrap --variant=buildd \
74
--components="${components[${release}]}" \
75
--arch="${arch}" $DEBOOTSTRAP_OPTION \
76
--foreign \
77
--include="${includes}" "${release}" "${target_dir}" "${mirror_addr}"
78
79
[[ $? -ne 0 || ! -f "${target_dir}"/debootstrap/debootstrap ]] && \
80
exit_with_error "Create chroot first stage failed"
81
82
cp /usr/bin/${qemu_binary[$arch]} "${target_dir}"/usr/bin/
83
[[ ! -f "${target_dir}"/usr/share/keyrings/debian-archive-keyring.gpg ]] && \
84
mkdir -p "${target_dir}"/usr/share/keyrings/ && \
85
cp /usr/share/keyrings/debian-archive-keyring.gpg "${target_dir}"/usr/share/keyrings/
86
87
chroot "${target_dir}" /bin/bash -c "/debootstrap/debootstrap --second-stage"
88
[[ $? -ne 0 || ! -f "${target_dir}"/bin/bash ]] && exit_with_error "Create chroot second stage failed"
89
90
create_sources_list "$release" "${target_dir}"
91
[[ $NO_APT_CACHER != yes ]] && \
92
echo 'Acquire::http { Proxy "http://localhost:3142"; };' > "${target_dir}"/etc/apt/apt.conf.d/02proxy
93
cat <<-EOF > "${target_dir}"/etc/apt/apt.conf.d/71-no-recommends
94
APT::Install-Recommends "0";
95
APT::Install-Suggests "0";
96
EOF
97
[[ -f "${target_dir}"/etc/locale.gen ]] && \
98
sed -i "s/^# en_US.UTF-8/en_US.UTF-8/" "${target_dir}"/etc/locale.gen
99
chroot "${target_dir}" /bin/bash -c "locale-gen; update-locale LANG=en_US:en LC_ALL=en_US.UTF-8"
100
101
printf '#!/bin/sh\nexit 101' > "${target_dir}"/usr/sbin/policy-rc.d
102
chmod 755 "${target_dir}"/usr/sbin/policy-rc.d
103
rm "${target_dir}"/etc/resolv.conf 2>/dev/null
104
echo "nameserver $NAMESERVER" > "${target_dir}"/etc/resolv.conf
105
rm "${target_dir}"/etc/hosts 2>/dev/null
106
echo "127.0.0.1 localhost" > "${target_dir}"/etc/hosts
107
mkdir -p "${target_dir}"/root/{build,overlay,sources} "${target_dir}"/selinux
108
if [[ -L "${target_dir}"/var/lock ]]; then
109
rm -rf "${target_dir}"/var/lock 2>/dev/null
110
mkdir -p "${target_dir}"/var/lock
111
fi
112
chroot "${target_dir}" /bin/bash -c "/usr/sbin/update-ccache-symlinks"
113
114
display_alert "Upgrading packages in" "${target_dir}" "info"
115
chroot "${target_dir}" /bin/bash -c "apt-get -q update; apt-get -q -y upgrade; apt-get clean"
116
date +%s >"$target_dir/root/.update-timestamp"
117
118
case $release in
119
bullseye|focal|hirsute|sid|bookworm)
120
chroot "${target_dir}" /bin/bash -c "apt-get install python-is-python3"
121
;;
122
esac
123
124
touch "${target_dir}"/root/.debootstrap-complete
125
display_alert "Debootstrap complete" "${release}/${arch}" "info"
126
} #############################################################################
127
128
129
# chroot_prepare_distccd <release> <arch>
130
#
131
chroot_prepare_distccd()
132
{
133
local release=$1
134
local arch=$2
135
local dest=/tmp/distcc/${release}-${arch}
136
declare -A gcc_version gcc_type
137
gcc_version['stretch']='6.3'
138
gcc_version['buster']='8.3'
139
gcc_version['bullseye']='9.2'
140
gcc_version['bookworm']='10.2'
141
gcc_version['xenial']='5.4'
142
gcc_version['bionic']='5.4'
143
gcc_version['focal']='9.2'
144
gcc_version['jammy']='10.2'
145
gcc_version['noble']='13.2'
146
gcc_version['hirsute']='10.2'
147
gcc_version['sid']='10.2'
148
gcc_type['armhf']='arm-linux-gnueabihf-'
149
gcc_type['arm64']='aarch64-linux-gnu-'
150
rm -f "${dest}"/cmdlist
151
mkdir -p "${dest}"
152
local toolchain_path
153
#local toolchain_path=$(find_toolchain "${gcc_type[${arch}]}" "== ${gcc_version[${release}]}")
154
toolchain_path=${toolchain}
155
ln -sf "${toolchain_path}/${gcc_type[${arch}]}gcc" "${dest}"/cc
156
echo "${dest}/cc" >> "${dest}"/cmdlist
157
for compiler in gcc cpp g++ c++; do
158
echo "${dest}/$compiler" >> "${dest}"/cmdlist
159
echo "${dest}/${gcc_type[$arch]}${compiler}" >> "${dest}"/cmdlist
160
ln -sf "${toolchain_path}/${gcc_type[${arch}]}${compiler}" "${dest}/${compiler}"
161
ln -sf "${toolchain_path}/${gcc_type[${arch}]}${compiler}" "${dest}/${gcc_type[${arch}]}${compiler}"
162
done
163
mkdir -p /var/run/distcc/
164
touch /var/run/distcc/"${release}-${arch}".pid
165
chown -R distccd /var/run/distcc/
166
chown -R distccd /tmp/distcc
167
}
168
169
# chroot_build_packages
170
#
171
chroot_build_packages()
172
{
173
local built_ok=()
174
local failed=()
175
176
if [[ $IMAGE_TYPE == user-built ]]; then
177
# if user-built image compile only for selected arch/release
178
target_release="${RELEASE}"
179
target_arch="${ARCH}"
180
else
181
# only make packages for recent releases. There are no changes on older
182
target_release="stretch bionic buster bullseye bookworm focal hirsute jammy noble sid"
183
target_arch="armhf arm64"
184
fi
185
186
for release in $target_release; do
187
for arch in $target_arch; do
188
display_alert "Starting package building process" "$release/$arch" "info"
189
190
local target_dir
191
target_dir="${EXTER}/cache/buildpkg/${release}-${arch}-v${CHROOT_CACHE_VERSION}"
192
local distcc_bindaddr="127.0.0.2"
193
194
[[ ! -f "${target_dir}"/root/.debootstrap-complete ]] && create_chroot "${target_dir}" "${release}" "${arch}"
195
[[ ! -f "${target_dir}"/root/.debootstrap-complete ]] && exit_with_error "Creating chroot failed" "${release}/${arch}"
196
197
[[ -f /var/run/distcc/"${release}-${arch}".pid ]] && kill "$(<"/var/run/distcc/${release}-${arch}.pid")" > /dev/null 2>&1
198
199
chroot_prepare_distccd "${release}" "${arch}"
200
201
# DISTCC_TCP_DEFER_ACCEPT=0
202
DISTCC_CMDLIST=/tmp/distcc/${release}-${arch}/cmdlist TMPDIR=/tmp/distcc distccd --daemon \
203
--pid-file "/var/run/distcc/${release}-${arch}.pid" --listen $distcc_bindaddr --allow 127.0.0.0/24 \
204
--log-file "/tmp/distcc/${release}-${arch}.log" --user distccd
205
206
local t=$target_dir/root/.update-timestamp
207
if [[ ! -f ${t} || $(( ($(date +%s) - $(<"${t}")) / 86400 )) -gt 7 ]]; then
208
display_alert "Upgrading packages" "$release/$arch" "info"
209
systemd-nspawn -a -q -D "${target_dir}" /bin/bash -c "apt-get -q update; apt-get -q -y upgrade; apt-get clean"
210
date +%s > "${t}"
211
fi
212
213
for plugin in "${EXTER}"/packages/extras-buildpkgs/*.conf; do
214
unset package_name package_repo package_ref package_builddeps package_install_chroot package_install_target \
215
package_upstream_version needs_building plugin_target_dir package_component "package_builddeps_${release}"
216
source "${plugin}"
217
218
# check build condition
219
if [[ $(type -t package_checkbuild) == function ]] && ! package_checkbuild; then
220
display_alert "Skipping building $package_name for" "$release/$arch"
221
continue
222
fi
223
224
local plugin_target_dir=${DEB_STORAGE}/extra/$package_component/
225
mkdir -p "${plugin_target_dir}"
226
227
# check if needs building
228
local needs_building=no
229
if [[ -n $package_install_target ]]; then
230
for f in $package_install_target; do
231
if [[ -z $(find "${plugin_target_dir}" -name "${f}_*$REVISION*_$arch.deb") ]]; then
232
needs_building=yes
233
break
234
fi
235
done
236
else
237
needs_building=yes
238
fi
239
if [[ $needs_building == no ]]; then
240
display_alert "Packages are up to date" "$package_name $release/$arch" "info"
241
continue
242
fi
243
display_alert "Building packages" "$package_name $release/$arch" "ext"
244
local dist_builddeps_name="package_builddeps_${release}"
245
[[ -v $dist_builddeps_name ]] && package_builddeps="${package_builddeps} ${!dist_builddeps_name}"
246
247
# create build script
248
create_build_script
249
250
fetch_from_repo "$package_repo" "${EXTER}/cache/sources/extra/$package_name" "$package_ref"
251
252
eval systemd-nspawn -a -q \
253
--capability=CAP_MKNOD -D "${target_dir}" \
254
--tmpfs=/root/build \
255
--tmpfs=/tmp:mode=777 \
256
--bind-ro "${EXTER}"/packages/extras-buildpkgs/:/root/overlay \
257
--bind-ro "${EXTER}"/cache/sources/extra/:/root/sources /bin/bash -c "/root/build.sh" 2>&1 \
258
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/buildpkg.log'}
259
260
if [[ ${PIPESTATUS[0]} -eq 2 ]]; then
261
failed+=("$package_name:$release/$arch")
262
else
263
built_ok+=("$package_name:$release/$arch")
264
fi
265
mv "${target_dir}"/root/*.deb "${plugin_target_dir}" 2>/dev/null
266
done
267
# cleanup for distcc
268
kill "$(<"/var/run/distcc/${release}-${arch}.pid")"
269
done
270
done
271
if [[ ${#built_ok[@]} -gt 0 ]]; then
272
display_alert "Following packages were built without errors" "" "info"
273
for p in ${built_ok[@]}; do
274
display_alert "$p"
275
done
276
fi
277
if [[ ${#failed[@]} -gt 0 ]]; then
278
display_alert "Following packages failed to build" "" "wrn"
279
for p in ${failed[@]}; do
280
display_alert "$p"
281
done
282
fi
283
} #############################################################################
284
285
# create build script
286
create_build_script ()
287
{
288
cat <<-EOF > "${target_dir}"/root/build.sh
289
#!/bin/bash
290
export PATH="/usr/lib/ccache:\$PATH"
291
export HOME="/root"
292
export DEBIAN_FRONTEND="noninteractive"
293
export DEB_BUILD_OPTIONS="nocheck noautodbgsym"
294
export CCACHE_TEMPDIR="/tmp"
295
# distcc is disabled to prevent compilation issues due
296
# to different host and cross toolchain configurations
297
#export CCACHE_PREFIX="distcc"
298
# uncomment for debug
299
#export CCACHE_RECACHE="true"
300
#export CCACHE_DISABLE="true"
301
export DISTCC_HOSTS="$distcc_bindaddr"
302
export DEBFULLNAME="$MAINTAINER"
303
export DEBEMAIL="$MAINTAINERMAIL"
304
$(declare -f display_alert)
305
306
cd /root/build
307
if [[ -n "${package_builddeps}" ]]; then
308
# can be replaced with mk-build-deps
309
deps=()
310
installed=\$(
311
dpkg-query -W -f '\${db:Status-Abbrev}|\${binary:Package}\n' '*' 2>/dev/null | \
312
grep '^ii' | \
313
awk -F '|' '{print \$2}' | \
314
cut -d ':' -f 1
315
)
316
317
for packet in $package_builddeps
318
do
319
grep -q -x -e "\$packet" <<< "\$installed" || deps+=("\$packet")
320
done
321
322
if [[ \${#deps[@]} -gt 0 ]]; then
323
display_alert "Installing build dependencies"
324
apt-get -y -q update
325
apt-get -y -q \
326
--no-install-recommends \
327
--show-progress \
328
-o DPKG::Progress-Fancy=1 install "\${deps[@]}"
329
fi
330
fi
331
332
display_alert "Copying sources"
333
rsync -aq /root/sources/"${package_name}" /root/build/
334
335
cd /root/build/"${package_name}"
336
# copy overlay / "debianization" files
337
[[ -d "/root/overlay/${package_name}/" ]] && rsync -aq /root/overlay/"${package_name}" /root/build/
338
339
# set upstream version
340
[[ -n "${package_upstream_version}" ]] && debchange --preserve --newversion "${package_upstream_version}" "Import from upstream"
341
342
# set local version
343
# debchange -l~orangepi${REVISION}-${builddate}+ "Custom $VENDOR release"
344
debchange -l~orangepi"${REVISION}"+ "Custom $VENDOR release"
345
346
display_alert "Building package"
347
dpkg-buildpackage -b -us -j2
348
349
if [[ \$? -eq 0 ]]; then
350
cd /root/build
351
# install in chroot if other libraries depend on them
352
if [[ -n "$package_install_chroot" ]]; then
353
display_alert "Installing packages"
354
for p in $package_install_chroot; do
355
dpkg -i \${p}_*.deb
356
done
357
fi
358
display_alert "Done building" "$package_name $release/$arch" "ext"
359
ls *.deb 2>/dev/null
360
mv *.deb /root 2>/dev/null
361
exit 0
362
else
363
display_alert "Failed building" "$package_name $release/$arch" "err"
364
exit 2
365
fi
366
EOF
367
368
chmod +x "${target_dir}"/root/build.sh
369
}
370
371
# chroot_installpackages_local
372
#
373
chroot_installpackages_local()
374
{
375
local conf=$EXTER/config/aptly-temp.conf
376
rm -rf /tmp/aptly-temp/
377
mkdir -p /tmp/aptly-temp/
378
aptly -config="${conf}" repo create temp >> "${DEST}"/${LOG_SUBPATH}/install.log
379
# NOTE: this works recursively
380
if [[ $EXTERNAL_NEW == prebuilt ]]; then
381
aptly -config="${conf}" repo add temp "${DEB_ORANGEPI}/extra/${RELEASE}-desktop/" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
382
aptly -config="${conf}" repo add temp "${DEB_ORANGEPI}/extra/${RELEASE}-utils/" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
383
else
384
aptly -config="${conf}" repo add temp "${DEB_STORAGE}/extra/${RELEASE}-desktop/" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
385
aptly -config="${conf}" repo add temp "${DEB_STORAGE}/extra/${RELEASE}-utils/" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
386
fi
387
388
# -gpg-key="925644A6"
389
[[ ! -d /root/.gnupg ]] && mkdir -p /root/.gnupg
390
aptly -keyring="$EXTER/packages/extras-buildpkgs/buildpkg-public.gpg" -secret-keyring="$EXTER/packages/extras-buildpkgs/buildpkg.gpg" -batch=true -config="${conf}" \
391
-gpg-key="925644A6" -passphrase="testkey1234" -component=temp -distribution="${RELEASE}" publish repo temp >> "${DEST}"/${LOG_SUBPATH}/install.log
392
#aptly -config="${conf}" -listen=":8189" serve &
393
aptly -config="${conf}" -listen=":8189" serve >> "${DEST}"/debug/install.log 2>&1 &
394
local aptly_pid=$!
395
cp $EXTER/packages/extras-buildpkgs/buildpkg.key "${SDCARD}"/tmp/buildpkg.key
396
cat <<-'EOF' > "${SDCARD}"/etc/apt/preferences.d/90-orangepi-temp.pref
397
Package: *
398
Pin: origin "localhost"
399
Pin-Priority: 550
400
EOF
401
cat <<-EOF > "${SDCARD}"/etc/apt/sources.list.d/orangepi-temp.list
402
deb http://localhost:8189/ $RELEASE temp
403
EOF
404
chroot_installpackages
405
kill "${aptly_pid}" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
406
} #############################################################################
407
408
# chroot_installpackages
409
#
410
chroot_installpackages()
411
{
412
local install_list=""
413
for plugin in "${EXTER}"/packages/extras-buildpkgs/*.conf; do
414
source "${plugin}"
415
if [[ $(type -t package_checkinstall) == function ]] && package_checkinstall; then
416
install_list="$install_list $package_install_target"
417
fi
418
unset package_install_target package_checkinstall
419
done
420
if [[ -n $PACKAGE_LIST_RM ]]; then
421
install_list=$(sed -r "s/\W($(tr ' ' '|' <<< ${PACKAGE_LIST_RM}))\W/ /g" <<< " ${install_list} ")
422
install_list="$(echo ${install_list})"
423
fi
424
display_alert "Installing extras-buildpkgs" "$install_list"
425
426
[[ $NO_APT_CACHER != yes ]] && local apt_extra="-o Acquire::http::Proxy=\"http://${APT_PROXY_ADDR:-localhost:3142}\" -o Acquire::http::Proxy::localhost=\"DIRECT\""
427
cat <<-EOF > "${SDCARD}"/tmp/install.sh
428
#!/bin/bash
429
apt-key add /tmp/buildpkg.key
430
apt-get $apt_extra -q update
431
apt-get -q ${apt_extra} --show-progress -o DPKG::Progress-Fancy=1 install -y ${install_list}
432
apt-get clean
433
apt-key del "925644A6"
434
rm /etc/apt/sources.list.d/orangepi-temp.list 2>/dev/null
435
rm /etc/apt/preferences.d/90-orangepi-temp.pref 2>/dev/null
436
rm /tmp/buildpkg.key 2>/dev/null
437
rm -- "\$0"
438
EOF
439
chmod +x "${SDCARD}"/tmp/install.sh
440
chroot "${SDCARD}" /bin/bash -c "/tmp/install.sh" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
441
442
[[ -f ${SDCARD}/etc/hostapd.conf ]] && sed -i "s/^ssid=.*/ssid=OrangePi/" ${SDCARD}/etc/hostapd.conf
443
} #############################################################################
444
445