From 9b075d12debefac71e455337ac7b5b78b3809e13 Mon Sep 17 00:00:00 2001 From: Kamil Dziezyk Date: Fri, 20 Nov 2020 12:44:01 +0100 Subject: [PATCH] arm-autonomy/xenguest-tools: set guest disk and partition sizes in MB or GB This patch brings following improvements: * Allow user to set guest disk and partition sizes in MB or GB. * Documentation update about this improvement. Change-Id: I0a1a2945022efcd9d32bb39404b4a85721e28e19 Issue-Id: SCM-1515 Signed-off-by: Kamil Dziezyk Signed-off-by: Jon Mason --- .../classes/xenguest-image.bbclass | 37 ++++++------ .../documentation/xenguest-mkimage.md | 18 +++--- .../xenguest/files/xenguest-manager | 56 +++++++++++++++++-- .../xenguest/files/xenguest-mkimage | 48 +++++++++++++++- 4 files changed, 125 insertions(+), 34 deletions(-) diff --git a/meta-arm-autonomy/classes/xenguest-image.bbclass b/meta-arm-autonomy/classes/xenguest-image.bbclass index 93f6578f..8c6b1416 100644 --- a/meta-arm-autonomy/classes/xenguest-image.bbclass +++ b/meta-arm-autonomy/classes/xenguest-image.bbclass @@ -44,13 +44,13 @@ XENGUEST_IMAGE_KERNEL ??= "Image" XENGUEST_IMAGE_DISK_SIZE ??= "${@ '4' if not d.getVar('INITRAMFS_IMAGE') else '0'}" # -# XENGUEST_IMAGE_DISK PARTITIONS is used to describe the partitions to setup +# XENGUEST_IMAGE_DISK_PARTITIONS is used to describe the partitions to setup # and their content. # It must be set to a space separated list of entries with each entry having -# the format num:sz:fs:[file] where: +# the format num:sz:[fs]:[file] where: # - num is a partition number -# - sz is the partition size in Gigabit -# - fs is the filesystem to use for the partition +# - sz is the partition size in MB or GB(default), e.g 1000M or 1[G] +# - fs is optional filesystem to use for the partition # - file is optionally pointing to a file to use as content of the partition # Please check image_types_xenguest.bbclass for rootfs handling of files # @@ -129,21 +129,22 @@ xenguest_image_create() { # create disk if needed disksize="${XENGUEST_IMAGE_DISK_SIZE}" - if [ -z "$disksize" ]; then - disksize="0" - fi - if [ $disksize -gt 0 ]; then - # setup disk size - call_xenguest_mkimage update --disk-reset-config --disk-size=$disksize + case ${disksize:=0} in + 0|0M|0G) + ;; + *) + # setup disk size + call_xenguest_mkimage update --disk-reset-config --disk-size=$disksize + + diskparts="${XENGUEST_IMAGE_DISK_PARTITIONS}" + if [ -n "$diskparts" ]; then + for arg in $diskparts; do + call_xenguest_mkimage update --disk-add-part=$arg + done + fi + ;; + esac - diskparts="${XENGUEST_IMAGE_DISK_PARTITIONS}" - if [ -n "$diskparts" ]; then - for arg in $diskparts; do - call_xenguest_mkimage update --disk-add-part=$arg - partnum="$(expr $partnum + 1)" - done - fi - fi if [ "${XENGUEST_IMAGE_AUTOBOOT}" = "1" ]; then call_xenguest_mkimage update --set-param=GUEST_AUTOBOOT=1 diff --git a/meta-arm-autonomy/documentation/xenguest-mkimage.md b/meta-arm-autonomy/documentation/xenguest-mkimage.md index ece17f76..d7baa2e4 100644 --- a/meta-arm-autonomy/documentation/xenguest-mkimage.md +++ b/meta-arm-autonomy/documentation/xenguest-mkimage.md @@ -58,12 +58,14 @@ order. ### disk.cfg and disk-files disk.cfg contains the guest disk description (disk size and disk partitions). The file contains the following entries: -- `DISK_SIZE=X`: size of the disk to create in GB +- `DISK_SIZE=X`: size of the disk to create in MB or GB(default), + e.g. 1000M or 4[G] - `DISK_PARTX=SIZE:FS:CONTENT`: create a partition number X (1 to 4) with a - size of SIZE GB, format it with filesystem FS (can be ext2, ext3, ext4, vfat - or swap) and extract CONTENT as initial partition content - (.tar[.gz|.xz|.bz2] file or img[.gz|.bz2] file to be dumped in the partition). FS and - CONTENT can be empty. + size of SIZE MB or GB(default), e.g 1000M or 2[G]. + Format it with filesystem FS (can be ext2, ext3, ext4, vfat or swap) + and extract CONTENT as initial partition content (.tar[.gz|.xz|.bz2] file + or img[.gz|.bz2] file to be dumped in the partition). + FS and CONTENT can be empty. The disk-files contain files to be used for initializing the disk partitions content. Those should be used to create a LVM or a physical disk and initialize @@ -105,12 +107,12 @@ For a detailed help on available operations, please use: image file. Several script can be added and the basename of FILE is used to distinguish them (calling the option twice with the same file will update the script in the image with the second one). - --disk-size=SIZE: set the guest disk size to SIZE in GB. Calling this with 0 - disable the guest disk. + --disk-size=SIZE: set the guest disk size to SIZE in MB or GB(default), + e.g 1000M or 2[G]. Calling this with 0 disable the guest disk. - --disk-add-part=NUM:SIZE:FS:CONTENT: This is adding a partition to the xenguest image disk. The partition is described with the arguments: - NUM: partition number. - - SIZE: partition size in GB. + - SIZE: partition size in MB or GB(default), e.g 1000M or 2[G]. - FS: filesystem to format the partition with. This can be ext2, ext3, ext4, vfat of swap. If empty the partition is not formated. - CONTENT: tar of img file to use to initialize the partition. The file must diff --git a/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-manager b/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-manager index 4ea3a379..eb7a3ceb 100755 --- a/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-manager +++ b/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-manager @@ -54,6 +54,47 @@ with ACTION being one of: EOF } +is_integer() { + if ! [[ "${1}" =~ ^[0-9]+$ ]]; then + >&2 echo "error: invalid number '${1}'"; exit 1 + fi +} + +# check size and convert it to MB, e.g '1[G]' => '1000M' +check_size() { + local disksize="${1}" + + [ -n "${disksize}" ] || disksize="invalid" + + # disksize may have appended M or G suffix, let's extract it + # ${var:offset:length}, where #var is var length + local lastchar="${disksize:${#disksize}-1}" + case "${lastchar}" in + [0-9]) + # backwards compatibility + is_integer "${disksize}" + echo -e "$((${disksize} * 1000))M" + return + ;; + G|M) + if [ "${#disksize}" -gt "1" ]; then + local size="${disksize::${#disksize}-1}" + is_integer "${size}" + # convert GB to MB + [ "${lastchar}" = "M" ] || size=$((${size} * 1000)) + echo -e "${size}M" + return + fi + ;; + *) + ;; + esac + + >&2 echo -e "Invalid size format '${1}'" \ + "\n\tSupported size format is e.g 1000M or 2[G]" + exit 1 +} + function xenguest_volume_init() { # Return: @@ -142,7 +183,8 @@ function xenguest_disk_init() source ${XENGUEST_CONF_BASE}/guests/${guestname}/disk.cfg - if [ ${DISK_SIZE:-0} -eq 0 ]; then + DISK_SIZE=$(check_size "${DISK_SIZE}") + if [ -z "${DISK_SIZE}" ] || [ "${DISK_SIZE}" = "0M" ]; then echo "${PREF} No disk for ${guestname}" return fi @@ -172,9 +214,9 @@ function xenguest_disk_init() fi # Create volume - echo "lvcreate -y -L ${DISK_SIZE}G -n ${guestname} ${XENGUEST_VOLUME_NAME}" \ + echo "lvcreate -y -L ${DISK_SIZE} -n ${guestname} ${XENGUEST_VOLUME_NAME}" \ >> ${LOGFILE} 2>&1 - lvcreate -y -L ${DISK_SIZE}G -n ${guestname} ${XENGUEST_VOLUME_NAME} \ + lvcreate -y -L ${DISK_SIZE} -n ${guestname} ${XENGUEST_VOLUME_NAME} \ >> ${LOGFILE} 2>&1 if [ $? -ne 0 ]; then echo "${PREF} Error creating volume ${guestname}" @@ -212,9 +254,11 @@ function xenguest_disk_init() fstype=$(echo ${partdesc} | sed -e "s/.*:\(.*\):.*/\1/") content=$(echo ${partdesc} | sed -e "s/.*:.*:\(.*\)/\1/") - if [ "${size}" -ne 0 ]; then - # Size is expressed in GB, pass it in MB - size=$(expr ${size} \* 1024) + size=$(check_size "${size}") + if [ -n "${size}" ] && [ "${size}" != "0M" ]; then + # size has appended M or G suffix, let's extract just the value + # ${var:offset:length}, where #var is var length + size="${size::${#size}-1}" partend=$(expr ${partstart} + ${size}) # Let first MB of disk free for partition table diff --git a/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-mkimage b/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-mkimage index fb321d6a..c133e0ee 100755 --- a/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-mkimage +++ b/meta-arm-autonomy/recipes-extended/xenguest/files/xenguest-mkimage @@ -110,7 +110,8 @@ Init configuration Disk configuration --disk-reset-config reset disk guest configuration to default (no disk) ---disk-size=SZ set guest disk size (in GB) +--disk-size=SZ set guest disk size in MB or GB(default), + e.g 1000M or 2[G]. --disk-device=DEV set device to be used to create the guest disk if unset or set to an empty string, the volume will be create in the default manager volume group. @@ -370,6 +371,47 @@ disk_config_rm_part() { sed -i "/DISK_PART${partid}=.*/d" ${IMAGE_TMPDIR}/disk.cfg } +is_integer() { + if ! [[ "${1}" =~ ^[0-9]+$ ]]; then + >&2 echo "error: invalid number '${1}'"; exit 1 + fi +} + +# check size and convert it to MB, e.g '1[G]' => '1000M' +check_size() { + local disksize="${1}" + + [ -n "${disksize}" ] || disksize="invalid" + + # disksize may have appended M or G suffix, let's extract it + # ${var:offset:length}, where #var is var length + local lastchar="${disksize:${#disksize}-1}" + case "${lastchar}" in + [0-9]) + # backwards compatibility + is_integer "${disksize}" + echo -e "$((${disksize} * 1000))M" + return + ;; + G|M) + if [ "${#disksize}" -gt "1" ]; then + local size="${disksize::${#disksize}-1}" + is_integer "${size}" + # convert GB to MB + [ "${lastchar}" = "M" ] || size=$((${size} * 1000)) + echo -e "${size}M" + return + fi + ;; + *) + ;; + esac + + >&2 echo -e "Invalid size format '${1}'" \ + "\n\tSupported size format is e.g 1000M or 2[G]" + exit 1 +} + disk_config_add_part() { partconf="${1}" partid=$(echo ${partconf} | sed -e "s/:.*//") @@ -742,7 +784,9 @@ for arg in "${@}"; do disk_config_reset ;; --disk-size=*) - sed -i "s/DISK_SIZE=.*/DISK_SIZE=\"${optarg}\"/" \ + size=$(check_size "${optarg}") + [ -n "size" ] || exit 1 + sed -i "s/DISK_SIZE=.*/DISK_SIZE=\"${size}\"/" \ ${IMAGE_TMPDIR}/disk.cfg ;; --disk-device=*)