Merge ~vorlon/cloud-init:master into cloud-init:master

Proposed by Steve Langasek
Status: Merged
Merged at revision: 0e2030ca7fe783ead06100c748f4714895461799
Proposed branch: ~vorlon/cloud-init:master
Merge into: cloud-init:master
Diff against target: 99 lines (+40/-21)
3 files modified
cloudinit/config/cc_growpart.py (+10/-1)
cloudinit/config/cc_resizefs.py (+1/-20)
cloudinit/util.py (+29/-0)
Reviewer Review Type Date Requested Status
Scott Moser Approve
Server Team CI bot continuous-integration Approve
Review via email: mp+321245@code.launchpad.net

Commit message

support resizing partition and rootfs on system booted without initramfs.

When booted without an initramfs, the root device will be /dev/root, not a
named device. There is partial support for this when resizing filesystems,
but not for growing partitions, without which it doesn't do much good. Move
the /dev/root resolution code to util.py and use it from cc_growpart.py.

Also, booting without an initramfs only works with a root= argument that's
either a kernel device name (which is unstable) or a partition UUID. Handle
the case of root=PARTUUID=value, not just LABEL and UUID.

LP: #1677376

Description of the change

When booted without an initramfs, the root device will be /dev/root, not a named device. There is partial support for this when resizing filesystems, but not for growing partitions, without which it doesn't do much good. Move the /dev/root resolution code to util.py and use it from cc_growpart.py.

Also, booting without an initramfs only works with a root= argument that's either a kernel device name (which is unstable) or a partition UUID. Handle the case of root=PARTUUID=value, not just LABEL and UUID.

To post a comment you must log in.
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Scott Moser (smoser) wrote :

Just a summary of what i said in irc for more public.

a.) lets opportunistically check the /dev/disk/by-partuuid path even though it does not seem to be present on 16.04 instances. It is present in my tests on zesty.
b.) use find_devs_with rather than the blkid subp call there.
     devlist = util.find_devs_with(criteria=found):
         return devlist[0]

~vorlon/cloud-init:master updated
f40b200... by Steve Langasek

use util.find_devs_with() instead of reimplementing a call to blkid

af28600... by Steve Langasek

Check /dev/disks/by-partuuid before exec()ing blkid

Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
~vorlon/cloud-init:master updated
29e332a... by Steve Langasek

handle the case where blkid finds no entries, instead of raising an IndexError

844a785... by Steve Langasek

er, don't call blkid twice

Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Scott Moser (smoser) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/config/cc_growpart.py b/cloudinit/config/cc_growpart.py
2index 832bb3f..089693e 100644
3--- a/cloudinit/config/cc_growpart.py
4+++ b/cloudinit/config/cc_growpart.py
5@@ -247,7 +247,16 @@ def devent2dev(devent):
6 result = util.get_mount_info(devent)
7 if not result:
8 raise ValueError("Could not determine device of '%s' % dev_ent")
9- return result[0]
10+ dev = result[0]
11+
12+ container = util.is_container()
13+
14+ # Ensure the path is a block device.
15+ if (dev == "/dev/root" and not os.path.exists(dev) and not container):
16+ dev = util.rootdev_from_cmdline(util.get_cmdline())
17+ if dev is None:
18+ raise ValueError("Unable to find device '/dev/root'")
19+ return dev
20
21
22 def resize_devices(resizer, devices):
23diff --git a/cloudinit/config/cc_resizefs.py b/cloudinit/config/cc_resizefs.py
24index e028abf..60e3ab5 100644
25--- a/cloudinit/config/cc_resizefs.py
26+++ b/cloudinit/config/cc_resizefs.py
27@@ -71,25 +71,6 @@ RESIZE_FS_PREFIXES_CMDS = [
28 NOBLOCK = "noblock"
29
30
31-def rootdev_from_cmdline(cmdline):
32- found = None
33- for tok in cmdline.split():
34- if tok.startswith("root="):
35- found = tok[5:]
36- break
37- if found is None:
38- return None
39-
40- if found.startswith("/dev/"):
41- return found
42- if found.startswith("LABEL="):
43- return "/dev/disk/by-label/" + found[len("LABEL="):]
44- if found.startswith("UUID="):
45- return "/dev/disk/by-uuid/" + found[len("UUID="):]
46-
47- return "/dev/" + found
48-
49-
50 def handle(name, cfg, _cloud, log, args):
51 if len(args) != 0:
52 resize_root = args[0]
53@@ -121,7 +102,7 @@ def handle(name, cfg, _cloud, log, args):
54 # Ensure the path is a block device.
55 if (devpth == "/dev/root" and not os.path.exists(devpth) and
56 not container):
57- devpth = rootdev_from_cmdline(util.get_cmdline())
58+ devpth = util.rootdev_from_cmdline(util.get_cmdline())
59 if devpth is None:
60 log.warn("Unable to find device '/dev/root'")
61 return
62diff --git a/cloudinit/util.py b/cloudinit/util.py
63index 3301957..17abdf8 100644
64--- a/cloudinit/util.py
65+++ b/cloudinit/util.py
66@@ -2382,4 +2382,33 @@ def indent(text, prefix):
67 return ''.join(lines)
68
69
70+def rootdev_from_cmdline(cmdline):
71+ found = None
72+ for tok in cmdline.split():
73+ if tok.startswith("root="):
74+ found = tok[5:]
75+ break
76+ if found is None:
77+ return None
78+
79+ if found.startswith("/dev/"):
80+ return found
81+ if found.startswith("LABEL="):
82+ return "/dev/disk/by-label/" + found[len("LABEL="):]
83+ if found.startswith("UUID="):
84+ return "/dev/disk/by-uuid/" + found[len("UUID="):]
85+ if found.startswith("PARTUUID="):
86+ disks_path = "/dev/disk/by-partuuid/" + found[len("PARTUUID="):]
87+ if os.path.exists(disks_path):
88+ return disks_path
89+ results = find_devs_with(found)
90+ if results:
91+ return results[0]
92+ # we know this doesn't exist, but for consistency return the path as
93+ # it /would/ exist
94+ return disks_path
95+
96+ return "/dev/" + found
97+
98+
99 # vi: ts=4 expandtab

Subscribers

People subscribed via source and target branches