image-helpers.sh 9.3 KB

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