summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Watkins <oddbloke@ubuntu.com>2021-05-03 10:56:46 -0400
committerGitHub <noreply@github.com>2021-05-03 10:56:46 -0400
commit5f5fa5ee99296b3b1044682c41bab38a32cdccd7 (patch)
tree3e277dadd43413c54af51df9529178d14ed68fe1
parent9ea643ff35382ab8ff1e6fe514cf21eb6640ef8c (diff)
downloadvyos-cloud-init-5f5fa5ee99296b3b1044682c41bab38a32cdccd7.tar.gz
vyos-cloud-init-5f5fa5ee99296b3b1044682c41bab38a32cdccd7.zip
Revert "Add support to resize rootfs if using LVM (#721)" (#887)
This reverts commit 74fa008bfcd3263eb691cc0b3f7a055b17569f8b. 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
-rw-r--r--cloudinit/config/cc_growpart.py83
-rw-r--r--doc/examples/cloud-config-growpart.txt2
-rw-r--r--tests/unittests/test_handler/test_handler_growpart.py56
3 files changed, 4 insertions, 137 deletions
diff --git a/cloudinit/config/cc_growpart.py b/cloudinit/config/cc_growpart.py
index 6399bfb7..9f338ad1 100644
--- a/cloudinit/config/cc_growpart.py
+++ b/cloudinit/config/cc_growpart.py
@@ -68,9 +68,7 @@ import os
import os.path
import re
import stat
-import platform
-from functools import lru_cache
from cloudinit import log as logging
from cloudinit.settings import PER_ALWAYS
from cloudinit import subp
@@ -95,58 +93,6 @@ class RESIZE(object):
LOG = logging.getLogger(__name__)
-@lru_cache()
-def is_lvm_lv(devpath):
- if util.is_Linux():
- # all lvm lvs will have a realpath as a 'dm-*' name.
- rpath = os.path.realpath(devpath)
- if not os.path.basename(rpath).startswith("dm-"):
- return False
- out, _ = subp.subp("udevadm", "info", devpath)
- # lvs should have DM_LV_NAME=<lvmuuid> and also DM_VG_NAME
- return 'DM_LV_NAME=' in out
- else:
- LOG.info("Not an LVM Logical Volume partition")
- return False
-
-
-@lru_cache()
-def get_pvs_for_lv(devpath):
- myenv = {'LANG': 'C'}
-
- 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
-
- try:
- (out, _err) = subp.subp(["lvm", "lvs", devpath, "--options=vgname",
- "--noheadings"], update_env=myenv)
- vgname = out.strip()
- except subp.ProcessExecutionError as e:
- if e.exit_code != 0:
- util.logexc(LOG, "Failed: can't get Volume Group information "
- "from %s", devpath)
- raise ResizeFailedException(e) from e
-
- try:
- (out, _err) = subp.subp(["lvm", "vgs", vgname, "--options=pvname",
- "--noheadings"], update_env=myenv)
- pvs = [p.strip() for p in out.splitlines()]
- if len(pvs) > 1:
- LOG.info("Do not know how to resize multiple Physical"
- " Volumes")
- else:
- return pvs[0]
- except subp.ProcessExecutionError as e:
- if e.exit_code != 0:
- util.logexc(LOG, "Failed: can't get Physical Volume "
- "information from Volume Group %s", vgname)
- raise ResizeFailedException(e) from e
-
-
def resizer_factory(mode):
resize_class = None
if mode == "auto":
@@ -262,18 +208,13 @@ def get_size(filename):
os.close(fd)
-def device_part_info(devpath, is_lvm):
+def device_part_info(devpath):
# convert an entry in /dev/ to parent disk and partition number
# input of /dev/vdb or /dev/disk/by-label/foo
# rpath is hopefully a real-ish path in /dev (vda, sdb..)
rpath = os.path.realpath(devpath)
- # first check if this is an LVM and get its PVs
- lvm_rpath = get_pvs_for_lv(devpath)
- if is_lvm and lvm_rpath:
- rpath = lvm_rpath
-
bname = os.path.basename(rpath)
syspath = "/sys/class/block/%s" % bname
@@ -303,7 +244,7 @@ def device_part_info(devpath, is_lvm):
# diskdevpath has something like 253:0
# and udev has put links in /dev/block/253:0 to the device name in /dev/
- return diskdevpath, ptnum
+ return (diskdevpath, ptnum)
def devent2dev(devent):
@@ -353,9 +294,8 @@ def resize_devices(resizer, devices):
"device '%s' not a block device" % blockdev,))
continue
- is_lvm = is_lvm_lv(blockdev)
try:
- disk, ptnum = device_part_info(blockdev, is_lvm)
+ (disk, ptnum) = device_part_info(blockdev)
except (TypeError, ValueError) as e:
info.append((devent, RESIZE.SKIPPED,
"device_part_info(%s) failed: %s" % (blockdev, e),))
@@ -376,23 +316,6 @@ def resize_devices(resizer, devices):
"failed to resize: disk=%s, ptnum=%s: %s" %
(disk, ptnum, e),))
- if is_lvm and isinstance(resizer, ResizeGrowPart):
- try:
- if len(devices) == 1:
- (_out, _err) = subp.subp(
- ["lvm", "lvextend", "--extents=100%FREE", blockdev],
- update_env={'LANG': 'C'})
- info.append((devent, RESIZE.CHANGED,
- "Logical Volume %s extended" % devices[0],))
- else:
- LOG.info("Exactly one device should be configured to be "
- "resized when using LVM. More than one configured"
- ": %s", devices)
- except (subp.ProcessExecutionError, ValueError) as e:
- info.append((devent, RESIZE.NOCHANGE,
- "Logical Volume %s resize failed: %s" %
- (blockdev, e),))
-
return info
diff --git a/doc/examples/cloud-config-growpart.txt b/doc/examples/cloud-config-growpart.txt
index 09268117..393d5164 100644
--- a/doc/examples/cloud-config-growpart.txt
+++ b/doc/examples/cloud-config-growpart.txt
@@ -13,8 +13,6 @@
#
# devices:
# a list of things to resize.
-# if the devices are under LVM, the list should be a single entry,
-# cloud-init will then extend the single entry, otherwise it will fail.
# items can be filesystem paths or devices (in /dev)
# examples:
# devices: [/, /dev/vdb1]
diff --git a/tests/unittests/test_handler/test_handler_growpart.py b/tests/unittests/test_handler/test_handler_growpart.py
index cc0a9248..7f039b79 100644
--- a/tests/unittests/test_handler/test_handler_growpart.py
+++ b/tests/unittests/test_handler/test_handler_growpart.py
@@ -172,53 +172,6 @@ class TestResize(unittest.TestCase):
self.name = "growpart"
self.log = logging.getLogger("TestResize")
- def test_lvm_resize(self):
- # LVM resize should work only if a single device is configured. More
- # than one device should fail.
- lvm_pass = ["/dev/XXdm-0"]
- lvm_fail = ["/dev/XXdm-1", "/dev/YYdm-1"]
- devstat_ret = Bunch(st_mode=25008, st_ino=6078, st_dev=5,
- st_nlink=1, st_uid=0, st_gid=6, st_size=0,
- st_atime=0, st_mtime=0, st_ctime=0)
- real_stat = os.stat
- resize_calls = []
-
- class myresizer(object):
- def resize(self, diskdev, partnum, partdev):
- resize_calls.append((diskdev, partnum, partdev))
- if partdev == "/dev/XXdm-0":
- return (1024, 2048)
- return (1024, 1024) # old size, new size
-
- def mystat(path):
- if path in lvm_pass or path in lvm_fail:
- return devstat_ret
- return real_stat(path)
-
- try:
- opinfo = cc_growpart.device_part_info
- cc_growpart.device_part_info = simple_device_part_info_lvm
- os.stat = mystat
-
- resized = cc_growpart.resize_devices(myresizer(), lvm_pass)
- not_resized = cc_growpart.resize_devices(myresizer(), lvm_fail)
-
- def find(name, res):
- for f in res:
- if f[0] == name:
- return f
- return None
-
- self.assertEqual(cc_growpart.RESIZE.CHANGED,
- find("/dev/XXdm-0", resized)[1])
- self.assertEqual(cc_growpart.RESIZE.NOCHANGE,
- find("/dev/XXdm-1", not_resized)[1])
- self.assertEqual(cc_growpart.RESIZE.NOCHANGE,
- find("/dev/YYdm-1", not_resized)[1])
- finally:
- cc_growpart.device_part_info = opinfo
- os.stat = real_stat
-
def test_simple_devices(self):
# test simple device list
# this patches out devent2dev, os.stat, and device_part_info
@@ -274,14 +227,7 @@ class TestResize(unittest.TestCase):
os.stat = real_stat
-def simple_device_part_info_lvm(devpath, is_lvm):
- # simple stupid return (/dev/vda, 1) for /dev/vda
- ret = re.search("([^0-9]*)([0-9]*)$", devpath)
- x = (ret.group(1), ret.group(2))
- return x
-
-
-def simple_device_part_info(devpath, is_lvm):
+def simple_device_part_info(devpath):
# simple stupid return (/dev/vda, 1) for /dev/vda
ret = re.search("([^0-9]*)([0-9]*)$", devpath)
x = (ret.group(1), ret.group(2))