summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/devops/resizing_root_partition.rst210
1 files changed, 210 insertions, 0 deletions
diff --git a/content/devops/resizing_root_partition.rst b/content/devops/resizing_root_partition.rst
new file mode 100644
index 0000000..e07f706
--- /dev/null
+++ b/content/devops/resizing_root_partition.rst
@@ -0,0 +1,210 @@
+Note to Self: Growing the Root File System on First Boot
+########################################################
+
+:date: 2019-02-16 22:13 +0530
+:slug: grow_rootfs
+:tags: resize2fs, notetoself
+:author: copyninja
+:summary: Post discusses about expanding root file system of a system to full
+ extent of available space in device.
+
+These 2 are the use cases I came across for expanding root file system.
+
+1. RaspberryPi images which comes in smaller image size like 1GB which you write
+ bigger size SD cards like 32GB but you want to use full 32GB of space when
+ system comes up.
+
+2. You have a VM image which is contains basic server operating system and you want
+ to provision the same as a VM with much larger size root file system.
+
+My current use case was second but I learnt the trick from 1, that is the
+`RaspberryPi3 image spec <https://github.com/Debian/raspi3-image-spec>`_ by
+Debian project.
+
+Idea behind the expanding root file system is first expanding the root file
+system to full available size and then run resize2fs on the expanded partition
+to grow file system. *resize2fs* is a tool specific for ext2/3/4 file system.
+But this needs to be done before the file system is mounted.
+
+Here is my modified script from `raspi3-image-spec repo
+<https://github.com/Debian/raspi3-image-spec/blob/master/rpi3-resizerootfs>`_.
+Only difference is I've changed the logic of extracting root partition device to
+my need, and of course added comments based on my understanding.
+
+.. code:: shell
+
+ #!/bin/sh
+
+ # Just extracts root partition and removes partition number to get the device
+ # name eg. /dev/sda1 becomes /dev/sda
+ roottmp=$(lsblk -l -o NAME,MOUNTPOINT | grep '/$')
+ rootpart=/dev/${roottmp%% */}
+ rootdev=${rootpart%1}
+
+ # Use sfdisk to extend partition to all available free space on device.
+ flock $rootdev sfdisk -f $rootdev -N 2 <<EOF
+ ,+
+ EOF
+
+ sleep 5
+
+ # Wait for all pending udev events to be handled
+ udevadm settle
+
+ sleep 5
+
+ # detect the changes to partition (we extended it).
+ flock $rootdev partprobe $rootdev
+
+ # remount the root partition in read write mode
+ mount -o remount,rw $rootpart
+
+ # Finally grow the file system on root partition
+ resize2fs $rootpart
+
+ exit 0fs
+
+
+raspi3-image-spec uses `sytemd service
+<https://github.com/Debian/raspi3-image-spec/blob/master/rpi3-resizerootfs.service>`_
+file to execute this script just before any file system is mounted. This is done
+by a making service execute before *local-fs.pre* target. From the man page for
+*systemd.special*
+
+ local-fs.target
+ systemd-fstab-generator(3) automatically adds dependencies of type
+ Before= to all mount units that refer to local mount points for this
+ target unit. In addition, it adds dependencies of type Wants= to this
+ target unit for those mounts listed in /etc/fstab that have the auto
+ mount option set.
+
+Testing with VM
+===============
+
+*raspi3-image-spec* is well tested, but I wanted to make sure this works with my
+use case for VM. Since I didn't have any spare physical disks to experiment with
+I used kpartx with raw file images. Here is what I did
+
+1. Created a stretch image using vmdb2 with grub installed. Image size is 1.5G
+2. I created another raw disk using fallocate of 4G size.
+3. I created a partition on 4G disk.
+4. Loop mounted the disk and wrote 1G image on it using dd
+5. Finally created a VM using virt-install with this loop mounted device as
+ root disk.
+
+Below is my vmdb configuration yml again derived from `raspi3-image-spec
+<https://github.com/Debian/raspi3-image-spec/blob/master/raspi3.yaml>`_ one with
+some modifications to my needs.
+
+.. code:: yaml
+
+ # See https://wiki.debian.org/RaspberryPi3 for known issues and more details.
+ steps:
+ - mkimg: "{{ output }}"
+ size: 1.5G
+
+ - mklabel: msdos
+ device: "{{ output }}"
+
+ - mkpart: primary
+ device: "{{ output }}"
+ start: 0%
+ end: 100%
+ tag: /
+
+ - kpartx: "{{ output }}"
+
+ - mkfs: ext4
+ partition: /
+ label: RASPIROOT
+
+ - mount: /
+
+ - unpack-rootfs: /
+
+ - debootstrap: stretch
+ mirror: http://localhost:3142/deb.debian.org/debian
+ target: /
+ variant: minbase
+ components:
+ - main
+ - contrib
+ - non-free
+ unless: rootfs_unpacked
+
+ # TODO(https://bugs.debian.org/877855): remove this workaround once
+ # debootstrap is fixed
+ - chroot: /
+ shell: |
+ echo 'deb http://deb.debian.org/debian buster main contrib non-free' > /etc/apt/sources.list
+ apt-get update
+ unless: rootfs_unpacked
+
+ - apt: install
+ packages:
+ - ssh
+ - parted
+ - dosfstools
+ - linux-image-amd64
+ tag: /
+ unless: rootfs_unpacked
+
+ - grub: bios
+ tag: /
+
+ - cache-rootfs: /
+ unless: rootfs_unpacked
+
+ - shell: |
+ echo "experimental" > "${ROOT?}/etc/hostname"
+
+ # '..VyaTFxP8kT6' is crypt.crypt('raspberry', '..')
+ sed -i 's,root:[^:]*,root:..VyaTFxP8kT6,' "${ROOT?}/etc/shadow"
+
+ sed -i 's,#PermitRootLogin prohibit-password,PermitRootLogin yes,g' "${ROOT?}/etc/ssh/sshd_config"
+
+ install -m 644 -o root -g root fstab "${ROOT?}/etc/fstab"
+
+ install -m 644 -o root -g root eth0 "${ROOT?}/etc/network/interfaces.d/eth0"
+
+ install -m 755 -o root -g root rpi3-resizerootfs "${ROOT?}/usr/sbin/rpi3-resizerootfs"
+ install -m 644 -o root -g root rpi3-resizerootfs.service "${ROOT?}/etc/systemd/system"
+ mkdir -p "${ROOT?}/etc/systemd/system/systemd-remount-fs.service.requires/"
+ ln -s /etc/systemd/system/rpi3-resizerootfs.service "${ROOT?}/etc/systemd/system/systemd-remount-fs.service.requires/rpi3-resizerootfs.service"
+
+ install -m 644 -o root -g root rpi3-generate-ssh-host-keys.service "${ROOT?}/etc/systemd/system"
+ mkdir -p "${ROOT?}/etc/systemd/system/multi-user.target.requires/"
+ ln -s /etc/systemd/system/rpi3-generate-ssh-host-keys.service "${ROOT?}/etc/systemd/system/multi-user.target.requires/rpi3-generate-ssh-host-keys.service"
+ rm -f ${ROOT?}/etc/ssh/ssh_host_*_key*
+
+ root-fs: /
+
+ # Clean up archive cache (likely not useful) and lists (likely outdated) to
+ # reduce image size by several hundred megabytes.
+ - chroot: /
+ shell: |
+ apt-get clean
+ rm -rf /var/lib/apt/lists
+
+ # TODO(https://github.com/larswirzenius/vmdb2/issues/24): remove once vmdb
+ # clears /etc/resolv.conf on its own.
+ - shell: |
+ rm "${ROOT?}/etc/resolv.conf"
+ root-fs: /
+
+I could not run with vmdb2 installed from Debian archive, so I cloned
+raspi3-image-spec and used vmdb2 submodule from it.
+
+.. code:: shell
+
+ fallocate -l 4G rootdisk.img
+ # Create one partition with full disk
+ sfdisk -f rootdisk.img <<EOF
+ ,+
+ EOF
+ kpartx -av rootdisk.img # mounts on /dev/loop0 for me
+ dd if=vmdb.img of=/dev/loop0
+ sudo virt-install --name experimental --memory 1024 --disk path=/dev/loop0 --controller type=scsi,model=virtio-scsi --boot hd --network bridge=lxcbr0
+
+Once VM booted I could see the root file system is 4G of size instead of 1.5G it
+was after using dd to write image on to it. So success!.