Merge ~chad.smith/cloud-init:ubuntu/devel into cloud-init:ubuntu/devel
- Git
- lp:~chad.smith/cloud-init
- ubuntu/devel
- Merge into ubuntu/devel
Proposed by
Chad Smith
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 10ab9a7c231b6f7d01da3a3a4c08cf4db01f5a87 | ||||||||||||
Proposed branch: | ~chad.smith/cloud-init:ubuntu/devel | ||||||||||||
Merge into: | cloud-init:ubuntu/devel | ||||||||||||
Diff against target: |
574 lines (+317/-15) 16 files modified
ChangeLog (+58/-0) cloudinit/config/cc_puppet.py (+3/-0) cloudinit/config/cc_resizefs.py (+22/-0) cloudinit/settings.py (+1/-0) cloudinit/sources/DataSourceHetzner.py (+6/-0) cloudinit/util.py (+35/-9) cloudinit/version.py (+1/-1) debian/changelog (+11/-2) packages/debian/control.in (+2/-1) tests/data/mount_parse_ext.txt (+19/-0) tests/data/mount_parse_zfs.txt (+21/-0) tests/data/zpool_status_simple.txt (+10/-0) tests/unittests/test_datasource/test_common.py (+2/-0) tests/unittests/test_datasource/test_hetzner.py (+19/-1) tests/unittests/test_handler/test_handler_resizefs.py (+57/-1) tests/unittests/test_util.py (+50/-0) |
||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Server Team CI bot | continuous-integration | Approve | |
Scott Moser | Pending | ||
Review via email:
|
Commit message
Sync upstream 18.2 release to Bionic for publish.
Description of the change
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)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/ChangeLog b/ChangeLog |
2 | index be4c357..daa7ccf 100644 |
3 | --- a/ChangeLog |
4 | +++ b/ChangeLog |
5 | @@ -1,3 +1,61 @@ |
6 | +18.2: |
7 | + - Hetzner: Exit early if dmi system-manufacturer is not Hetzner. |
8 | + - Add missing dependency on isc-dhcp-client to trunk ubuntu packaging. |
9 | + (LP: #1759307) |
10 | + - FreeBSD: resizefs module now able to handle zfs/zpool. |
11 | + [Dominic Schlegel] (LP: #1721243) |
12 | + - cc_puppet: Revert regression of puppet creating ssl and ssl_cert dirs |
13 | + - Enable IBMCloud datasource in settings.py. |
14 | + - IBMCloud: Initial IBM Cloud datasource. |
15 | + - tests: remove jsonschema from xenial tox environment. |
16 | + - tests: Fix newly added schema unit tests to skip if no jsonschema. |
17 | + - ec2: Adjust ec2 datasource after exception_cb change. |
18 | + - Reduce AzurePreprovisioning HTTP timeouts. |
19 | + [Douglas Jordan] (LP: #1752977) |
20 | + - Revert the logic of exception_cb in read_url. |
21 | + [Kurt Garloff] (LP: #1702160, #1298921) |
22 | + - ubuntu-advantage: Add new config module to support |
23 | + ubuntu-advantage-tools |
24 | + - Handle global dns entries in netplan (LP: #1750884) |
25 | + - Identify OpenTelekomCloud Xen as OpenStack DS. |
26 | + [Kurt Garloff] (LP: #1756471) |
27 | + - datasources: fix DataSource subclass get_hostname method signature |
28 | + (LP: #1757176) |
29 | + - OpenNebula: Update network to return v2 config rather than ENI. |
30 | + [Akihiko Ota] |
31 | + - Add Hetzner Cloud DataSource |
32 | + - net: recognize iscsi root cases without ip= on kernel command line. |
33 | + (LP: #1752391) |
34 | + - tests: fix flakes warning for unused variable |
35 | + - tests: patch leaked stderr messages from snap unit tests |
36 | + - cc_snap: Add new module to install and configure snapd and snap |
37 | + packages. |
38 | + - tests: Make pylint happy and fix python2.6 uses of assertRaisesRegex. |
39 | + - netplan: render bridge port-priority values (LP: #1735821) |
40 | + - util: Fix subp regression. Allow specifying subp command as a string. |
41 | + (LP: #1755965) |
42 | + - doc: fix all warnings issued by 'tox -e doc' |
43 | + - FreeBSD: Set hostname to FQDN. [Dominic Schlegel] (LP: #1753499) |
44 | + - tests: fix run_tree and bddeb |
45 | + - tests: Fix some warnings in tests that popped up with newer python. |
46 | + - set_hostname: When present in metadata, set it before network bringup. |
47 | + (LP: #1746455) |
48 | + - tests: Centralize and re-use skipTest based on json schema presense. |
49 | + - This commit fixes get_hostname on the AzureDataSource. |
50 | + [Douglas Jordan] (LP: #1754495) |
51 | + - shellify: raise TypeError on bad input. |
52 | + - Make salt minion module work on FreeBSD. |
53 | + [Dominic Schlegel] (LP: #1721503) |
54 | + - Simplify some comparisions. [Rémy Léone] |
55 | + - Change some list creation and population to literal. [Rémy Léone] |
56 | + - GCE: fix reading of user-data that is not base64 encoded. (LP: #1752711) |
57 | + - doc: fix chef install from apt packages example in RTD. |
58 | + - Implement puppet 4 support [Romanos Skiadas] (LP: #1446804) |
59 | + - subp: Fix subp usage with non-ascii characters when no system locale. |
60 | + (LP: #1751051) |
61 | + - salt: configure grains in grains file rather than in minion config. |
62 | + [Daniel Wallace] |
63 | + |
64 | 18.1: |
65 | - OVF: Fix VMware support for 64-bit platforms. [Sankar Tanguturi] |
66 | - ds-identify: Fix searching for iso9660 OVF cdroms. (LP: #1749980) |
67 | diff --git a/cloudinit/config/cc_puppet.py b/cloudinit/config/cc_puppet.py |
68 | index 297e072..4190a20 100644 |
69 | --- a/cloudinit/config/cc_puppet.py |
70 | +++ b/cloudinit/config/cc_puppet.py |
71 | @@ -140,6 +140,7 @@ def handle(name, cfg, cloud, log, _args): |
72 | # (TODO(harlowja) is this really needed??) |
73 | cleaned_lines = [i.lstrip() for i in contents.splitlines()] |
74 | cleaned_contents = '\n'.join(cleaned_lines) |
75 | + # Move to puppet_config.read_file when dropping py2.7 |
76 | puppet_config.readfp( # pylint: disable=W1505 |
77 | StringIO(cleaned_contents), |
78 | filename=p_constants.conf_path) |
79 | @@ -150,6 +151,8 @@ def handle(name, cfg, cloud, log, _args): |
80 | # Puppet ssl sub-directory isn't created yet |
81 | # Create it with the proper permissions and ownership |
82 | util.ensure_dir(p_constants.ssl_dir, 0o771) |
83 | + util.chownbyname(p_constants.ssl_dir, 'puppet', 'root') |
84 | + util.ensure_dir(p_constants.ssl_cert_dir) |
85 | |
86 | util.chownbyname(p_constants.ssl_cert_dir, 'puppet', 'root') |
87 | util.write_file(p_constants.ssl_cert_path, cfg) |
88 | diff --git a/cloudinit/config/cc_resizefs.py b/cloudinit/config/cc_resizefs.py |
89 | index cec22bb..c8e1752 100644 |
90 | --- a/cloudinit/config/cc_resizefs.py |
91 | +++ b/cloudinit/config/cc_resizefs.py |
92 | @@ -84,6 +84,10 @@ def _resize_ufs(mount_point, devpth): |
93 | return ('growfs', devpth) |
94 | |
95 | |
96 | +def _resize_zfs(mount_point, devpth): |
97 | + return ('zpool', 'online', '-e', mount_point, devpth) |
98 | + |
99 | + |
100 | def _get_dumpfs_output(mount_point): |
101 | dumpfs_res, err = util.subp(['dumpfs', '-m', mount_point]) |
102 | return dumpfs_res |
103 | @@ -148,6 +152,7 @@ RESIZE_FS_PREFIXES_CMDS = [ |
104 | ('ext', _resize_ext), |
105 | ('xfs', _resize_xfs), |
106 | ('ufs', _resize_ufs), |
107 | + ('zfs', _resize_zfs), |
108 | ] |
109 | |
110 | RESIZE_FS_PRECHECK_CMDS = { |
111 | @@ -188,6 +193,13 @@ def maybe_get_writable_device_path(devpath, info, log): |
112 | log.debug("Not attempting to resize devpath '%s': %s", devpath, info) |
113 | return None |
114 | |
115 | + # FreeBSD zpool can also just use gpt/<label> |
116 | + # with that in mind we can not do an os.stat on "gpt/whatever" |
117 | + # therefore return the devpath already here. |
118 | + if devpath.startswith('gpt/'): |
119 | + log.debug('We have a gpt label - just go ahead') |
120 | + return devpath |
121 | + |
122 | try: |
123 | statret = os.stat(devpath) |
124 | except OSError as exc: |
125 | @@ -231,6 +243,16 @@ def handle(name, cfg, _cloud, log, args): |
126 | |
127 | (devpth, fs_type, mount_point) = result |
128 | |
129 | + # if we have a zfs then our device path at this point |
130 | + # is the zfs label. For example: vmzroot/ROOT/freebsd |
131 | + # we will have to get the zpool name out of this |
132 | + # and set the resize_what variable to the zpool |
133 | + # so the _resize_zfs function gets the right attribute. |
134 | + if fs_type == 'zfs': |
135 | + zpool = devpth.split('/')[0] |
136 | + devpth = util.get_device_info_from_zpool(zpool) |
137 | + resize_what = zpool |
138 | + |
139 | info = "dev=%s mnt_point=%s path=%s" % (devpth, mount_point, resize_what) |
140 | log.debug("resize_info: %s" % info) |
141 | |
142 | diff --git a/cloudinit/settings.py b/cloudinit/settings.py |
143 | index 5fe749d..dde5749 100644 |
144 | --- a/cloudinit/settings.py |
145 | +++ b/cloudinit/settings.py |
146 | @@ -37,6 +37,7 @@ CFG_BUILTIN = { |
147 | 'Bigstep', |
148 | 'Scaleway', |
149 | 'Hetzner', |
150 | + 'IBMCloud', |
151 | # At the end to act as a 'catch' when none of the above work... |
152 | 'None', |
153 | ], |
154 | diff --git a/cloudinit/sources/DataSourceHetzner.py b/cloudinit/sources/DataSourceHetzner.py |
155 | index 769fe13..5c75b65 100644 |
156 | --- a/cloudinit/sources/DataSourceHetzner.py |
157 | +++ b/cloudinit/sources/DataSourceHetzner.py |
158 | @@ -44,6 +44,8 @@ class DataSourceHetzner(sources.DataSource): |
159 | self.dsmode = sources.DSMODE_NETWORK |
160 | |
161 | def get_data(self): |
162 | + if not on_hetzner(): |
163 | + return False |
164 | nic = cloudnet.find_fallback_nic() |
165 | with cloudnet.EphemeralIPv4Network(nic, "169.254.0.1", 16, |
166 | "169.254.255.255"): |
167 | @@ -87,6 +89,10 @@ class DataSourceHetzner(sources.DataSource): |
168 | return self._network_config |
169 | |
170 | |
171 | +def on_hetzner(): |
172 | + return util.read_dmi_data('system-manufacturer') == "Hetzner" |
173 | + |
174 | + |
175 | # Used to match classes to dependencies |
176 | datasources = [ |
177 | (DataSourceHetzner, (sources.DEP_FILESYSTEM, )), |
178 | diff --git a/cloudinit/util.py b/cloudinit/util.py |
179 | index fb4ee5f..0ab2c48 100644 |
180 | --- a/cloudinit/util.py |
181 | +++ b/cloudinit/util.py |
182 | @@ -2234,7 +2234,7 @@ def get_path_dev_freebsd(path, mnt_list): |
183 | return path_found |
184 | |
185 | |
186 | -def get_mount_info_freebsd(path, log=LOG): |
187 | +def get_mount_info_freebsd(path): |
188 | (result, err) = subp(['mount', '-p', path], rcs=[0, 1]) |
189 | if len(err): |
190 | # find a path if the input is not a mounting point |
191 | @@ -2248,23 +2248,49 @@ def get_mount_info_freebsd(path, log=LOG): |
192 | return "/dev/" + label_part, ret[2], ret[1] |
193 | |
194 | |
195 | +def get_device_info_from_zpool(zpool): |
196 | + (zpoolstatus, err) = subp(['zpool', 'status', zpool]) |
197 | + if len(err): |
198 | + return None |
199 | + r = r'.*(ONLINE).*' |
200 | + for line in zpoolstatus.split("\n"): |
201 | + if re.search(r, line) and zpool not in line and "state" not in line: |
202 | + disk = line.split()[0] |
203 | + LOG.debug('found zpool "%s" on disk %s', zpool, disk) |
204 | + return disk |
205 | + |
206 | + |
207 | def parse_mount(path): |
208 | - (mountoutput, _err) = subp("mount") |
209 | + (mountoutput, _err) = subp(['mount']) |
210 | mount_locs = mountoutput.splitlines() |
211 | + # there are 2 types of mount outputs we have to parse therefore |
212 | + # the regex is a bit complex. to better understand this regex see: |
213 | + # https://regex101.com/r/2F6c1k/1 |
214 | + # https://regex101.com/r/T2en7a/1 |
215 | + regex = r'^(/dev/[\S]+|.*zroot\S*?) on (/[\S]*) ' + \ |
216 | + '(?=(?:type)[\s]+([\S]+)|\(([^,]*))' |
217 | for line in mount_locs: |
218 | - m = re.search(r'^(/dev/[\S]+) on (/.*) \((.+), .+, (.+)\)$', line) |
219 | + m = re.search(regex, line) |
220 | if not m: |
221 | continue |
222 | + devpth = m.group(1) |
223 | + mount_point = m.group(2) |
224 | + # above regex will either fill the fs_type in group(3) |
225 | + # or group(4) depending on the format we have. |
226 | + fs_type = m.group(3) |
227 | + if fs_type is None: |
228 | + fs_type = m.group(4) |
229 | + LOG.debug('found line in mount -> devpth: %s, mount_point: %s, ' |
230 | + 'fs_type: %s', devpth, mount_point, fs_type) |
231 | # check whether the dev refers to a label on FreeBSD |
232 | # for example, if dev is '/dev/label/rootfs', we should |
233 | # continue finding the real device like '/dev/da0'. |
234 | - devm = re.search('^(/dev/.+)p([0-9])$', m.group(1)) |
235 | - if (not devm and is_FreeBSD()): |
236 | + # this is only valid for non zfs file systems as a zpool |
237 | + # can have gpt labels as disk. |
238 | + devm = re.search('^(/dev/.+)p([0-9])$', devpth) |
239 | + if not devm and is_FreeBSD() and fs_type != 'zfs': |
240 | return get_mount_info_freebsd(path) |
241 | - devpth = m.group(1) |
242 | - mount_point = m.group(2) |
243 | - fs_type = m.group(3) |
244 | - if mount_point == path: |
245 | + elif mount_point == path: |
246 | return devpth, fs_type, mount_point |
247 | return None |
248 | |
249 | diff --git a/cloudinit/version.py b/cloudinit/version.py |
250 | index 4a682ad..ccd0f84 100644 |
251 | --- a/cloudinit/version.py |
252 | +++ b/cloudinit/version.py |
253 | @@ -4,7 +4,7 @@ |
254 | # |
255 | # This file is part of cloud-init. See LICENSE file for license information. |
256 | |
257 | -__VERSION__ = "18.1" |
258 | +__VERSION__ = "18.2" |
259 | |
260 | FEATURES = [ |
261 | # supports network config version 1 |
262 | diff --git a/debian/changelog b/debian/changelog |
263 | index 6f022bb..cdfbf6a 100644 |
264 | --- a/debian/changelog |
265 | +++ b/debian/changelog |
266 | @@ -1,8 +1,17 @@ |
267 | -cloud-init (18.1-35-ge0f644b7-0ubuntu3) UNRELEASED; urgency=medium |
268 | +cloud-init (18.2-0ubuntu1) bionic; urgency=medium |
269 | |
270 | * debian/control: Add missing dependency on isc-dhcp-client (LP: #1759307). |
271 | + * New upstream snapshot. |
272 | + - release 18.2 (LP: #1759318) |
273 | + - Hetzner: Exit early if dmi system-manufacturer is not Hetzner. |
274 | + - Add missing dependency on isc-dhcp-client to trunk ubuntu packaging. |
275 | + (LP: #1759307) |
276 | + - FreeBSD: resizefs module now able to handle zfs/zpool. |
277 | + [Dominic Schlegel] (LP: #1721243) |
278 | + - cc_puppet: Revert regression of puppet creating ssl and ssl_cert dirs |
279 | + - Enable IBMCloud datasource in settings.py. |
280 | |
281 | - -- Scott Moser <smoser@ubuntu.com> Tue, 27 Mar 2018 12:19:44 -0400 |
282 | + -- Chad Smith <chad.smith@canonical.com> Tue, 27 Mar 2018 14:59:58 -0600 |
283 | |
284 | cloud-init (18.1-35-ge0f644b7-0ubuntu2) bionic; urgency=medium |
285 | |
286 | diff --git a/packages/debian/control.in b/packages/debian/control.in |
287 | index 265b261..46da6df 100644 |
288 | --- a/packages/debian/control.in |
289 | +++ b/packages/debian/control.in |
290 | @@ -10,7 +10,8 @@ Standards-Version: 3.9.6 |
291 | Package: cloud-init |
292 | Architecture: all |
293 | Depends: ${misc:Depends}, |
294 | - ${${python}:Depends} |
295 | + ${${python}:Depends}, |
296 | + isc-dhcp-client |
297 | Recommends: eatmydata, sudo, software-properties-common, gdisk |
298 | XB-Python-Version: ${python:Versions} |
299 | Description: Init scripts for cloud instances |
300 | diff --git a/tests/data/mount_parse_ext.txt b/tests/data/mount_parse_ext.txt |
301 | new file mode 100644 |
302 | index 0000000..da0c870 |
303 | --- /dev/null |
304 | +++ b/tests/data/mount_parse_ext.txt |
305 | @@ -0,0 +1,19 @@ |
306 | +/dev/mapper/vg00-lv_root on / type ext4 (rw,errors=remount-ro) |
307 | +proc on /proc type proc (rw,noexec,nosuid,nodev) |
308 | +sysfs on /sys type sysfs (rw,noexec,nosuid,nodev) |
309 | +none on /sys/fs/cgroup type tmpfs (rw) |
310 | +none on /sys/fs/fuse/connections type fusectl (rw) |
311 | +none on /sys/kernel/debug type debugfs (rw) |
312 | +none on /sys/kernel/security type securityfs (rw) |
313 | +udev on /dev type devtmpfs (rw,mode=0755) |
314 | +devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620) |
315 | +none on /tmp type tmpfs (rw) |
316 | +tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755) |
317 | +none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880) |
318 | +none on /run/shm type tmpfs (rw,nosuid,nodev) |
319 | +none on /run/user type tmpfs (rw,noexec,nosuid,nodev,size=104857600,mode=0755) |
320 | +none on /sys/fs/pstore type pstore (rw) |
321 | +/dev/mapper/vg00-lv_var on /var type ext4 (rw) |
322 | +rpc_pipefs on /run/rpc_pipefs type rpc_pipefs (rw) |
323 | +systemd on /sys/fs/cgroup/systemd type cgroup (rw,noexec,nosuid,nodev,none,name=systemd) |
324 | +10.0.1.1:/backup on /backup type nfs (rw,noexec,nosuid,nodev,bg,nolock,tcp,nfsvers=3,hard,addr=10.0.1.1) |
325 | \ No newline at end of file |
326 | diff --git a/tests/data/mount_parse_zfs.txt b/tests/data/mount_parse_zfs.txt |
327 | new file mode 100644 |
328 | index 0000000..08af04f |
329 | --- /dev/null |
330 | +++ b/tests/data/mount_parse_zfs.txt |
331 | @@ -0,0 +1,21 @@ |
332 | +vmzroot/ROOT/freebsd on / (zfs, local, nfsv4acls) |
333 | +devfs on /dev (devfs, local, multilabel) |
334 | +fdescfs on /dev/fd (fdescfs) |
335 | +vmzroot/root on /root (zfs, local, nfsv4acls) |
336 | +vmzroot/tmp on /tmp (zfs, local, nosuid, nfsv4acls) |
337 | +vmzroot/ROOT/freebsd/usr on /usr (zfs, local, nfsv4acls) |
338 | +vmzroot/ROOT/freebsd/usr/local on /usr/local (zfs, local, nfsv4acls) |
339 | +vmzroot/ROOT/freebsd/var on /var (zfs, local, nfsv4acls) |
340 | +vmzroot/ROOT/freebsd/var/cache on /var/cache (zfs, local, noexec, nosuid, nfsv4acls) |
341 | +vmzroot/ROOT/freebsd/var/crash on /var/crash (zfs, local, noexec, nosuid, nfsv4acls) |
342 | +vmzroot/var/cron on /var/cron (zfs, local, nosuid, nfsv4acls) |
343 | +vmzroot/ROOT/freebsd/var/db on /var/db (zfs, local, noatime, noexec, nosuid, nfsv4acls) |
344 | +vmzroot/ROOT/freebsd/var/empty on /var/empty (zfs, local, noexec, nosuid, read-only, nfsv4acls) |
345 | +vmzroot/var/log on /var/log (zfs, local, noexec, nosuid, nfsv4acls) |
346 | +vmzroot/var/log/pf on /var/log/pf (zfs, local, noexec, nosuid, nfsv4acls) |
347 | +vmzroot/var/mail on /var/mail (zfs, local, noexec, nosuid, nfsv4acls) |
348 | +vmzroot/ROOT/freebsd/var/run on /var/run (zfs, local, noexec, nosuid, nfsv4acls) |
349 | +vmzroot/var/spool on /var/spool (zfs, local, noexec, nosuid, nfsv4acls) |
350 | +vmzroot/var/tmp on /var/tmp (zfs, local, nosuid, nfsv4acls) |
351 | +10.0.0.1:/vol/test on /mnt/test (nfs, read-only) |
352 | +10.0.0.2:/vol/tes2 on /mnt/test2 (nfs, nosuid) |
353 | \ No newline at end of file |
354 | diff --git a/tests/data/zpool_status_simple.txt b/tests/data/zpool_status_simple.txt |
355 | new file mode 100644 |
356 | index 0000000..a2c573a |
357 | --- /dev/null |
358 | +++ b/tests/data/zpool_status_simple.txt |
359 | @@ -0,0 +1,10 @@ |
360 | + pool: vmzroot |
361 | + state: ONLINE |
362 | + scan: none requested |
363 | +config: |
364 | + |
365 | + NAME STATE READ WRITE CKSUM |
366 | + vmzroot ONLINE 0 0 0 |
367 | + gpt/system ONLINE 0 0 0 |
368 | + |
369 | +errors: No known data errors |
370 | \ No newline at end of file |
371 | diff --git a/tests/unittests/test_datasource/test_common.py b/tests/unittests/test_datasource/test_common.py |
372 | index 6d2dc5b..ec33388 100644 |
373 | --- a/tests/unittests/test_datasource/test_common.py |
374 | +++ b/tests/unittests/test_datasource/test_common.py |
375 | @@ -15,6 +15,7 @@ from cloudinit.sources import ( |
376 | DataSourceEc2 as Ec2, |
377 | DataSourceGCE as GCE, |
378 | DataSourceHetzner as Hetzner, |
379 | + DataSourceIBMCloud as IBMCloud, |
380 | DataSourceMAAS as MAAS, |
381 | DataSourceNoCloud as NoCloud, |
382 | DataSourceOpenNebula as OpenNebula, |
383 | @@ -33,6 +34,7 @@ DEFAULT_LOCAL = [ |
384 | ConfigDrive.DataSourceConfigDrive, |
385 | DigitalOcean.DataSourceDigitalOcean, |
386 | Hetzner.DataSourceHetzner, |
387 | + IBMCloud.DataSourceIBMCloud, |
388 | NoCloud.DataSourceNoCloud, |
389 | OpenNebula.DataSourceOpenNebula, |
390 | OVF.DataSourceOVF, |
391 | diff --git a/tests/unittests/test_datasource/test_hetzner.py b/tests/unittests/test_datasource/test_hetzner.py |
392 | index f1d1525..a9c1259 100644 |
393 | --- a/tests/unittests/test_datasource/test_hetzner.py |
394 | +++ b/tests/unittests/test_datasource/test_hetzner.py |
395 | @@ -73,7 +73,10 @@ class TestDataSourceHetzner(CiTestCase): |
396 | @mock.patch('cloudinit.net.find_fallback_nic') |
397 | @mock.patch('cloudinit.sources.helpers.hetzner.read_metadata') |
398 | @mock.patch('cloudinit.sources.helpers.hetzner.read_userdata') |
399 | - def test_read_data(self, m_usermd, m_readmd, m_fallback_nic, m_net): |
400 | + @mock.patch('cloudinit.sources.DataSourceHetzner.on_hetzner') |
401 | + def test_read_data(self, m_on_hetzner, m_usermd, m_readmd, m_fallback_nic, |
402 | + m_net): |
403 | + m_on_hetzner.return_value = True |
404 | m_readmd.return_value = METADATA.copy() |
405 | m_usermd.return_value = USERDATA |
406 | m_fallback_nic.return_value = 'eth0' |
407 | @@ -97,3 +100,18 @@ class TestDataSourceHetzner(CiTestCase): |
408 | self.assertIsInstance(ds.get_public_ssh_keys(), list) |
409 | self.assertEqual(ds.get_userdata_raw(), USERDATA) |
410 | self.assertEqual(ds.get_vendordata_raw(), METADATA.get('vendor_data')) |
411 | + |
412 | + @mock.patch('cloudinit.sources.helpers.hetzner.read_metadata') |
413 | + @mock.patch('cloudinit.net.find_fallback_nic') |
414 | + @mock.patch('cloudinit.sources.DataSourceHetzner.on_hetzner') |
415 | + def test_not_on_hetzner_returns_false(self, m_on_hetzner, m_find_fallback, |
416 | + m_read_md): |
417 | + """If helper 'on_hetzner' returns False, return False from get_data.""" |
418 | + m_on_hetzner.return_value = False |
419 | + ds = self.get_ds() |
420 | + ret = ds.get_data() |
421 | + |
422 | + self.assertFalse(ret) |
423 | + # These are a white box attempt to ensure it did not search. |
424 | + m_find_fallback.assert_not_called() |
425 | + m_read_md.assert_not_called() |
426 | diff --git a/tests/unittests/test_handler/test_handler_resizefs.py b/tests/unittests/test_handler/test_handler_resizefs.py |
427 | index c2a7f9f..7a7ba1f 100644 |
428 | --- a/tests/unittests/test_handler/test_handler_resizefs.py |
429 | +++ b/tests/unittests/test_handler/test_handler_resizefs.py |
430 | @@ -1,7 +1,8 @@ |
431 | # This file is part of cloud-init. See LICENSE file for license information. |
432 | |
433 | from cloudinit.config.cc_resizefs import ( |
434 | - can_skip_resize, handle, maybe_get_writable_device_path, _resize_btrfs) |
435 | + can_skip_resize, handle, maybe_get_writable_device_path, _resize_btrfs, |
436 | + _resize_zfs, _resize_xfs, _resize_ext, _resize_ufs) |
437 | |
438 | from collections import namedtuple |
439 | import logging |
440 | @@ -60,6 +61,9 @@ class TestResizefs(CiTestCase): |
441 | res = can_skip_resize(fs_type, resize_what, devpth) |
442 | self.assertTrue(res) |
443 | |
444 | + def test_can_skip_resize_ext(self): |
445 | + self.assertFalse(can_skip_resize('ext', '/', '/dev/sda1')) |
446 | + |
447 | def test_handle_noops_on_disabled(self): |
448 | """The handle function logs when the configuration disables resize.""" |
449 | cfg = {'resize_rootfs': False} |
450 | @@ -122,6 +126,51 @@ class TestResizefs(CiTestCase): |
451 | logs = self.logs.getvalue() |
452 | self.assertIn("WARNING: Unable to find device '/dev/root'", logs) |
453 | |
454 | + def test_resize_zfs_cmd_return(self): |
455 | + zpool = 'zroot' |
456 | + devpth = 'gpt/system' |
457 | + self.assertEqual(('zpool', 'online', '-e', zpool, devpth), |
458 | + _resize_zfs(zpool, devpth)) |
459 | + |
460 | + def test_resize_xfs_cmd_return(self): |
461 | + mount_point = '/mnt/test' |
462 | + devpth = '/dev/sda1' |
463 | + self.assertEqual(('xfs_growfs', mount_point), |
464 | + _resize_xfs(mount_point, devpth)) |
465 | + |
466 | + def test_resize_ext_cmd_return(self): |
467 | + mount_point = '/' |
468 | + devpth = '/dev/sdb1' |
469 | + self.assertEqual(('resize2fs', devpth), |
470 | + _resize_ext(mount_point, devpth)) |
471 | + |
472 | + def test_resize_ufs_cmd_return(self): |
473 | + mount_point = '/' |
474 | + devpth = '/dev/sda2' |
475 | + self.assertEqual(('growfs', devpth), |
476 | + _resize_ufs(mount_point, devpth)) |
477 | + |
478 | + @mock.patch('cloudinit.util.get_mount_info') |
479 | + @mock.patch('cloudinit.util.get_device_info_from_zpool') |
480 | + @mock.patch('cloudinit.util.parse_mount') |
481 | + def test_handle_zfs_root(self, mount_info, zpool_info, parse_mount): |
482 | + devpth = 'vmzroot/ROOT/freebsd' |
483 | + disk = 'gpt/system' |
484 | + fs_type = 'zfs' |
485 | + mount_point = '/' |
486 | + |
487 | + mount_info.return_value = (devpth, fs_type, mount_point) |
488 | + zpool_info.return_value = disk |
489 | + parse_mount.return_value = (devpth, fs_type, mount_point) |
490 | + |
491 | + cfg = {'resize_rootfs': True} |
492 | + |
493 | + with mock.patch('cloudinit.config.cc_resizefs.do_resize') as dresize: |
494 | + handle('cc_resizefs', cfg, _cloud=None, log=LOG, args=[]) |
495 | + ret = dresize.call_args[0][0] |
496 | + |
497 | + self.assertEqual(('zpool', 'online', '-e', 'vmzroot', disk), ret) |
498 | + |
499 | |
500 | class TestRootDevFromCmdline(CiTestCase): |
501 | |
502 | @@ -305,5 +354,12 @@ class TestMaybeGetDevicePathAsWritableBlock(CiTestCase): |
503 | ('btrfs', 'filesystem', 'resize', 'max', '/'), |
504 | _resize_btrfs("/", "/dev/sda1")) |
505 | |
506 | + @mock.patch('cloudinit.util.is_FreeBSD') |
507 | + def test_maybe_get_writable_device_path_zfs_freebsd(self, freebsd): |
508 | + freebsd.return_value = True |
509 | + info = 'dev=gpt/system mnt_point=/ path=/' |
510 | + devpth = maybe_get_writable_device_path('gpt/system', info, LOG) |
511 | + self.assertEqual('gpt/system', devpth) |
512 | + |
513 | |
514 | # vi: ts=4 expandtab |
515 | diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py |
516 | index 67d9607..8685b8e 100644 |
517 | --- a/tests/unittests/test_util.py |
518 | +++ b/tests/unittests/test_util.py |
519 | @@ -366,6 +366,56 @@ class TestMountinfoParsing(helpers.ResourceUsingTestCase): |
520 | expected = ('none', 'tmpfs', '/run/lock') |
521 | self.assertEqual(expected, util.parse_mount_info('/run/lock', lines)) |
522 | |
523 | + @mock.patch('cloudinit.util.subp') |
524 | + def test_get_device_info_from_zpool(self, zpool_output): |
525 | + # mock subp command from util.get_mount_info_fs_on_zpool |
526 | + zpool_output.return_value = ( |
527 | + self.readResource('zpool_status_simple.txt'), '' |
528 | + ) |
529 | + # save function return values and do asserts |
530 | + ret = util.get_device_info_from_zpool('vmzroot') |
531 | + self.assertEqual('gpt/system', ret) |
532 | + self.assertIsNotNone(ret) |
533 | + |
534 | + @mock.patch('cloudinit.util.subp') |
535 | + def test_get_device_info_from_zpool_on_error(self, zpool_output): |
536 | + # mock subp command from util.get_mount_info_fs_on_zpool |
537 | + zpool_output.return_value = ( |
538 | + self.readResource('zpool_status_simple.txt'), 'error' |
539 | + ) |
540 | + # save function return values and do asserts |
541 | + ret = util.get_device_info_from_zpool('vmzroot') |
542 | + self.assertIsNone(ret) |
543 | + |
544 | + @mock.patch('cloudinit.util.subp') |
545 | + def test_parse_mount_with_ext(self, mount_out): |
546 | + mount_out.return_value = (self.readResource('mount_parse_ext.txt'), '') |
547 | + # this one is valid and exists in mount_parse_ext.txt |
548 | + ret = util.parse_mount('/var') |
549 | + self.assertEqual(('/dev/mapper/vg00-lv_var', 'ext4', '/var'), ret) |
550 | + # another one that is valid and exists |
551 | + ret = util.parse_mount('/') |
552 | + self.assertEqual(('/dev/mapper/vg00-lv_root', 'ext4', '/'), ret) |
553 | + # this one exists in mount_parse_ext.txt |
554 | + ret = util.parse_mount('/sys/kernel/debug') |
555 | + self.assertIsNone(ret) |
556 | + # this one does not even exist in mount_parse_ext.txt |
557 | + ret = util.parse_mount('/not/existing/mount') |
558 | + self.assertIsNone(ret) |
559 | + |
560 | + @mock.patch('cloudinit.util.subp') |
561 | + def test_parse_mount_with_zfs(self, mount_out): |
562 | + mount_out.return_value = (self.readResource('mount_parse_zfs.txt'), '') |
563 | + # this one is valid and exists in mount_parse_zfs.txt |
564 | + ret = util.parse_mount('/var') |
565 | + self.assertEqual(('vmzroot/ROOT/freebsd/var', 'zfs', '/var'), ret) |
566 | + # this one is the root, valid and also exists in mount_parse_zfs.txt |
567 | + ret = util.parse_mount('/') |
568 | + self.assertEqual(('vmzroot/ROOT/freebsd', 'zfs', '/'), ret) |
569 | + # this one does not even exist in mount_parse_ext.txt |
570 | + ret = util.parse_mount('/not/existing/mount') |
571 | + self.assertIsNone(ret) |
572 | + |
573 | |
574 | class TestReadDMIData(helpers.FilesystemMockingTestCase): |
575 |
PASSED: Continuous integration, rev:10ab9a7c231 b6f7d01da3a3a4c 08cf4db01f5a87 /jenkins. ubuntu. com/server/ job/cloud- init-ci/ 940/
https:/
Executed test runs:
SUCCESS: Checkout
SUCCESS: Unit & Style Tests
SUCCESS: Ubuntu LTS: Build
SUCCESS: Ubuntu LTS: Integration
SUCCESS: MAAS Compatability Testing
IN_PROGRESS: Declarative: Post Actions
Click here to trigger a rebuild: /jenkins. ubuntu. com/server/ job/cloud- init-ci/ 940/rebuild
https:/