diff options
author | Lars Wirzenius <liw@liw.fi> | 2020-10-07 10:24:24 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2020-10-07 11:14:00 +0300 |
commit | eb6b53f818f7bf73ce8b37c16264df4884094c1e (patch) | |
tree | 4aa574f6c2b9a3b8f64c0522f45a50d92725425c | |
parent | 458538055bf09428d706c7bd7b17c8a0d63d44ad (diff) | |
download | vmdb2-eb6b53f818f7bf73ce8b37c16264df4884094c1e.tar.gz |
feat: add new plugin to resize rootfs upon boot
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | pc.vmdb | 10 | ||||
-rw-r--r-- | vmdb/plugins/resize.mdwn | 24 | ||||
-rw-r--r-- | vmdb/plugins/resize_plugin.py | 116 | ||||
-rw-r--r-- | without-tests | 1 |
5 files changed, 152 insertions, 2 deletions
@@ -6,6 +6,9 @@ Version 0.19+git, not yet released * All use of the Python `cliapp` library has been dropped from vmdb2 now. +* New step `resize-rootfs` adds a systemd service to resize the root + file system to fit the actual drive on boot. + Version 0.19, released 2020-09-16 ----------------------------------------------------------------------------- @@ -11,7 +11,7 @@ steps: - mkpart: primary device: "{{ output }}" start: 0% - end: 100% + end: 50% tag: / - kpartx: "{{ output }}" @@ -40,10 +40,16 @@ steps: - chroot: / shell: | echo pc > /etc/hostname - apt -y install python + apt -y install python parted - fstab: / + - chroot: / + shell: | + sed -i 's,^root:[^:]*:,root::,' /etc/passwd + + - resize-rootfs: / + - grub: bios tag: / quiet: false diff --git a/vmdb/plugins/resize.mdwn b/vmdb/plugins/resize.mdwn new file mode 100644 index 0000000..4097f1e --- /dev/null +++ b/vmdb/plugins/resize.mdwn @@ -0,0 +1,24 @@ +Step: rezize-rootfs +----------------------------------------------------------------------------- + +Configure the system on the image so that it automatically resizes +itself to fill the actual disk, upon first boot. For this to work, the +root file system MUST be the last partition on the image. + +Also, the image MUST have the `parted` package installed for the +`partprobe` command. + +Step keys: + +* `resize-rootfs` — REQUIRED; value MUST be the tag for the root + filesystem. + +This is based on reading the changes by Peter Lawler to the +[image-specs](https://salsa.debian.org/raspi-team/image-specs.git) +repository to do the same thing. + +Example: + +~~~yaml +- resize-rootfs: root +~~~ diff --git a/vmdb/plugins/resize_plugin.py b/vmdb/plugins/resize_plugin.py new file mode 100644 index 0000000..d3efbad --- /dev/null +++ b/vmdb/plugins/resize_plugin.py @@ -0,0 +1,116 @@ +# Copyright 2020 Lars Wirzenius, Peter Lawler +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# =*= License: GPL-3+ =*= + + +import os + +import vmdb + + +SCRIPT = """\ +#!/bin/sh + +rootpart="$(findmnt -n -o SOURCE /)" +rootdev="/dev/$(lsblk -no pkname "$rootpart")" +partno="$(lsblk -n --list "$rootpart" | wc -l)" + +flock $rootdev sfdisk -f $rootdev -N "$partno" <<EOF +,+ +EOF + +sleep 5 + +udevadm settle + +sleep 5 + +flock $rootdev partprobe $rootdev + +mount -o remount,rw $rootpart + +resize2fs -f $rootpart + +exit 0 +""" + +SERVICE = """\ +[Unit] +Description=resize root file system +Before=local-fs-pre.target +DefaultDependencies=no + +[Service] +Type=oneshot +TimeoutSec=infinity +ExecStart=/usr/sbin/resize-rootfs +ExecStart=/bin/systemctl --no-reload disable %n + +[Install] +RequiredBy=local-fs-pre.target +""" + + +class ResizeRootfsPlugin(vmdb.Plugin): + def enable(self): + self.app.step_runners.add(ResizeRootfsStepRunner()) + + +class ResizeRootfsStepRunner(vmdb.StepRunnerInterface): + def get_key_spec(self): + return {"resize-rootfs": str} + + def run(self, values, settings, state): + tag = values["resize-rootfs"] + root = state.tags.get_builder_mount_point(tag) + + partprobe = self.relative(root, "/sbin/parted") + if not os.path.exists(partprobe): + raise Exception("partprobe is not installed on image, can't resize") + + script_path = "/usr/sbin/resize-rootfs" + service_path = "/etc/systemd/system/resize-rootfs.service" + requires_path = "/etc/systemd/system/systemd-remount-fs.service.requires/" + + # Install the script that actually does the resizing. + self.install(SCRIPT, root, script_path, 0o755) + + # Install the systemd service file to invoke the script at boot. + self.install(SERVICE, root, service_path, 0o644) + + # Tell systemd to run the script at the right time. This corresponds to + # "systemctl enable". + self.mkdir(root, "etc/systemd/system/systemd-remount-fs.service.requires") + self.symlink(root, service_path, requires_path) + + def relative(self, root, pathname): + return os.path.join(root, "./" + pathname) + + def install(self, content, root, filename, mode): + filename = self.relative(root, filename) + with open(filename, "w") as f: + f.write(content) + os.chmod(filename, mode) + + def mkdir(self, root, pathname): + pathname = self.relative(root, pathname) + os.makedirs(pathname, exist_ok=True) + + def symlink(self, root, linkto, linkname): + linkname = self.relative(root, linkname) + basename = os.path.basename(linkto) + linkname = os.path.join(linkname, basename) + os.symlink(linkto, linkname) diff --git a/without-tests b/without-tests index 8821505..49079d0 100644 --- a/without-tests +++ b/without-tests @@ -22,6 +22,7 @@ vmdb/plugins/mklabel_plugin.py vmdb/plugins/mkpart_plugin.py vmdb/plugins/mount_plugin.py vmdb/plugins/qemudebootstrap_plugin.py +vmdb/plugins/resize_plugin.py vmdb/plugins/shell_plugin.py vmdb/plugins/unpack_rootfs_plugin.py vmdb/plugins/vgcreate_plugin.py |