hypriot/flash

Add option to resize root partition

breandan opened this issue · 6 comments

It would be convenient to have an option to set the root partition size, so that users do not need to rebuild the HypriotOS image.

I don't quite understand this. The root filesystem will be resized on first boot. So what's the problem?
Flash couldn't help here I guess.

The motivation here is to support putting larger files on /var/local, as it is currently limited to 1GB. After flashing an image, and prior to inserting the SD card into the RPI, I would like to write a file, however the default root allocation is not large enough. I would like to avoid running image-builder-rpi. Maybe this is not a common use case, although it seems fairly standard.

I don‘t know if that can be done with flash, changing Linux disk size from a Mac will be hard.
If you find a way you are welcome to send a PR.

Closing due to inactivity.

I would love this to be possible as well.
I have got some code for Linux to accomplish it but after resizing the image and copying the files it is bricked.

@breandan did you ever get it to work?

CODE

echo "Image preparation script has started"
set -euf -o pipefail

baseImage=
imageFile=
deployPackage=
userDataFile=

rm $imageFile
sudo rm /tmp/$imageFile # TODO - Remove this, only applies to debuging
cp $baseImage $imageFile

partedInfo="$(sudo parted --machine "${imageFile}" print)"
sectorSize="$(echo "${partedInfo}" | grep :file: | awk -F ':' '{ print $4; }')"

startSectors=( $(fdisk --list --bytes "${imageFile}" | tail -n 2 | awk '{ print $2; }') )
bootStart=$((startSectors[0] * sectorSize))
rootStart=$((startSectors[1] * sectorSize))

dirMount="$(mktemp --directory)"
unmountImage() {
echo "Unmounting image..."
sleep 1
sudo umount "${dirMount}"
}
mountRoot() {
echo "Mounting root partition (offset=$rootStart) to ${dirMount}..."
sleep 1
sudo mount -o loop,offset=$rootStart "${imageFile}" "${dirMount}"
}
mountRoot
rootFree="$(sudo df "${dirMount}" | grep "${dirMount}" | awk '{ print $4; }')"
deploySize="$(du -b "${deployPackage}" | awk '{ print $1; }')"
addSize=$(( deploySize - rootFree * 1024 ))
unmountImage
rm $dirMount -R

if [ $addSize -gt 0 ] # Resize Image if needed

then
echo "Need ${addSize} more bytes to fit ${deployPackage}"
addSize=$(( 10 + addSize / (1000 * 1000) ))
oldEnd="$(echo "${partedInfo}"
| grep '^2:'
| awk -F ':' '{ print $3; }'
| grep --color=never -oE '[0-9]+'
)"
newEnd="$((oldEnd + addSize))MB"

echo "Adding ${addSize}MB to root partition of ${imageFile}..."
sudo dd if=/dev/zero bs=1MB count=$addSize >> "${imageFile}"

echo "Resizing root partition to end at ${newEnd}..."
sudo parted "${imageFile}" resizepart 2 "${newEnd}"
sudo kpartx -a "${imageFile}"

devLoop="$(sudo losetup -a \
    | grep `basename "${imageFile}"` \
    | grep --color=never -oP '(?<=^/dev/)loop[0-9]+' \
)"
devMapper="/dev/mapper/${devLoop}p2"
sudo e2fsck -f -y -C 0 "${devMapper}"
sudo resize2fs -p "${devMapper}"

sleep 3     # Give time for system clean ups

echo "Removing ${devLoop}..."
sudo kpartx -d "${imageFile}"
sudo dmsetup info | grep --color=never -o "${devLoop}p.*" | xargs sudo dmsetup remove || :
sudo losetup -a | grep -q "${devLoop}:" && sudo losetup -d "/dev/${devLoop}" || :

fi

sudo guestfish --rw -a "${imageFile}"<<EOF
run
mount /dev/sda2 /
mount /dev/sda1 /boot
echo "Copying user-data..."
copy-in "${userDataFile}" /boot
echo "Upacking the home directory..."
tgz-in "${deployPackage}" /home
EOF

I am all of a sudden unable to connect to my pi running hypriot nor start the docker demon and it appears that the logs are reporting insufficient space for some reason. The only partition that is "full" is my root partition, so the only culprit is then the 100% full root partition. So, if the idea is that there is no reason to allow for increasing the root partition then how does one recover from a problem like this?

I thought I might remove snap, for example, since I was not using it after my initial play. Can't even remove snap as I get:

$ sudo apt remove snap
Reading package lists... Error!
E: Write error - write (28: No space left on device)
E: Write error - write (28: No space left on device)
E: The package lists or status file could not be parsed or opened.

Trying to connect to the pi with hypriot from VSCODE off my windoze 64 laptop now fails with the same problem expressed as:

[10:11:23.658] > pirate@192.168.0.100's password: 
[10:11:23.659] Showing password prompt
[10:11:31.148] Got password response
[10:11:31.149] "install" wrote data to terminal: "*******"
[10:11:31.161] > 
> 
[10:11:31.497] > 9fc55655c9a4: running
> 
[10:11:31.514] > mkdir: cannot create directory ‘/home/pirate/.vscode-server/bin/db40434f56299411
> 6e5b21c24015a2e40b2504e6’: No space left on device
> Creating the server install dir failed...
> 9fc55655c9a4##34##
> 
[10:11:31.515] Received install output: 9fc55655c9a4##34##
[10:11:31.516] Resolver error: Failed to create the remote server's install directory
[10:11:31.521] ------

All evidence is then root space is the problem?

I am otherwise running node-red, emqx, home-assistant and deconz and have done for months without problems.

Being able to bump up root might help at least confirm the 100% full root is the problem.