-
Notifications
You must be signed in to change notification settings - Fork 834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support to resize rootfs if using LVM #721
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙋🏻♀️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one general comment, and some changes requested inline.
If there is no 'lvm', then we should not try to resize with lvm (i think right now that would atually just fail/stacktrace if there is no 'lvm' command). just check if subp.which('lvm'):
Hello! Thank you for this proposed change to cloud-init. This pull request is now marked as stale as it has not seen any activity in 14 days. If no activity occurs within the next 7 days, this pull request will automatically close. If you are waiting for code review and you are seeing this message, apologies! Please reply, tagging mitechie, and he will ensure that someone takes a look soon. (If the pull request is closed, please do feel free to reopen it if you wish to continue working on it.) |
This is what it looks like without LVM:
Based on 'growpart's simplified view of the world,
So after growpart, we end up with:
In a simple LVM case (one PV on a VG) we might see a disk like this:
Assuming we can determine a simple case like this.
What we've done there is:
There are all sorts of ways the above could be more complicated. The vg0 could be spread across multiple PVS via RAID or stripe or linear. Lets focus on the simple case. I think the operations above simplify down to 2 groups (1,2,3 and 4,5). I think I'm fine with saying 'yes' to both as the default behavior, and if the user does not like it, they should disable growpart. Also, lets limit operations to the simple case described above. If the / LV is on a VG that spans multiple PVs, then we should just do nothing. |
Thanks for all the input @smoser . I believe I fixed most of the things. Feel free to leave comments on the rework :-) Also, had to force push because of outdated branch, I personally don't like merge commits. Also^2: Running into lots of tox/pylint errors, even on a clean checkout. I'll file a bug for that (but that's why I'm not running tox in its full extent on my local laptop) |
923befc
to
d145939
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we're almost there, @otubo. Thank you for your patience.
Thank you, Scott for all the review and help merging this. Just finished the final fixes and pushed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@otubo thanks... I just have the one comment. And seeking further input from @OddBloke or @blackboxsw . It really is not a huge deal, but I just don't like stack traces that aren't errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @otubo; minor suggestion about a possible failure path on Linux and non-linux systems that probably requires a bit of work on get_pvs_for_lv
and handling.
Minimally, I'd like to see get_pvs_for_lv values get checked before putting it into rpath and allowing os.path.basename to field a boolean return value.
Ideally get_pvs_for_lv would return only one data type, not str or False.
Please also change the two util.logexc to logging.warning in cases where we would like to proceed or actually raise an exception if we really want cloud-init to fall over. It's confusing to a user to have a logged exception in cloud-init that isn't actually raising an exception.
This patch adds support to resize a single partition of a VM if it's using an LVM underneath. The patch detects if it's LVM if the given block device is a device mapper by its name (e.g. /dev/dm-1) and if it has slave devices under it on sysfs. After that syspath is updated to the real block device and growpart will be called to resize it (and automatically its Physical Volume). The Volume Group will be updated automatically and a final call to extend the rootfs to the remaining space available will be made. Using the same growpart configuration, the user can specify only one device to be resized when using LVM and growpart, otherwise cloud-init won't know which one should be resized and will fail. rhbz: #1810878 Signed-off-by: Eduardo Otubo <otubo@redhat.com>
* Moved LVM detection and PV information to its own function * Other small fixes * Adjusted the tests for the new functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @otubo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs fixing just so that we have a pre-flight subp.which('lvm') check before erroring and calling lvm commands.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok with this as it is. But if you wanted to move the sanity check to the top of get_pvs_for_lv, i would approve that change also.
Thank you so much for your patience, @otubo
@lru_cache
def get_pvs_for_lv(devpath):
if not util.is_Linux():
LOG.info("No support for LVM on %s", platform.system())
return None
if not subp.which('lvm'):
LOG.info("No 'lvm' command present")
return None
# continue on with less indentation
try:
(out, _err) = subp.subp(...
I think that makes sense. Just updated. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 thanks a lot @otubo all good on my front with this review. I've just clicked update branch to get latest from cloud-init tip and someone can land it if they get to it before I see it tomorrow morning.
This reverts commit 74fa008. During pre-release testing, we discovered two issues with this commit. Firstly, there's a typo in the udevadm command that causes a TypeError for _all_ growpart executions. Secondly, the LVM resizing does not appear to successfully resize everything up to the LV, though some things do get resized. We certainly want this change, so we'll be happy to review and land it alongside an integration test which confirms that it is working as expected.
This reverts commit 74fa008. During pre-release testing, we discovered two issues with this commit. Firstly, there's a typo in the udevadm command that causes a TypeError for _all_ growpart executions. Secondly, the LVM resizing does not appear to successfully resize everything up to the LV, though some things do get resized. We certainly want this change, so we'll be happy to review and land it alongside an integration test which confirms that it is working as expected. LP: #1922742
Proposed Commit Message
This patch adds support to resize a single partition of a VM if it's using an
LVM underneath. The patch detects if it's LVM if the given block device
is a device mapper by its name (e.g.
/dev/dm-1
) and if it has slavedevices under it on sysfs. After that syspath is updated to the real
block device and growpart will be called to resize it (and automatically
its Physical Volume).
The Volume Group will be updated automatically and a final call to
extend the rootfs to the remaining space available will be made.
Using the same growpart configuration, the user can specify only one
device to be resized when using LVM and growpart, otherwise cloud-init
won't know which one should be resized and will fail.
rhbz: #1810878
LP: #1799953
Signed-off-by: Eduardo Otubo otubo@redhat.com
Additional Context
The commit also includes changes to the documentation as well as to unit tests to support the changes. The unit test is a copy from the existing test but using
/dev/XXdm-0
variants for LVM tests.Test Steps
One can verify the fix by installing cloud-init on an instance using LVM and configure it to expand one single partition, e.g. the
rootfs
.Checklist: