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/image-helpers.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
# mount_chroot
13
# umount_chroot
14
# unmount_on_exit
15
# check_loop_device
16
# install_external_applications
17
# write_uboot
18
# copy_all_packages_files_for
19
# customize_image
20
# install_deb_chroot
21
# run_on_sdcard
22
23
24
25
26
# mount_chroot <target>
27
#
28
# helper to reduce code duplication
29
#
30
mount_chroot()
31
{
32
33
local target=$1
34
mount -t proc chproc "${target}"/proc
35
mount -t sysfs chsys "${target}"/sys
36
mount -t devtmpfs chdev "${target}"/dev || mount --bind /dev "${target}"/dev
37
mount -t devpts chpts "${target}"/dev/pts
38
39
}
40
41
42
43
44
# umount_chroot <target>
45
#
46
# helper to reduce code duplication
47
#
48
umount_chroot()
49
{
50
51
local target=$1
52
display_alert "Unmounting" "$target" "info"
53
while grep -Eq "${target}.*(dev|proc|sys)" /proc/mounts
54
do
55
umount -l --recursive "${target}"/dev >/dev/null 2>&1
56
umount -l "${target}"/proc >/dev/null 2>&1
57
umount -l "${target}"/sys >/dev/null 2>&1
58
sleep 5
59
done
60
61
}
62
63
64
65
66
# unmount_on_exit
67
#
68
unmount_on_exit()
69
{
70
71
trap - INT TERM EXIT
72
local stacktrace="$(get_extension_hook_stracktrace "${BASH_SOURCE[*]}" "${BASH_LINENO[*]}")"
73
display_alert "unmount_on_exit() called!" "$stacktrace" "err"
74
if [[ "${ERROR_DEBUG_SHELL}" == "yes" ]]; then
75
ERROR_DEBUG_SHELL=no # dont do it twice
76
display_alert "MOUNT" "${MOUNT}" "err"
77
display_alert "SDCARD" "${SDCARD}" "err"
78
display_alert "ERROR_DEBUG_SHELL=yes, starting a shell." "ERROR_DEBUG_SHELL" "err"
79
bash < /dev/tty || true
80
fi
81
82
umount_chroot "${SDCARD}/"
83
umount -l "${SDCARD}"/tmp >/dev/null 2>&1
84
umount -l "${SDCARD}" >/dev/null 2>&1
85
umount -l "${MOUNT}"/boot >/dev/null 2>&1
86
umount -l "${MOUNT}" >/dev/null 2>&1
87
[[ $CRYPTROOT_ENABLE == yes ]] && cryptsetup luksClose "${ROOT_MAPPER}"
88
losetup -d "${LOOP}" >/dev/null 2>&1
89
rm -rf --one-file-system "${SDCARD}"
90
exit_with_error "debootstrap-ng was interrupted" || true # don't trigger again
91
92
}
93
94
95
96
97
# check_loop_device <device_node>
98
#
99
check_loop_device()
100
{
101
102
local device=$1
103
if [[ ! -b $device ]]; then
104
if [[ $CONTAINER_COMPAT == yes && -b /tmp/$device ]]; then
105
display_alert "Creating device node" "$device"
106
mknod -m0660 "${device}" b "0x$(stat -c '%t' "/tmp/$device")" "0x$(stat -c '%T' "/tmp/$device")"
107
else
108
exit_with_error "Device node $device does not exist"
109
fi
110
fi
111
112
}
113
114
115
116
117
# write_uboot <loopdev>
118
#
119
write_uboot()
120
{
121
122
local loop=$1 revision
123
display_alert "Writing U-boot bootloader" "$loop" "info"
124
TEMP_DIR=$(mktemp -d || exit 1)
125
chmod 700 ${TEMP_DIR}
126
revision=${REVISION}
127
if [[ -n $UPSTREM_VER ]]; then
128
revision=${UPSTREM_VER}
129
dpkg -x "${DEB_STORAGE}/u-boot/linux-u-boot-${BOARD}-${BRANCH}_${revision}_${ARCH}.deb" ${TEMP_DIR}/
130
else
131
dpkg -x "${DEB_STORAGE}/u-boot/${CHOSEN_UBOOT}_${revision}_${ARCH}.deb" ${TEMP_DIR}/
132
fi
133
134
# source platform install to read $DIR
135
source ${TEMP_DIR}/usr/lib/u-boot/platform_install.sh
136
write_uboot_platform "${TEMP_DIR}${DIR}" "$loop"
137
[[ $? -ne 0 ]] && exit_with_error "U-boot bootloader failed to install" "@host"
138
rm -rf ${TEMP_DIR}
139
140
}
141
142
143
144
145
# copy_all_packages_files_for <folder> to package
146
#
147
copy_all_packages_files_for()
148
{
149
local package_name="${1}"
150
for package_src_dir in ${PACKAGES_SEARCH_ROOT_ABSOLUTE_DIRS};
151
do
152
local package_dirpath="${package_src_dir}/${package_name}"
153
if [ -d "${package_dirpath}" ];
154
then
155
cp -r "${package_dirpath}/"* "${destination}/" 2> /dev/null
156
display_alert "Adding files from" "${package_dirpath}"
157
fi
158
done
159
}
160
161
162
163
164
customize_image()
165
{
166
167
# for users that need to prepare files at host
168
[[ -f $USERPATCHES_PATH/customize-image-host.sh ]] && source "$USERPATCHES_PATH"/customize-image-host.sh
169
170
call_extension_method "pre_customize_image" "image_tweaks_pre_customize" << 'PRE_CUSTOMIZE_IMAGE'
171
*run before customize-image.sh*
172
This hook is called after `customize-image-host.sh` is called, but before the overlay is mounted.
173
It thus can be used for the same purposes as `customize-image-host.sh`.
174
PRE_CUSTOMIZE_IMAGE
175
176
cp "$USERPATCHES_PATH"/customize-image.sh "${SDCARD}"/tmp/customize-image.sh
177
chmod +x "${SDCARD}"/tmp/customize-image.sh
178
mkdir -p "${SDCARD}"/tmp/overlay
179
# util-linux >= 2.27 required
180
mount -o bind,ro "$USERPATCHES_PATH"/overlay "${SDCARD}"/tmp/overlay
181
display_alert "Calling image customization script" "customize-image.sh" "info"
182
chroot "${SDCARD}" /bin/bash -c "/tmp/customize-image.sh $RELEASE $LINUXFAMILY $BOARD $BUILD_DESKTOP $ARCH"
183
CUSTOMIZE_IMAGE_RC=$?
184
umount -i "${SDCARD}"/tmp/overlay >/dev/null 2>&1
185
mountpoint -q "${SDCARD}"/tmp/overlay || rm -r "${SDCARD}"/tmp/overlay
186
if [[ $CUSTOMIZE_IMAGE_RC != 0 ]]; then
187
exit_with_error "customize-image.sh exited with error (rc: $CUSTOMIZE_IMAGE_RC)"
188
fi
189
190
call_extension_method "post_customize_image" "image_tweaks_post_customize" << 'POST_CUSTOMIZE_IMAGE'
191
*post customize-image.sh hook*
192
Run after the customize-image.sh script is run, and the overlay is unmounted.
193
POST_CUSTOMIZE_IMAGE
194
}
195
196
197
198
199
install_deb_chroot()
200
{
201
202
local package=$1
203
local variant=$2
204
local transfer=$3
205
local name
206
local desc
207
if [[ ${variant} != remote ]]; then
208
name="/root/"$(basename "${package}")
209
[[ ! -f "${SDCARD}${name}" ]] && cp "${package}" "${SDCARD}${name}"
210
desc=""
211
else
212
name=$1
213
desc=" from repository"
214
fi
215
216
display_alert "Installing${desc}" "${name/\/root\//}"
217
[[ $NO_APT_CACHER != yes ]] && local apt_extra="-o Acquire::http::Proxy=\"http://${APT_PROXY_ADDR:-localhost:3142}\" -o Acquire::http::Proxy::localhost=\"DIRECT\""
218
# when building in bulk from remote, lets make sure we have up2date index
219
[[ $BUILD_ALL == yes && ${variant} == remote ]] && chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get $apt_extra -yqq update"
220
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq $apt_extra --no-install-recommends install $name" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
221
[[ $? -ne 0 ]] && exit_with_error "Installation of $name failed" "${BOARD} ${RELEASE} ${BUILD_DESKTOP} ${LINUXFAMILY}"
222
[[ ${variant} == remote && ${transfer} == yes ]] && rsync -rq "${SDCARD}"/var/cache/apt/archives/*.deb ${DEB_STORAGE}/
223
224
}
225
226
227
228
dpkg_install_deb_chroot()
229
{
230
231
local package=$1
232
local name
233
local desc
234
235
name="/root/"$(basename "${package}")
236
[[ ! -f "${SDCARD}${name}" ]] && cp "${package}" "${SDCARD}${name}"
237
238
display_alert "Installing${desc}" "${name/\/root\//}"
239
240
# when building in bulk from remote, lets make sure we have up2date index
241
chroot "${SDCARD}" /bin/bash -c "dpkg -i $name" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
242
chroot "${SDCARD}" /bin/bash -c "dpkg-deb -f $name Package | xargs apt-mark hold" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
243
[[ $? -ne 0 ]] && exit_with_error "Installation of $name failed" "${BOARD} ${RELEASE} ${BUILD_DESKTOP} ${LINUXFAMILY}"
244
245
}
246
247
dpkg_install_debs_chroot()
248
{
249
local deb_dir=$1
250
local unsatisfied_dependencies=()
251
local package_names=()
252
local package_dependencies=()
253
254
[ ! -d "$deb_dir" ] && return
255
256
deb_packages=($(find "${deb_dir}/" -mindepth 1 -maxdepth 1 -type f -name "*.deb"))
257
258
find_in_array() {
259
local target="$1"
260
local element=""
261
shift
262
for element in "$@"; do
263
[[ "$element" == "$target" ]] && return 0
264
done
265
return 1
266
}
267
268
for package in "${deb_packages[@]}"; do
269
package_names+=($(dpkg-deb -f "$package" Package))
270
271
dep_str=$(dpkg-deb -I "${package}" | grep 'Depends' | sed 's/.*: //' | sed 's/ //g' | sed 's/([^)]*)//g')
272
IFS=',' read -ra dep_array <<< "$dep_str"
273
274
if [[ ! ${#dep_array[@]} -eq 0 ]]; then
275
#dep_array[-1]="${dep_array[-1]} "
276
277
for element in "${dep_array[@]}"; do
278
if [[ $element == *"|"* ]]; then
279
#dep_array=("${dep_array[@]/$element}")
280
:
281
else
282
if ! find_in_array "$element" "${package_dependencies[@]}"; then
283
package_dependencies+=("${element}")
284
fi
285
fi
286
done
287
288
fi
289
done
290
291
for dependency in "${package_dependencies[@]}"; do
292
if ! chroot "${SDCARD}" /bin/bash -c "dpkg-query -W --showformat='\${Status}' ${dependency} \
293
| grep -q 'ok installed'" &>/dev/null; then
294
295
all=("${package_names[@]}" "${unsatisfied_dependencies[@]}")
296
297
if ! find_in_array "$dependency" "${all[@]}"; then
298
unsatisfied_dependencies+=("$dependency")
299
fi
300
fi
301
done
302
303
if [[ ! -z "${unsatisfied_dependencies[*]}" ]]; then
304
display_alert "Installing Dependencies" "${unsatisfied_dependencies[*]}"
305
chroot $SDCARD /bin/bash -c "apt-get -y -qq install ${unsatisfied_dependencies[*]}" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
306
fi
307
308
local names=""
309
for package in "${deb_packages[@]}"; do
310
name="/root/"$(basename "${package}")
311
names+=($name)
312
[[ ! -f "${SDCARD}${name}" ]] && cp "${package}" "${SDCARD}${name}"
313
done
314
315
if [[ ! -z "${names[*]}" ]]; then
316
display_alert "Installing" "$(basename $deb_dir)"
317
318
# when building in bulk from remote, lets make sure we have up2date index
319
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive dpkg -i ${names[*]} " >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
320
[[ $? -ne 0 ]] && exit_with_error "Installation of $(basename $deb_dir) failed" "${BOARD} ${RELEASE} ${BUILD_DESKTOP} ${LINUXFAMILY}"
321
chroot "${SDCARD}" /bin/bash -c "apt-mark hold ${package_names[*]}" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
322
fi
323
}
324
325
run_on_sdcard()
326
{
327
328
# Lack of quotes allows for redirections and pipes easily.
329
chroot "${SDCARD}" /bin/bash -c "${@}" >> "${DEST}"/${LOG_SUBPATH}/install.log
330
331
}
332
333