#! /usr/bin/env bash # # Copyright 2020 Northern.tech AS # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. function trap_exit() { echo "mender-convert-extract has finished. Cleaning up..." } function trap_term() { true } trap trap_term INT TERM trap trap_exit EXIT echo "Running $(basename $0): $@" source modules/bootstrap.sh source modules/disk.sh source modules/probe.sh # The mender_convert_config is always used and provides all the defaults declare -a configs=("configs/mender_convert_config") disk_image="" while (( "$#" )); do case "$1" in -o | --overlay) overlays+=("${2}") shift 2 ;; -c | --config) configs+=("${2}") shift 2 ;; -d | --disk-image) disk_image="${2}" shift 2 ;; *) log_fatal "Sorry but the provided option is not supported: $1" ;; esac done if [ -z "${disk_image}" ]; then log_warn "Sorry, but '--disk-image' is a mandatory option" log_warn "See ./mender-convert --help for more information" exit 1 fi if [ ! -e ${disk_image} ]; then log_fatal "File not found: ${disk_image}" fi # Note the use of %q formatting here. This is a bash feature to add # proper quoting to the strings so that spaces and special characters # will be treated properly. Primarily for supporting spaces in # pathnames and avoid splitting those into multiple parameters. source modules/config.sh $(printf "%q " "${configs[@]}") MKFS_VFAT="/usr/bin/mkfs.vfat" if [ ! -f ${MKFS_VFAT} ]; then MKFS_VFAT="/sbin/mkfs.vfat" fi declare -a part_nrs=($(disk_get_part_nums ${disk_image})) declare -i nr_of_parts=${#part_nrs[@]} log_info "Validating disk image" if [ ${nr_of_parts} -eq 0 ]; then log_fatal "Sorry, but could not find any valid partitions for: ${disk_image}" fi log_info "Disk parsed successfully" log_info "NUMBER OF PARTS: ${nr_of_parts} TYPE: $(disk_get_part_value ${disk_image} 1 SCHEME)" for n in ${part_nrs[*]} ; do part_dst_file="work/part-${n}.fs" if [ "$(disk_get_part_value ${disk_image} ${n} TYPE)" == "0x8e" ]; then log_fatal "Detected an LVM volume group on disk. Unfortunately this is not yet supported" fi log_info "PART ${n}: SIZE: $(disk_get_part_value ${disk_image} ${n} SIZE) TYPE: $(disk_get_part_value ${disk_image} ${n} TYPE)" log_info "PART ${n}: extracting to ${part_dst_file}" disk_extract_part "${disk_image}" $(disk_get_part_value ${disk_image} ${n} START) \ $(disk_get_part_value ${disk_image} ${n} SECTORS) ${part_dst_file} done # Some disk images will not have an boot partition for us to extract, # but we do require it be present and hence we might need to generate # a filesystem image here. if [ ${nr_of_parts} -eq 1 ]; then log_info "Generating boot partition (required, does not exist in original image)" run_and_log_cmd "dd if=/dev/zero of=work/boot-generated.vfat count=${MENDER_BOOT_PART_SIZE_MB} bs=1M status=none" run_and_log_cmd "${MKFS_VFAT} work/boot-generated.vfat" fi # Extract boot gap, that is the area from sector 1 until first part, and # this is done because some images might contain the bootloader embedded here # and we might need to keep this area intact when we generate our custom # image. if [ "${MENDER_COPY_BOOT_GAP}" == "y" ]; then log_info "Extracting boot gap to work/boot-gap.bin" disk_extract_part "${disk_image}" \ 1 $(( $(disk_get_part_value ${disk_image} 1 START) - 1)) work/boot-gap.bin if [ "${MENDER_GRUB_EFI_INTEGRATION}" == "y" ]; then # Check for known U-Boot problems in the boot gap (probable boot loader # location). check_for_broken_uboot_uefi_support work/boot-gap.bin fi fi