Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/next/scripts/image-helpers.sh
Views: 3960
#!/bin/bash1#2# Copyright (c) 2013-2021 Igor Pecovnik, igor.pecovnik@gma**.com3#4# This file is licensed under the terms of the GNU General Public5# License version 2. This program is licensed "as is" without any6# warranty of any kind, whether express or implied.789# Functions:1011# mount_chroot12# umount_chroot13# unmount_on_exit14# check_loop_device15# install_external_applications16# write_uboot17# copy_all_packages_files_for18# customize_image19# install_deb_chroot20# run_on_sdcard2122232425# mount_chroot <target>26#27# helper to reduce code duplication28#29mount_chroot()30{3132local target=$133mount -t proc chproc "${target}"/proc34mount -t sysfs chsys "${target}"/sys35mount -t devtmpfs chdev "${target}"/dev || mount --bind /dev "${target}"/dev36mount -t devpts chpts "${target}"/dev/pts3738}3940414243# umount_chroot <target>44#45# helper to reduce code duplication46#47umount_chroot()48{4950local target=$151display_alert "Unmounting" "$target" "info"52while grep -Eq "${target}.*(dev|proc|sys)" /proc/mounts53do54umount -l --recursive "${target}"/dev >/dev/null 2>&155umount -l "${target}"/proc >/dev/null 2>&156umount -l "${target}"/sys >/dev/null 2>&157sleep 558done5960}6162636465# unmount_on_exit66#67unmount_on_exit()68{6970trap - INT TERM EXIT71local stacktrace="$(get_extension_hook_stracktrace "${BASH_SOURCE[*]}" "${BASH_LINENO[*]}")"72display_alert "unmount_on_exit() called!" "$stacktrace" "err"73if [[ "${ERROR_DEBUG_SHELL}" == "yes" ]]; then74ERROR_DEBUG_SHELL=no # dont do it twice75display_alert "MOUNT" "${MOUNT}" "err"76display_alert "SDCARD" "${SDCARD}" "err"77display_alert "ERROR_DEBUG_SHELL=yes, starting a shell." "ERROR_DEBUG_SHELL" "err"78bash < /dev/tty || true79fi8081umount_chroot "${SDCARD}/"82umount -l "${SDCARD}"/tmp >/dev/null 2>&183umount -l "${SDCARD}" >/dev/null 2>&184umount -l "${MOUNT}"/boot >/dev/null 2>&185umount -l "${MOUNT}" >/dev/null 2>&186[[ $CRYPTROOT_ENABLE == yes ]] && cryptsetup luksClose "${ROOT_MAPPER}"87losetup -d "${LOOP}" >/dev/null 2>&188rm -rf --one-file-system "${SDCARD}"89exit_with_error "debootstrap-ng was interrupted" || true # don't trigger again9091}9293949596# check_loop_device <device_node>97#98check_loop_device()99{100101local device=$1102if [[ ! -b $device ]]; then103if [[ $CONTAINER_COMPAT == yes && -b /tmp/$device ]]; then104display_alert "Creating device node" "$device"105mknod -m0660 "${device}" b "0x$(stat -c '%t' "/tmp/$device")" "0x$(stat -c '%T' "/tmp/$device")"106else107exit_with_error "Device node $device does not exist"108fi109fi110111}112113114115116# write_uboot <loopdev>117#118write_uboot()119{120121local loop=$1 revision122display_alert "Writing U-boot bootloader" "$loop" "info"123TEMP_DIR=$(mktemp -d || exit 1)124chmod 700 ${TEMP_DIR}125revision=${REVISION}126if [[ -n $UPSTREM_VER ]]; then127revision=${UPSTREM_VER}128dpkg -x "${DEB_STORAGE}/u-boot/linux-u-boot-${BOARD}-${BRANCH}_${revision}_${ARCH}.deb" ${TEMP_DIR}/129else130dpkg -x "${DEB_STORAGE}/u-boot/${CHOSEN_UBOOT}_${revision}_${ARCH}.deb" ${TEMP_DIR}/131fi132133# source platform install to read $DIR134source ${TEMP_DIR}/usr/lib/u-boot/platform_install.sh135write_uboot_platform "${TEMP_DIR}${DIR}" "$loop"136[[ $? -ne 0 ]] && exit_with_error "U-boot bootloader failed to install" "@host"137rm -rf ${TEMP_DIR}138139}140141142143144# copy_all_packages_files_for <folder> to package145#146copy_all_packages_files_for()147{148local package_name="${1}"149for package_src_dir in ${PACKAGES_SEARCH_ROOT_ABSOLUTE_DIRS};150do151local package_dirpath="${package_src_dir}/${package_name}"152if [ -d "${package_dirpath}" ];153then154cp -r "${package_dirpath}/"* "${destination}/" 2> /dev/null155display_alert "Adding files from" "${package_dirpath}"156fi157done158}159160161162163customize_image()164{165166# for users that need to prepare files at host167[[ -f $USERPATCHES_PATH/customize-image-host.sh ]] && source "$USERPATCHES_PATH"/customize-image-host.sh168169call_extension_method "pre_customize_image" "image_tweaks_pre_customize" << 'PRE_CUSTOMIZE_IMAGE'170*run before customize-image.sh*171This hook is called after `customize-image-host.sh` is called, but before the overlay is mounted.172It thus can be used for the same purposes as `customize-image-host.sh`.173PRE_CUSTOMIZE_IMAGE174175cp "$USERPATCHES_PATH"/customize-image.sh "${SDCARD}"/tmp/customize-image.sh176chmod +x "${SDCARD}"/tmp/customize-image.sh177mkdir -p "${SDCARD}"/tmp/overlay178# util-linux >= 2.27 required179mount -o bind,ro "$USERPATCHES_PATH"/overlay "${SDCARD}"/tmp/overlay180display_alert "Calling image customization script" "customize-image.sh" "info"181chroot "${SDCARD}" /bin/bash -c "/tmp/customize-image.sh $RELEASE $LINUXFAMILY $BOARD $BUILD_DESKTOP $ARCH"182CUSTOMIZE_IMAGE_RC=$?183umount -i "${SDCARD}"/tmp/overlay >/dev/null 2>&1184mountpoint -q "${SDCARD}"/tmp/overlay || rm -r "${SDCARD}"/tmp/overlay185if [[ $CUSTOMIZE_IMAGE_RC != 0 ]]; then186exit_with_error "customize-image.sh exited with error (rc: $CUSTOMIZE_IMAGE_RC)"187fi188189call_extension_method "post_customize_image" "image_tweaks_post_customize" << 'POST_CUSTOMIZE_IMAGE'190*post customize-image.sh hook*191Run after the customize-image.sh script is run, and the overlay is unmounted.192POST_CUSTOMIZE_IMAGE193}194195196197198install_deb_chroot()199{200201local package=$1202local variant=$2203local transfer=$3204local name205local desc206if [[ ${variant} != remote ]]; then207name="/root/"$(basename "${package}")208[[ ! -f "${SDCARD}${name}" ]] && cp "${package}" "${SDCARD}${name}"209desc=""210else211name=$1212desc=" from repository"213fi214215display_alert "Installing${desc}" "${name/\/root\//}"216[[ $NO_APT_CACHER != yes ]] && local apt_extra="-o Acquire::http::Proxy=\"http://${APT_PROXY_ADDR:-localhost:3142}\" -o Acquire::http::Proxy::localhost=\"DIRECT\""217# when building in bulk from remote, lets make sure we have up2date index218[[ $BUILD_ALL == yes && ${variant} == remote ]] && chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get $apt_extra -yqq update"219chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq $apt_extra --no-install-recommends install $name" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1220[[ $? -ne 0 ]] && exit_with_error "Installation of $name failed" "${BOARD} ${RELEASE} ${BUILD_DESKTOP} ${LINUXFAMILY}"221[[ ${variant} == remote && ${transfer} == yes ]] && rsync -rq "${SDCARD}"/var/cache/apt/archives/*.deb ${DEB_STORAGE}/222223}224225226227dpkg_install_deb_chroot()228{229230local package=$1231local name232local desc233234name="/root/"$(basename "${package}")235[[ ! -f "${SDCARD}${name}" ]] && cp "${package}" "${SDCARD}${name}"236237display_alert "Installing${desc}" "${name/\/root\//}"238239# when building in bulk from remote, lets make sure we have up2date index240chroot "${SDCARD}" /bin/bash -c "dpkg -i $name" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1241chroot "${SDCARD}" /bin/bash -c "dpkg-deb -f $name Package | xargs apt-mark hold" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1242[[ $? -ne 0 ]] && exit_with_error "Installation of $name failed" "${BOARD} ${RELEASE} ${BUILD_DESKTOP} ${LINUXFAMILY}"243244}245246dpkg_install_debs_chroot()247{248local deb_dir=$1249local unsatisfied_dependencies=()250local package_names=()251local package_dependencies=()252253[ ! -d "$deb_dir" ] && return254255deb_packages=($(find "${deb_dir}/" -mindepth 1 -maxdepth 1 -type f -name "*.deb"))256257find_in_array() {258local target="$1"259local element=""260shift261for element in "$@"; do262[[ "$element" == "$target" ]] && return 0263done264return 1265}266267for package in "${deb_packages[@]}"; do268package_names+=($(dpkg-deb -f "$package" Package))269270dep_str=$(dpkg-deb -I "${package}" | grep 'Depends' | sed 's/.*: //' | sed 's/ //g' | sed 's/([^)]*)//g')271IFS=',' read -ra dep_array <<< "$dep_str"272273if [[ ! ${#dep_array[@]} -eq 0 ]]; then274#dep_array[-1]="${dep_array[-1]} "275276for element in "${dep_array[@]}"; do277if [[ $element == *"|"* ]]; then278#dep_array=("${dep_array[@]/$element}")279:280else281if ! find_in_array "$element" "${package_dependencies[@]}"; then282package_dependencies+=("${element}")283fi284fi285done286287fi288done289290for dependency in "${package_dependencies[@]}"; do291if ! chroot "${SDCARD}" /bin/bash -c "dpkg-query -W --showformat='\${Status}' ${dependency} \292| grep -q 'ok installed'" &>/dev/null; then293294all=("${package_names[@]}" "${unsatisfied_dependencies[@]}")295296if ! find_in_array "$dependency" "${all[@]}"; then297unsatisfied_dependencies+=("$dependency")298fi299fi300done301302if [[ ! -z "${unsatisfied_dependencies[*]}" ]]; then303display_alert "Installing Dependencies" "${unsatisfied_dependencies[*]}"304chroot $SDCARD /bin/bash -c "apt-get -y -qq install ${unsatisfied_dependencies[*]}" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1305fi306307local names=""308for package in "${deb_packages[@]}"; do309name="/root/"$(basename "${package}")310names+=($name)311[[ ! -f "${SDCARD}${name}" ]] && cp "${package}" "${SDCARD}${name}"312done313314if [[ ! -z "${names[*]}" ]]; then315display_alert "Installing" "$(basename $deb_dir)"316317# when building in bulk from remote, lets make sure we have up2date index318chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive dpkg -i ${names[*]} " >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1319[[ $? -ne 0 ]] && exit_with_error "Installation of $(basename $deb_dir) failed" "${BOARD} ${RELEASE} ${BUILD_DESKTOP} ${LINUXFAMILY}"320chroot "${SDCARD}" /bin/bash -c "apt-mark hold ${package_names[*]}" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1321fi322}323324run_on_sdcard()325{326327# Lack of quotes allows for redirections and pipes easily.328chroot "${SDCARD}" /bin/bash -c "${@}" >> "${DEST}"/${LOG_SUBPATH}/install.log329330}331332333